Implement GUI display of R2L lines, fix TTY display of R2L lines.
[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_get_next_char_visually, 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 #include <config.h>
223 #include <stdio.h>
224 #include <limits.h>
225 #include <setjmp.h>
226
227 #include "lisp.h"
228 #include "keyboard.h"
229 #include "frame.h"
230 #include "window.h"
231 #include "termchar.h"
232 #include "dispextern.h"
233 #include "buffer.h"
234 #include "character.h"
235 #include "charset.h"
236 #include "indent.h"
237 #include "commands.h"
238 #include "keymap.h"
239 #include "macros.h"
240 #include "disptab.h"
241 #include "termhooks.h"
242 #include "intervals.h"
243 #include "coding.h"
244 #include "process.h"
245 #include "region-cache.h"
246 #include "font.h"
247 #include "fontset.h"
248 #include "blockinput.h"
249
250 #ifdef HAVE_X_WINDOWS
251 #include "xterm.h"
252 #endif
253 #ifdef WINDOWSNT
254 #include "w32term.h"
255 #endif
256 #ifdef HAVE_NS
257 #include "nsterm.h"
258 #endif
259 #ifdef USE_GTK
260 #include "gtkutil.h"
261 #endif
262
263 #include "font.h"
264
265 #ifndef FRAME_X_OUTPUT
266 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
267 #endif
268
269 #define INFINITY 10000000
270
271 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
272 || defined(HAVE_NS) || defined (USE_GTK)
273 extern void set_frame_menubar P_ ((struct frame *f, int, int));
274 extern int pending_menu_activation;
275 #endif
276
277 extern int interrupt_input;
278 extern int command_loop_level;
279
280 extern Lisp_Object do_mouse_tracking;
281
282 extern int minibuffer_auto_raise;
283 extern Lisp_Object Vminibuffer_list;
284
285 extern Lisp_Object Qface;
286 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
287
288 extern Lisp_Object Voverriding_local_map;
289 extern Lisp_Object Voverriding_local_map_menu_flag;
290 extern Lisp_Object Qmenu_item;
291 extern Lisp_Object Qwhen;
292 extern Lisp_Object Qhelp_echo;
293 extern Lisp_Object Qbefore_string, Qafter_string;
294
295 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
296 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
297 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
298 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
299 Lisp_Object Qinhibit_point_motion_hooks;
300 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
301 Lisp_Object Qfontified;
302 Lisp_Object Qgrow_only;
303 Lisp_Object Qinhibit_eval_during_redisplay;
304 Lisp_Object Qbuffer_position, Qposition, Qobject;
305 Lisp_Object Qright_to_left, Qleft_to_right;
306
307 /* Cursor shapes */
308 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
309
310 /* Pointer shapes */
311 Lisp_Object Qarrow, Qhand, Qtext;
312
313 Lisp_Object Qrisky_local_variable;
314
315 /* Holds the list (error). */
316 Lisp_Object list_of_error;
317
318 /* Functions called to fontify regions of text. */
319
320 Lisp_Object Vfontification_functions;
321 Lisp_Object Qfontification_functions;
322
323 /* Non-nil means automatically select any window when the mouse
324 cursor moves into it. */
325 Lisp_Object Vmouse_autoselect_window;
326
327 Lisp_Object Vwrap_prefix, Qwrap_prefix;
328 Lisp_Object Vline_prefix, Qline_prefix;
329
330 /* Non-zero means draw tool bar buttons raised when the mouse moves
331 over them. */
332
333 int auto_raise_tool_bar_buttons_p;
334
335 /* Non-zero means to reposition window if cursor line is only partially visible. */
336
337 int make_cursor_line_fully_visible_p;
338
339 /* Margin below tool bar in pixels. 0 or nil means no margin.
340 If value is `internal-border-width' or `border-width',
341 the corresponding frame parameter is used. */
342
343 Lisp_Object Vtool_bar_border;
344
345 /* Margin around tool bar buttons in pixels. */
346
347 Lisp_Object Vtool_bar_button_margin;
348
349 /* Thickness of shadow to draw around tool bar buttons. */
350
351 EMACS_INT tool_bar_button_relief;
352
353 /* Non-nil means automatically resize tool-bars so that all tool-bar
354 items are visible, and no blank lines remain.
355
356 If value is `grow-only', only make tool-bar bigger. */
357
358 Lisp_Object Vauto_resize_tool_bars;
359
360 /* Non-zero means draw block and hollow cursor as wide as the glyph
361 under it. For example, if a block cursor is over a tab, it will be
362 drawn as wide as that tab on the display. */
363
364 int x_stretch_cursor_p;
365
366 /* Non-nil means don't actually do any redisplay. */
367
368 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
369
370 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
371
372 int inhibit_eval_during_redisplay;
373
374 /* Names of text properties relevant for redisplay. */
375
376 Lisp_Object Qdisplay;
377 extern Lisp_Object Qface, Qinvisible, Qwidth;
378
379 /* Symbols used in text property values. */
380
381 Lisp_Object Vdisplay_pixels_per_inch;
382 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
383 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
384 Lisp_Object Qslice;
385 Lisp_Object Qcenter;
386 Lisp_Object Qmargin, Qpointer;
387 Lisp_Object Qline_height;
388 extern Lisp_Object Qheight;
389 extern Lisp_Object QCwidth, QCheight, QCascent;
390 extern Lisp_Object Qscroll_bar;
391 extern Lisp_Object Qcursor;
392
393 /* Non-nil means highlight trailing whitespace. */
394
395 Lisp_Object Vshow_trailing_whitespace;
396
397 /* Non-nil means escape non-break space and hyphens. */
398
399 Lisp_Object Vnobreak_char_display;
400
401 #ifdef HAVE_WINDOW_SYSTEM
402 extern Lisp_Object Voverflow_newline_into_fringe;
403
404 /* Test if overflow newline into fringe. Called with iterator IT
405 at or past right window margin, and with IT->current_x set. */
406
407 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
408 (!NILP (Voverflow_newline_into_fringe) \
409 && FRAME_WINDOW_P ((IT)->f) \
410 && ((IT)->bidi_it.paragraph_dir == R2L \
411 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
412 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
413 && (IT)->current_x == (IT)->last_visible_x \
414 && (IT)->line_wrap != WORD_WRAP)
415
416 #else /* !HAVE_WINDOW_SYSTEM */
417 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
418 #endif /* HAVE_WINDOW_SYSTEM */
419
420 /* Test if the display element loaded in IT is a space or tab
421 character. This is used to determine word wrapping. */
422
423 #define IT_DISPLAYING_WHITESPACE(it) \
424 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
425
426 /* Non-nil means show the text cursor in void text areas
427 i.e. in blank areas after eol and eob. This used to be
428 the default in 21.3. */
429
430 Lisp_Object Vvoid_text_area_pointer;
431
432 /* Name of the face used to highlight trailing whitespace. */
433
434 Lisp_Object Qtrailing_whitespace;
435
436 /* Name and number of the face used to highlight escape glyphs. */
437
438 Lisp_Object Qescape_glyph;
439
440 /* Name and number of the face used to highlight non-breaking spaces. */
441
442 Lisp_Object Qnobreak_space;
443
444 /* The symbol `image' which is the car of the lists used to represent
445 images in Lisp. */
446
447 Lisp_Object Qimage;
448
449 /* The image map types. */
450 Lisp_Object QCmap, QCpointer;
451 Lisp_Object Qrect, Qcircle, Qpoly;
452
453 /* Non-zero means print newline to stdout before next mini-buffer
454 message. */
455
456 int noninteractive_need_newline;
457
458 /* Non-zero means print newline to message log before next message. */
459
460 static int message_log_need_newline;
461
462 /* Three markers that message_dolog uses.
463 It could allocate them itself, but that causes trouble
464 in handling memory-full errors. */
465 static Lisp_Object message_dolog_marker1;
466 static Lisp_Object message_dolog_marker2;
467 static Lisp_Object message_dolog_marker3;
468 \f
469 /* The buffer position of the first character appearing entirely or
470 partially on the line of the selected window which contains the
471 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
472 redisplay optimization in redisplay_internal. */
473
474 static struct text_pos this_line_start_pos;
475
476 /* Number of characters past the end of the line above, including the
477 terminating newline. */
478
479 static struct text_pos this_line_end_pos;
480
481 /* The vertical positions and the height of this line. */
482
483 static int this_line_vpos;
484 static int this_line_y;
485 static int this_line_pixel_height;
486
487 /* X position at which this display line starts. Usually zero;
488 negative if first character is partially visible. */
489
490 static int this_line_start_x;
491
492 /* Buffer that this_line_.* variables are referring to. */
493
494 static struct buffer *this_line_buffer;
495
496 /* Nonzero means truncate lines in all windows less wide than the
497 frame. */
498
499 Lisp_Object Vtruncate_partial_width_windows;
500
501 /* A flag to control how to display unibyte 8-bit character. */
502
503 int unibyte_display_via_language_environment;
504
505 /* Nonzero means we have more than one non-mini-buffer-only frame.
506 Not guaranteed to be accurate except while parsing
507 frame-title-format. */
508
509 int multiple_frames;
510
511 Lisp_Object Vglobal_mode_string;
512
513
514 /* List of variables (symbols) which hold markers for overlay arrows.
515 The symbols on this list are examined during redisplay to determine
516 where to display overlay arrows. */
517
518 Lisp_Object Voverlay_arrow_variable_list;
519
520 /* Marker for where to display an arrow on top of the buffer text. */
521
522 Lisp_Object Voverlay_arrow_position;
523
524 /* String to display for the arrow. Only used on terminal frames. */
525
526 Lisp_Object Voverlay_arrow_string;
527
528 /* Values of those variables at last redisplay are stored as
529 properties on `overlay-arrow-position' symbol. However, if
530 Voverlay_arrow_position is a marker, last-arrow-position is its
531 numerical position. */
532
533 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
534
535 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
536 properties on a symbol in overlay-arrow-variable-list. */
537
538 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
539
540 /* Like mode-line-format, but for the title bar on a visible frame. */
541
542 Lisp_Object Vframe_title_format;
543
544 /* Like mode-line-format, but for the title bar on an iconified frame. */
545
546 Lisp_Object Vicon_title_format;
547
548 /* List of functions to call when a window's size changes. These
549 functions get one arg, a frame on which one or more windows' sizes
550 have changed. */
551
552 static Lisp_Object Vwindow_size_change_functions;
553
554 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
555
556 /* Nonzero if an overlay arrow has been displayed in this window. */
557
558 static int overlay_arrow_seen;
559
560 /* Nonzero means highlight the region even in nonselected windows. */
561
562 int highlight_nonselected_windows;
563
564 /* If cursor motion alone moves point off frame, try scrolling this
565 many lines up or down if that will bring it back. */
566
567 static EMACS_INT scroll_step;
568
569 /* Nonzero means scroll just far enough to bring point back on the
570 screen, when appropriate. */
571
572 static EMACS_INT scroll_conservatively;
573
574 /* Recenter the window whenever point gets within this many lines of
575 the top or bottom of the window. This value is translated into a
576 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
577 that there is really a fixed pixel height scroll margin. */
578
579 EMACS_INT scroll_margin;
580
581 /* Number of windows showing the buffer of the selected window (or
582 another buffer with the same base buffer). keyboard.c refers to
583 this. */
584
585 int buffer_shared;
586
587 /* Vector containing glyphs for an ellipsis `...'. */
588
589 static Lisp_Object default_invis_vector[3];
590
591 /* Zero means display the mode-line/header-line/menu-bar in the default face
592 (this slightly odd definition is for compatibility with previous versions
593 of emacs), non-zero means display them using their respective faces.
594
595 This variable is deprecated. */
596
597 int mode_line_inverse_video;
598
599 /* Prompt to display in front of the mini-buffer contents. */
600
601 Lisp_Object minibuf_prompt;
602
603 /* Width of current mini-buffer prompt. Only set after display_line
604 of the line that contains the prompt. */
605
606 int minibuf_prompt_width;
607
608 /* This is the window where the echo area message was displayed. It
609 is always a mini-buffer window, but it may not be the same window
610 currently active as a mini-buffer. */
611
612 Lisp_Object echo_area_window;
613
614 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
615 pushes the current message and the value of
616 message_enable_multibyte on the stack, the function restore_message
617 pops the stack and displays MESSAGE again. */
618
619 Lisp_Object Vmessage_stack;
620
621 /* Nonzero means multibyte characters were enabled when the echo area
622 message was specified. */
623
624 int message_enable_multibyte;
625
626 /* Nonzero if we should redraw the mode lines on the next redisplay. */
627
628 int update_mode_lines;
629
630 /* Nonzero if window sizes or contents have changed since last
631 redisplay that finished. */
632
633 int windows_or_buffers_changed;
634
635 /* Nonzero means a frame's cursor type has been changed. */
636
637 int cursor_type_changed;
638
639 /* Nonzero after display_mode_line if %l was used and it displayed a
640 line number. */
641
642 int line_number_displayed;
643
644 /* Maximum buffer size for which to display line numbers. */
645
646 Lisp_Object Vline_number_display_limit;
647
648 /* Line width to consider when repositioning for line number display. */
649
650 static EMACS_INT line_number_display_limit_width;
651
652 /* Number of lines to keep in the message log buffer. t means
653 infinite. nil means don't log at all. */
654
655 Lisp_Object Vmessage_log_max;
656
657 /* The name of the *Messages* buffer, a string. */
658
659 static Lisp_Object Vmessages_buffer_name;
660
661 /* Current, index 0, and last displayed echo area message. Either
662 buffers from echo_buffers, or nil to indicate no message. */
663
664 Lisp_Object echo_area_buffer[2];
665
666 /* The buffers referenced from echo_area_buffer. */
667
668 static Lisp_Object echo_buffer[2];
669
670 /* A vector saved used in with_area_buffer to reduce consing. */
671
672 static Lisp_Object Vwith_echo_area_save_vector;
673
674 /* Non-zero means display_echo_area should display the last echo area
675 message again. Set by redisplay_preserve_echo_area. */
676
677 static int display_last_displayed_message_p;
678
679 /* Nonzero if echo area is being used by print; zero if being used by
680 message. */
681
682 int message_buf_print;
683
684 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
685
686 Lisp_Object Qinhibit_menubar_update;
687 int inhibit_menubar_update;
688
689 /* When evaluating expressions from menu bar items (enable conditions,
690 for instance), this is the frame they are being processed for. */
691
692 Lisp_Object Vmenu_updating_frame;
693
694 /* Maximum height for resizing mini-windows. Either a float
695 specifying a fraction of the available height, or an integer
696 specifying a number of lines. */
697
698 Lisp_Object Vmax_mini_window_height;
699
700 /* Non-zero means messages should be displayed with truncated
701 lines instead of being continued. */
702
703 int message_truncate_lines;
704 Lisp_Object Qmessage_truncate_lines;
705
706 /* Set to 1 in clear_message to make redisplay_internal aware
707 of an emptied echo area. */
708
709 static int message_cleared_p;
710
711 /* How to blink the default frame cursor off. */
712 Lisp_Object Vblink_cursor_alist;
713
714 /* A scratch glyph row with contents used for generating truncation
715 glyphs. Also used in direct_output_for_insert. */
716
717 #define MAX_SCRATCH_GLYPHS 100
718 struct glyph_row scratch_glyph_row;
719 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
720
721 /* Ascent and height of the last line processed by move_it_to. */
722
723 static int last_max_ascent, last_height;
724
725 /* Non-zero if there's a help-echo in the echo area. */
726
727 int help_echo_showing_p;
728
729 /* If >= 0, computed, exact values of mode-line and header-line height
730 to use in the macros CURRENT_MODE_LINE_HEIGHT and
731 CURRENT_HEADER_LINE_HEIGHT. */
732
733 int current_mode_line_height, current_header_line_height;
734
735 /* The maximum distance to look ahead for text properties. Values
736 that are too small let us call compute_char_face and similar
737 functions too often which is expensive. Values that are too large
738 let us call compute_char_face and alike too often because we
739 might not be interested in text properties that far away. */
740
741 #define TEXT_PROP_DISTANCE_LIMIT 100
742
743 #if GLYPH_DEBUG
744
745 /* Variables to turn off display optimizations from Lisp. */
746
747 int inhibit_try_window_id, inhibit_try_window_reusing;
748 int inhibit_try_cursor_movement;
749
750 /* Non-zero means print traces of redisplay if compiled with
751 GLYPH_DEBUG != 0. */
752
753 int trace_redisplay_p;
754
755 #endif /* GLYPH_DEBUG */
756
757 #ifdef DEBUG_TRACE_MOVE
758 /* Non-zero means trace with TRACE_MOVE to stderr. */
759 int trace_move;
760
761 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
762 #else
763 #define TRACE_MOVE(x) (void) 0
764 #endif
765
766 /* Non-zero means automatically scroll windows horizontally to make
767 point visible. */
768
769 int automatic_hscrolling_p;
770 Lisp_Object Qauto_hscroll_mode;
771
772 /* How close to the margin can point get before the window is scrolled
773 horizontally. */
774 EMACS_INT hscroll_margin;
775
776 /* How much to scroll horizontally when point is inside the above margin. */
777 Lisp_Object Vhscroll_step;
778
779 /* The variable `resize-mini-windows'. If nil, don't resize
780 mini-windows. If t, always resize them to fit the text they
781 display. If `grow-only', let mini-windows grow only until they
782 become empty. */
783
784 Lisp_Object Vresize_mini_windows;
785
786 /* Buffer being redisplayed -- for redisplay_window_error. */
787
788 struct buffer *displayed_buffer;
789
790 /* Space between overline and text. */
791
792 EMACS_INT overline_margin;
793
794 /* Require underline to be at least this many screen pixels below baseline
795 This to avoid underline "merging" with the base of letters at small
796 font sizes, particularly when x_use_underline_position_properties is on. */
797
798 EMACS_INT underline_minimum_offset;
799
800 /* Value returned from text property handlers (see below). */
801
802 enum prop_handled
803 {
804 HANDLED_NORMALLY,
805 HANDLED_RECOMPUTE_PROPS,
806 HANDLED_OVERLAY_STRING_CONSUMED,
807 HANDLED_RETURN
808 };
809
810 /* A description of text properties that redisplay is interested
811 in. */
812
813 struct props
814 {
815 /* The name of the property. */
816 Lisp_Object *name;
817
818 /* A unique index for the property. */
819 enum prop_idx idx;
820
821 /* A handler function called to set up iterator IT from the property
822 at IT's current position. Value is used to steer handle_stop. */
823 enum prop_handled (*handler) P_ ((struct it *it));
824 };
825
826 static enum prop_handled handle_face_prop P_ ((struct it *));
827 static enum prop_handled handle_invisible_prop P_ ((struct it *));
828 static enum prop_handled handle_display_prop P_ ((struct it *));
829 static enum prop_handled handle_composition_prop P_ ((struct it *));
830 static enum prop_handled handle_overlay_change P_ ((struct it *));
831 static enum prop_handled handle_fontified_prop P_ ((struct it *));
832
833 /* Properties handled by iterators. */
834
835 static struct props it_props[] =
836 {
837 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
838 /* Handle `face' before `display' because some sub-properties of
839 `display' need to know the face. */
840 {&Qface, FACE_PROP_IDX, handle_face_prop},
841 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
842 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
843 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
844 {NULL, 0, NULL}
845 };
846
847 /* Value is the position described by X. If X is a marker, value is
848 the marker_position of X. Otherwise, value is X. */
849
850 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
851
852 /* Enumeration returned by some move_it_.* functions internally. */
853
854 enum move_it_result
855 {
856 /* Not used. Undefined value. */
857 MOVE_UNDEFINED,
858
859 /* Move ended at the requested buffer position or ZV. */
860 MOVE_POS_MATCH_OR_ZV,
861
862 /* Move ended at the requested X pixel position. */
863 MOVE_X_REACHED,
864
865 /* Move within a line ended at the end of a line that must be
866 continued. */
867 MOVE_LINE_CONTINUED,
868
869 /* Move within a line ended at the end of a line that would
870 be displayed truncated. */
871 MOVE_LINE_TRUNCATED,
872
873 /* Move within a line ended at a line end. */
874 MOVE_NEWLINE_OR_CR
875 };
876
877 /* This counter is used to clear the face cache every once in a while
878 in redisplay_internal. It is incremented for each redisplay.
879 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
880 cleared. */
881
882 #define CLEAR_FACE_CACHE_COUNT 500
883 static int clear_face_cache_count;
884
885 /* Similarly for the image cache. */
886
887 #ifdef HAVE_WINDOW_SYSTEM
888 #define CLEAR_IMAGE_CACHE_COUNT 101
889 static int clear_image_cache_count;
890 #endif
891
892 /* Non-zero while redisplay_internal is in progress. */
893
894 int redisplaying_p;
895
896 /* Non-zero means don't free realized faces. Bound while freeing
897 realized faces is dangerous because glyph matrices might still
898 reference them. */
899
900 int inhibit_free_realized_faces;
901 Lisp_Object Qinhibit_free_realized_faces;
902
903 /* If a string, XTread_socket generates an event to display that string.
904 (The display is done in read_char.) */
905
906 Lisp_Object help_echo_string;
907 Lisp_Object help_echo_window;
908 Lisp_Object help_echo_object;
909 int help_echo_pos;
910
911 /* Temporary variable for XTread_socket. */
912
913 Lisp_Object previous_help_echo_string;
914
915 /* Null glyph slice */
916
917 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
918
919 /* Platform-independent portion of hourglass implementation. */
920
921 /* Non-zero means we're allowed to display a hourglass pointer. */
922 int display_hourglass_p;
923
924 /* Non-zero means an hourglass cursor is currently shown. */
925 int hourglass_shown_p;
926
927 /* If non-null, an asynchronous timer that, when it expires, displays
928 an hourglass cursor on all frames. */
929 struct atimer *hourglass_atimer;
930
931 /* Number of seconds to wait before displaying an hourglass cursor. */
932 Lisp_Object Vhourglass_delay;
933
934 /* Default number of seconds to wait before displaying an hourglass
935 cursor. */
936 #define DEFAULT_HOURGLASS_DELAY 1
937
938 \f
939 /* Function prototypes. */
940
941 static void setup_for_ellipsis P_ ((struct it *, int));
942 static void mark_window_display_accurate_1 P_ ((struct window *, int));
943 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
944 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
945 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
946 static int redisplay_mode_lines P_ ((Lisp_Object, int));
947 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
948
949 static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop));
950
951 static void handle_line_prefix P_ ((struct it *));
952
953 static void pint2str P_ ((char *, int, int));
954 static void pint2hrstr P_ ((char *, int, int));
955 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
956 struct text_pos));
957 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
958 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
959 static void store_mode_line_noprop_char P_ ((char));
960 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
961 static void x_consider_frame_title P_ ((Lisp_Object));
962 static void handle_stop P_ ((struct it *));
963 static void handle_stop_backwards P_ ((struct it *, EMACS_INT));
964 static int tool_bar_lines_needed P_ ((struct frame *, int *));
965 static int single_display_spec_intangible_p P_ ((Lisp_Object));
966 static void ensure_echo_area_buffers P_ ((void));
967 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
968 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
969 static int with_echo_area_buffer P_ ((struct window *, int,
970 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
971 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
972 static void clear_garbaged_frames P_ ((void));
973 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
974 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
975 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
976 static int display_echo_area P_ ((struct window *));
977 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
978 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
979 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
980 static int string_char_and_length P_ ((const unsigned char *, int *));
981 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
982 struct text_pos));
983 static int compute_window_start_on_continuation_line P_ ((struct window *));
984 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
985 static void insert_left_trunc_glyphs P_ ((struct it *));
986 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
987 Lisp_Object));
988 static void extend_face_to_end_of_line P_ ((struct it *));
989 static int append_space_for_newline P_ ((struct it *, int));
990 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
991 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
992 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
993 static int trailing_whitespace_p P_ ((int));
994 static int message_log_check_duplicate P_ ((int, int, int, int));
995 static void push_it P_ ((struct it *));
996 static void pop_it P_ ((struct it *));
997 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
998 static void select_frame_for_redisplay P_ ((Lisp_Object));
999 static void redisplay_internal P_ ((int));
1000 static int echo_area_display P_ ((int));
1001 static void redisplay_windows P_ ((Lisp_Object));
1002 static void redisplay_window P_ ((Lisp_Object, int));
1003 static Lisp_Object redisplay_window_error ();
1004 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
1005 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
1006 static int update_menu_bar P_ ((struct frame *, int, int));
1007 static int try_window_reusing_current_matrix P_ ((struct window *));
1008 static int try_window_id P_ ((struct window *));
1009 static int display_line P_ ((struct it *));
1010 static int display_mode_lines P_ ((struct window *));
1011 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
1012 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
1013 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
1014 static char *decode_mode_spec P_ ((struct window *, int, int, int,
1015 Lisp_Object *));
1016 static void display_menu_bar P_ ((struct window *));
1017 static int display_count_lines P_ ((int, int, int, int, int *));
1018 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
1019 EMACS_INT, EMACS_INT, struct it *, int, int, int, int));
1020 static void compute_line_metrics P_ ((struct it *));
1021 static void run_redisplay_end_trigger_hook P_ ((struct it *));
1022 static int get_overlay_strings P_ ((struct it *, int));
1023 static int get_overlay_strings_1 P_ ((struct it *, int, int));
1024 static void next_overlay_string P_ ((struct it *));
1025 static void reseat P_ ((struct it *, struct text_pos, int));
1026 static void reseat_1 P_ ((struct it *, struct text_pos, int));
1027 static void back_to_previous_visible_line_start P_ ((struct it *));
1028 void reseat_at_previous_visible_line_start P_ ((struct it *));
1029 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
1030 static int next_element_from_ellipsis P_ ((struct it *));
1031 static int next_element_from_display_vector P_ ((struct it *));
1032 static int next_element_from_string P_ ((struct it *));
1033 static int next_element_from_c_string P_ ((struct it *));
1034 static int next_element_from_buffer P_ ((struct it *));
1035 static int next_element_from_composition P_ ((struct it *));
1036 static int next_element_from_image P_ ((struct it *));
1037 static int next_element_from_stretch P_ ((struct it *));
1038 static void load_overlay_strings P_ ((struct it *, int));
1039 static int init_from_display_pos P_ ((struct it *, struct window *,
1040 struct display_pos *));
1041 static void reseat_to_string P_ ((struct it *, unsigned char *,
1042 Lisp_Object, int, int, int, int));
1043 static enum move_it_result
1044 move_it_in_display_line_to (struct it *, EMACS_INT, int,
1045 enum move_operation_enum);
1046 void move_it_vertically_backward P_ ((struct it *, int));
1047 static void init_to_row_start P_ ((struct it *, struct window *,
1048 struct glyph_row *));
1049 static int init_to_row_end P_ ((struct it *, struct window *,
1050 struct glyph_row *));
1051 static void back_to_previous_line_start P_ ((struct it *));
1052 static int forward_to_next_line_start P_ ((struct it *, int *));
1053 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
1054 Lisp_Object, int));
1055 static struct text_pos string_pos P_ ((int, Lisp_Object));
1056 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
1057 static int number_of_chars P_ ((unsigned char *, int));
1058 static void compute_stop_pos P_ ((struct it *));
1059 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
1060 Lisp_Object));
1061 static int face_before_or_after_it_pos P_ ((struct it *, int));
1062 static EMACS_INT next_overlay_change P_ ((EMACS_INT));
1063 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
1064 Lisp_Object, Lisp_Object,
1065 struct text_pos *, int));
1066 static int underlying_face_id P_ ((struct it *));
1067 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
1068 struct window *));
1069
1070 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1071 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1072
1073 #ifdef HAVE_WINDOW_SYSTEM
1074
1075 static void update_tool_bar P_ ((struct frame *, int));
1076 static void build_desired_tool_bar_string P_ ((struct frame *f));
1077 static int redisplay_tool_bar P_ ((struct frame *));
1078 static void display_tool_bar_line P_ ((struct it *, int));
1079 static void notice_overwritten_cursor P_ ((struct window *,
1080 enum glyph_row_area,
1081 int, int, int, int));
1082 static void append_stretch_glyph P_ ((struct it *, Lisp_Object,
1083 int, int, int));
1084
1085
1086
1087 #endif /* HAVE_WINDOW_SYSTEM */
1088
1089 \f
1090 /***********************************************************************
1091 Window display dimensions
1092 ***********************************************************************/
1093
1094 /* Return the bottom boundary y-position for text lines in window W.
1095 This is the first y position at which a line cannot start.
1096 It is relative to the top of the window.
1097
1098 This is the height of W minus the height of a mode line, if any. */
1099
1100 INLINE int
1101 window_text_bottom_y (w)
1102 struct window *w;
1103 {
1104 int height = WINDOW_TOTAL_HEIGHT (w);
1105
1106 if (WINDOW_WANTS_MODELINE_P (w))
1107 height -= CURRENT_MODE_LINE_HEIGHT (w);
1108 return height;
1109 }
1110
1111 /* Return the pixel width of display area AREA of window W. AREA < 0
1112 means return the total width of W, not including fringes to
1113 the left and right of the window. */
1114
1115 INLINE int
1116 window_box_width (w, area)
1117 struct window *w;
1118 int area;
1119 {
1120 int cols = XFASTINT (w->total_cols);
1121 int pixels = 0;
1122
1123 if (!w->pseudo_window_p)
1124 {
1125 cols -= WINDOW_SCROLL_BAR_COLS (w);
1126
1127 if (area == TEXT_AREA)
1128 {
1129 if (INTEGERP (w->left_margin_cols))
1130 cols -= XFASTINT (w->left_margin_cols);
1131 if (INTEGERP (w->right_margin_cols))
1132 cols -= XFASTINT (w->right_margin_cols);
1133 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1134 }
1135 else if (area == LEFT_MARGIN_AREA)
1136 {
1137 cols = (INTEGERP (w->left_margin_cols)
1138 ? XFASTINT (w->left_margin_cols) : 0);
1139 pixels = 0;
1140 }
1141 else if (area == RIGHT_MARGIN_AREA)
1142 {
1143 cols = (INTEGERP (w->right_margin_cols)
1144 ? XFASTINT (w->right_margin_cols) : 0);
1145 pixels = 0;
1146 }
1147 }
1148
1149 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1150 }
1151
1152
1153 /* Return the pixel height of the display area of window W, not
1154 including mode lines of W, if any. */
1155
1156 INLINE int
1157 window_box_height (w)
1158 struct window *w;
1159 {
1160 struct frame *f = XFRAME (w->frame);
1161 int height = WINDOW_TOTAL_HEIGHT (w);
1162
1163 xassert (height >= 0);
1164
1165 /* Note: the code below that determines the mode-line/header-line
1166 height is essentially the same as that contained in the macro
1167 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1168 the appropriate glyph row has its `mode_line_p' flag set,
1169 and if it doesn't, uses estimate_mode_line_height instead. */
1170
1171 if (WINDOW_WANTS_MODELINE_P (w))
1172 {
1173 struct glyph_row *ml_row
1174 = (w->current_matrix && w->current_matrix->rows
1175 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1176 : 0);
1177 if (ml_row && ml_row->mode_line_p)
1178 height -= ml_row->height;
1179 else
1180 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1181 }
1182
1183 if (WINDOW_WANTS_HEADER_LINE_P (w))
1184 {
1185 struct glyph_row *hl_row
1186 = (w->current_matrix && w->current_matrix->rows
1187 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1188 : 0);
1189 if (hl_row && hl_row->mode_line_p)
1190 height -= hl_row->height;
1191 else
1192 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1193 }
1194
1195 /* With a very small font and a mode-line that's taller than
1196 default, we might end up with a negative height. */
1197 return max (0, height);
1198 }
1199
1200 /* Return the window-relative coordinate of the left edge of display
1201 area AREA of window W. AREA < 0 means return the left edge of the
1202 whole window, to the right of the left fringe of W. */
1203
1204 INLINE int
1205 window_box_left_offset (w, area)
1206 struct window *w;
1207 int area;
1208 {
1209 int x;
1210
1211 if (w->pseudo_window_p)
1212 return 0;
1213
1214 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1215
1216 if (area == TEXT_AREA)
1217 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1218 + window_box_width (w, LEFT_MARGIN_AREA));
1219 else if (area == RIGHT_MARGIN_AREA)
1220 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1221 + window_box_width (w, LEFT_MARGIN_AREA)
1222 + window_box_width (w, TEXT_AREA)
1223 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1224 ? 0
1225 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1226 else if (area == LEFT_MARGIN_AREA
1227 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1228 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1229
1230 return x;
1231 }
1232
1233
1234 /* Return the window-relative coordinate of the right edge of display
1235 area AREA of window W. AREA < 0 means return the left edge of the
1236 whole window, to the left of the right fringe of W. */
1237
1238 INLINE int
1239 window_box_right_offset (w, area)
1240 struct window *w;
1241 int area;
1242 {
1243 return window_box_left_offset (w, area) + window_box_width (w, area);
1244 }
1245
1246 /* Return the frame-relative coordinate of the left edge of display
1247 area AREA of window W. AREA < 0 means return the left edge of the
1248 whole window, to the right of the left fringe of W. */
1249
1250 INLINE int
1251 window_box_left (w, area)
1252 struct window *w;
1253 int area;
1254 {
1255 struct frame *f = XFRAME (w->frame);
1256 int x;
1257
1258 if (w->pseudo_window_p)
1259 return FRAME_INTERNAL_BORDER_WIDTH (f);
1260
1261 x = (WINDOW_LEFT_EDGE_X (w)
1262 + window_box_left_offset (w, area));
1263
1264 return x;
1265 }
1266
1267
1268 /* Return the frame-relative coordinate of the right edge of display
1269 area AREA of window W. AREA < 0 means return the left edge of the
1270 whole window, to the left of the right fringe of W. */
1271
1272 INLINE int
1273 window_box_right (w, area)
1274 struct window *w;
1275 int area;
1276 {
1277 return window_box_left (w, area) + window_box_width (w, area);
1278 }
1279
1280 /* Get the bounding box of the display area AREA of window W, without
1281 mode lines, in frame-relative coordinates. AREA < 0 means the
1282 whole window, not including the left and right fringes of
1283 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1284 coordinates of the upper-left corner of the box. Return in
1285 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1286
1287 INLINE void
1288 window_box (w, area, box_x, box_y, box_width, box_height)
1289 struct window *w;
1290 int area;
1291 int *box_x, *box_y, *box_width, *box_height;
1292 {
1293 if (box_width)
1294 *box_width = window_box_width (w, area);
1295 if (box_height)
1296 *box_height = window_box_height (w);
1297 if (box_x)
1298 *box_x = window_box_left (w, area);
1299 if (box_y)
1300 {
1301 *box_y = WINDOW_TOP_EDGE_Y (w);
1302 if (WINDOW_WANTS_HEADER_LINE_P (w))
1303 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1304 }
1305 }
1306
1307
1308 /* Get the bounding box of the display area AREA of window W, without
1309 mode lines. AREA < 0 means the whole window, not including the
1310 left and right fringe of the window. Return in *TOP_LEFT_X
1311 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1312 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1313 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1314 box. */
1315
1316 INLINE void
1317 window_box_edges (w, area, top_left_x, top_left_y,
1318 bottom_right_x, bottom_right_y)
1319 struct window *w;
1320 int area;
1321 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1322 {
1323 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1324 bottom_right_y);
1325 *bottom_right_x += *top_left_x;
1326 *bottom_right_y += *top_left_y;
1327 }
1328
1329
1330 \f
1331 /***********************************************************************
1332 Utilities
1333 ***********************************************************************/
1334
1335 /* Return the bottom y-position of the line the iterator IT is in.
1336 This can modify IT's settings. */
1337
1338 int
1339 line_bottom_y (it)
1340 struct it *it;
1341 {
1342 int line_height = it->max_ascent + it->max_descent;
1343 int line_top_y = it->current_y;
1344
1345 if (line_height == 0)
1346 {
1347 if (last_height)
1348 line_height = last_height;
1349 else if (IT_CHARPOS (*it) < ZV)
1350 {
1351 move_it_by_lines (it, 1, 1);
1352 line_height = (it->max_ascent || it->max_descent
1353 ? it->max_ascent + it->max_descent
1354 : last_height);
1355 }
1356 else
1357 {
1358 struct glyph_row *row = it->glyph_row;
1359
1360 /* Use the default character height. */
1361 it->glyph_row = NULL;
1362 it->what = IT_CHARACTER;
1363 it->c = ' ';
1364 it->len = 1;
1365 PRODUCE_GLYPHS (it);
1366 line_height = it->ascent + it->descent;
1367 it->glyph_row = row;
1368 }
1369 }
1370
1371 return line_top_y + line_height;
1372 }
1373
1374
1375 /* Return 1 if position CHARPOS is visible in window W.
1376 CHARPOS < 0 means return info about WINDOW_END position.
1377 If visible, set *X and *Y to pixel coordinates of top left corner.
1378 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1379 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1380
1381 int
1382 pos_visible_p (w, charpos, x, y, rtop, rbot, rowh, vpos)
1383 struct window *w;
1384 int charpos, *x, *y, *rtop, *rbot, *rowh, *vpos;
1385 {
1386 struct it it;
1387 struct text_pos top;
1388 int visible_p = 0;
1389 struct buffer *old_buffer = NULL;
1390
1391 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1392 return visible_p;
1393
1394 if (XBUFFER (w->buffer) != current_buffer)
1395 {
1396 old_buffer = current_buffer;
1397 set_buffer_internal_1 (XBUFFER (w->buffer));
1398 }
1399
1400 SET_TEXT_POS_FROM_MARKER (top, w->start);
1401
1402 /* Compute exact mode line heights. */
1403 if (WINDOW_WANTS_MODELINE_P (w))
1404 current_mode_line_height
1405 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1406 current_buffer->mode_line_format);
1407
1408 if (WINDOW_WANTS_HEADER_LINE_P (w))
1409 current_header_line_height
1410 = display_mode_line (w, HEADER_LINE_FACE_ID,
1411 current_buffer->header_line_format);
1412
1413 start_display (&it, w, top);
1414 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1415 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1416
1417 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1418 {
1419 /* We have reached CHARPOS, or passed it. How the call to
1420 move_it_to can overshoot: (i) If CHARPOS is on invisible
1421 text, move_it_to stops at the end of the invisible text,
1422 after CHARPOS. (ii) If CHARPOS is in a display vector,
1423 move_it_to stops on its last glyph. */
1424 int top_x = it.current_x;
1425 int top_y = it.current_y;
1426 enum it_method it_method = it.method;
1427 /* Calling line_bottom_y may change it.method, it.position, etc. */
1428 int bottom_y = (last_height = 0, line_bottom_y (&it));
1429 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1430
1431 if (top_y < window_top_y)
1432 visible_p = bottom_y > window_top_y;
1433 else if (top_y < it.last_visible_y)
1434 visible_p = 1;
1435 if (visible_p)
1436 {
1437 if (it_method == GET_FROM_DISPLAY_VECTOR)
1438 {
1439 /* We stopped on the last glyph of a display vector.
1440 Try and recompute. Hack alert! */
1441 if (charpos < 2 || top.charpos >= charpos)
1442 top_x = it.glyph_row->x;
1443 else
1444 {
1445 struct it it2;
1446 start_display (&it2, w, top);
1447 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1448 get_next_display_element (&it2);
1449 PRODUCE_GLYPHS (&it2);
1450 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1451 || it2.current_x > it2.last_visible_x)
1452 top_x = it.glyph_row->x;
1453 else
1454 {
1455 top_x = it2.current_x;
1456 top_y = it2.current_y;
1457 }
1458 }
1459 }
1460
1461 *x = top_x;
1462 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1463 *rtop = max (0, window_top_y - top_y);
1464 *rbot = max (0, bottom_y - it.last_visible_y);
1465 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1466 - max (top_y, window_top_y)));
1467 *vpos = it.vpos;
1468 }
1469 }
1470 else
1471 {
1472 struct it it2;
1473
1474 it2 = it;
1475 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1476 move_it_by_lines (&it, 1, 0);
1477 if (charpos < IT_CHARPOS (it)
1478 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1479 {
1480 visible_p = 1;
1481 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1482 *x = it2.current_x;
1483 *y = it2.current_y + it2.max_ascent - it2.ascent;
1484 *rtop = max (0, -it2.current_y);
1485 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1486 - it.last_visible_y));
1487 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1488 it.last_visible_y)
1489 - max (it2.current_y,
1490 WINDOW_HEADER_LINE_HEIGHT (w))));
1491 *vpos = it2.vpos;
1492 }
1493 }
1494
1495 if (old_buffer)
1496 set_buffer_internal_1 (old_buffer);
1497
1498 current_header_line_height = current_mode_line_height = -1;
1499
1500 if (visible_p && XFASTINT (w->hscroll) > 0)
1501 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1502
1503 #if 0
1504 /* Debugging code. */
1505 if (visible_p)
1506 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1507 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1508 else
1509 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1510 #endif
1511
1512 return visible_p;
1513 }
1514
1515
1516 /* Return the next character from STR which is MAXLEN bytes long.
1517 Return in *LEN the length of the character. This is like
1518 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1519 we find one, we return a `?', but with the length of the invalid
1520 character. */
1521
1522 static INLINE int
1523 string_char_and_length (str, len)
1524 const unsigned char *str;
1525 int *len;
1526 {
1527 int c;
1528
1529 c = STRING_CHAR_AND_LENGTH (str, *len);
1530 if (!CHAR_VALID_P (c, 1))
1531 /* We may not change the length here because other places in Emacs
1532 don't use this function, i.e. they silently accept invalid
1533 characters. */
1534 c = '?';
1535
1536 return c;
1537 }
1538
1539
1540
1541 /* Given a position POS containing a valid character and byte position
1542 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1543
1544 static struct text_pos
1545 string_pos_nchars_ahead (pos, string, nchars)
1546 struct text_pos pos;
1547 Lisp_Object string;
1548 int nchars;
1549 {
1550 xassert (STRINGP (string) && nchars >= 0);
1551
1552 if (STRING_MULTIBYTE (string))
1553 {
1554 int rest = SBYTES (string) - BYTEPOS (pos);
1555 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1556 int len;
1557
1558 while (nchars--)
1559 {
1560 string_char_and_length (p, &len);
1561 p += len, rest -= len;
1562 xassert (rest >= 0);
1563 CHARPOS (pos) += 1;
1564 BYTEPOS (pos) += len;
1565 }
1566 }
1567 else
1568 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1569
1570 return pos;
1571 }
1572
1573
1574 /* Value is the text position, i.e. character and byte position,
1575 for character position CHARPOS in STRING. */
1576
1577 static INLINE struct text_pos
1578 string_pos (charpos, string)
1579 int charpos;
1580 Lisp_Object string;
1581 {
1582 struct text_pos pos;
1583 xassert (STRINGP (string));
1584 xassert (charpos >= 0);
1585 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1586 return pos;
1587 }
1588
1589
1590 /* Value is a text position, i.e. character and byte position, for
1591 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1592 means recognize multibyte characters. */
1593
1594 static struct text_pos
1595 c_string_pos (charpos, s, multibyte_p)
1596 int charpos;
1597 unsigned char *s;
1598 int multibyte_p;
1599 {
1600 struct text_pos pos;
1601
1602 xassert (s != NULL);
1603 xassert (charpos >= 0);
1604
1605 if (multibyte_p)
1606 {
1607 int rest = strlen (s), len;
1608
1609 SET_TEXT_POS (pos, 0, 0);
1610 while (charpos--)
1611 {
1612 string_char_and_length (s, &len);
1613 s += len, rest -= len;
1614 xassert (rest >= 0);
1615 CHARPOS (pos) += 1;
1616 BYTEPOS (pos) += len;
1617 }
1618 }
1619 else
1620 SET_TEXT_POS (pos, charpos, charpos);
1621
1622 return pos;
1623 }
1624
1625
1626 /* Value is the number of characters in C string S. MULTIBYTE_P
1627 non-zero means recognize multibyte characters. */
1628
1629 static int
1630 number_of_chars (s, multibyte_p)
1631 unsigned char *s;
1632 int multibyte_p;
1633 {
1634 int nchars;
1635
1636 if (multibyte_p)
1637 {
1638 int rest = strlen (s), len;
1639 unsigned char *p = (unsigned char *) s;
1640
1641 for (nchars = 0; rest > 0; ++nchars)
1642 {
1643 string_char_and_length (p, &len);
1644 rest -= len, p += len;
1645 }
1646 }
1647 else
1648 nchars = strlen (s);
1649
1650 return nchars;
1651 }
1652
1653
1654 /* Compute byte position NEWPOS->bytepos corresponding to
1655 NEWPOS->charpos. POS is a known position in string STRING.
1656 NEWPOS->charpos must be >= POS.charpos. */
1657
1658 static void
1659 compute_string_pos (newpos, pos, string)
1660 struct text_pos *newpos, pos;
1661 Lisp_Object string;
1662 {
1663 xassert (STRINGP (string));
1664 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1665
1666 if (STRING_MULTIBYTE (string))
1667 *newpos = string_pos_nchars_ahead (pos, string,
1668 CHARPOS (*newpos) - CHARPOS (pos));
1669 else
1670 BYTEPOS (*newpos) = CHARPOS (*newpos);
1671 }
1672
1673 /* EXPORT:
1674 Return an estimation of the pixel height of mode or header lines on
1675 frame F. FACE_ID specifies what line's height to estimate. */
1676
1677 int
1678 estimate_mode_line_height (f, face_id)
1679 struct frame *f;
1680 enum face_id face_id;
1681 {
1682 #ifdef HAVE_WINDOW_SYSTEM
1683 if (FRAME_WINDOW_P (f))
1684 {
1685 int height = FONT_HEIGHT (FRAME_FONT (f));
1686
1687 /* This function is called so early when Emacs starts that the face
1688 cache and mode line face are not yet initialized. */
1689 if (FRAME_FACE_CACHE (f))
1690 {
1691 struct face *face = FACE_FROM_ID (f, face_id);
1692 if (face)
1693 {
1694 if (face->font)
1695 height = FONT_HEIGHT (face->font);
1696 if (face->box_line_width > 0)
1697 height += 2 * face->box_line_width;
1698 }
1699 }
1700
1701 return height;
1702 }
1703 #endif
1704
1705 return 1;
1706 }
1707
1708 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1709 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1710 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1711 not force the value into range. */
1712
1713 void
1714 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1715 FRAME_PTR f;
1716 register int pix_x, pix_y;
1717 int *x, *y;
1718 NativeRectangle *bounds;
1719 int noclip;
1720 {
1721
1722 #ifdef HAVE_WINDOW_SYSTEM
1723 if (FRAME_WINDOW_P (f))
1724 {
1725 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1726 even for negative values. */
1727 if (pix_x < 0)
1728 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1729 if (pix_y < 0)
1730 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1731
1732 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1733 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1734
1735 if (bounds)
1736 STORE_NATIVE_RECT (*bounds,
1737 FRAME_COL_TO_PIXEL_X (f, pix_x),
1738 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1739 FRAME_COLUMN_WIDTH (f) - 1,
1740 FRAME_LINE_HEIGHT (f) - 1);
1741
1742 if (!noclip)
1743 {
1744 if (pix_x < 0)
1745 pix_x = 0;
1746 else if (pix_x > FRAME_TOTAL_COLS (f))
1747 pix_x = FRAME_TOTAL_COLS (f);
1748
1749 if (pix_y < 0)
1750 pix_y = 0;
1751 else if (pix_y > FRAME_LINES (f))
1752 pix_y = FRAME_LINES (f);
1753 }
1754 }
1755 #endif
1756
1757 *x = pix_x;
1758 *y = pix_y;
1759 }
1760
1761
1762 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1763 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1764 can't tell the positions because W's display is not up to date,
1765 return 0. */
1766
1767 int
1768 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1769 struct window *w;
1770 int hpos, vpos;
1771 int *frame_x, *frame_y;
1772 {
1773 #ifdef HAVE_WINDOW_SYSTEM
1774 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1775 {
1776 int success_p;
1777
1778 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1779 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1780
1781 if (display_completed)
1782 {
1783 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1784 struct glyph *glyph = row->glyphs[TEXT_AREA];
1785 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1786
1787 hpos = row->x;
1788 vpos = row->y;
1789 while (glyph < end)
1790 {
1791 hpos += glyph->pixel_width;
1792 ++glyph;
1793 }
1794
1795 /* If first glyph is partially visible, its first visible position is still 0. */
1796 if (hpos < 0)
1797 hpos = 0;
1798
1799 success_p = 1;
1800 }
1801 else
1802 {
1803 hpos = vpos = 0;
1804 success_p = 0;
1805 }
1806
1807 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1808 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1809 return success_p;
1810 }
1811 #endif
1812
1813 *frame_x = hpos;
1814 *frame_y = vpos;
1815 return 1;
1816 }
1817
1818
1819 #ifdef HAVE_WINDOW_SYSTEM
1820
1821 /* Find the glyph under window-relative coordinates X/Y in window W.
1822 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1823 strings. Return in *HPOS and *VPOS the row and column number of
1824 the glyph found. Return in *AREA the glyph area containing X.
1825 Value is a pointer to the glyph found or null if X/Y is not on
1826 text, or we can't tell because W's current matrix is not up to
1827 date. */
1828
1829 static
1830 struct glyph *
1831 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1832 struct window *w;
1833 int x, y;
1834 int *hpos, *vpos, *dx, *dy, *area;
1835 {
1836 struct glyph *glyph, *end;
1837 struct glyph_row *row = NULL;
1838 int x0, i;
1839
1840 /* Find row containing Y. Give up if some row is not enabled. */
1841 for (i = 0; i < w->current_matrix->nrows; ++i)
1842 {
1843 row = MATRIX_ROW (w->current_matrix, i);
1844 if (!row->enabled_p)
1845 return NULL;
1846 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1847 break;
1848 }
1849
1850 *vpos = i;
1851 *hpos = 0;
1852
1853 /* Give up if Y is not in the window. */
1854 if (i == w->current_matrix->nrows)
1855 return NULL;
1856
1857 /* Get the glyph area containing X. */
1858 if (w->pseudo_window_p)
1859 {
1860 *area = TEXT_AREA;
1861 x0 = 0;
1862 }
1863 else
1864 {
1865 if (x < window_box_left_offset (w, TEXT_AREA))
1866 {
1867 *area = LEFT_MARGIN_AREA;
1868 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1869 }
1870 else if (x < window_box_right_offset (w, TEXT_AREA))
1871 {
1872 *area = TEXT_AREA;
1873 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1874 }
1875 else
1876 {
1877 *area = RIGHT_MARGIN_AREA;
1878 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1879 }
1880 }
1881
1882 /* Find glyph containing X. */
1883 glyph = row->glyphs[*area];
1884 end = glyph + row->used[*area];
1885 x -= x0;
1886 while (glyph < end && x >= glyph->pixel_width)
1887 {
1888 x -= glyph->pixel_width;
1889 ++glyph;
1890 }
1891
1892 if (glyph == end)
1893 return NULL;
1894
1895 if (dx)
1896 {
1897 *dx = x;
1898 *dy = y - (row->y + row->ascent - glyph->ascent);
1899 }
1900
1901 *hpos = glyph - row->glyphs[*area];
1902 return glyph;
1903 }
1904
1905
1906 /* EXPORT:
1907 Convert frame-relative x/y to coordinates relative to window W.
1908 Takes pseudo-windows into account. */
1909
1910 void
1911 frame_to_window_pixel_xy (w, x, y)
1912 struct window *w;
1913 int *x, *y;
1914 {
1915 if (w->pseudo_window_p)
1916 {
1917 /* A pseudo-window is always full-width, and starts at the
1918 left edge of the frame, plus a frame border. */
1919 struct frame *f = XFRAME (w->frame);
1920 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1921 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1922 }
1923 else
1924 {
1925 *x -= WINDOW_LEFT_EDGE_X (w);
1926 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1927 }
1928 }
1929
1930 /* EXPORT:
1931 Return in RECTS[] at most N clipping rectangles for glyph string S.
1932 Return the number of stored rectangles. */
1933
1934 int
1935 get_glyph_string_clip_rects (s, rects, n)
1936 struct glyph_string *s;
1937 NativeRectangle *rects;
1938 int n;
1939 {
1940 XRectangle r;
1941
1942 if (n <= 0)
1943 return 0;
1944
1945 if (s->row->full_width_p)
1946 {
1947 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1948 r.x = WINDOW_LEFT_EDGE_X (s->w);
1949 r.width = WINDOW_TOTAL_WIDTH (s->w);
1950
1951 /* Unless displaying a mode or menu bar line, which are always
1952 fully visible, clip to the visible part of the row. */
1953 if (s->w->pseudo_window_p)
1954 r.height = s->row->visible_height;
1955 else
1956 r.height = s->height;
1957 }
1958 else
1959 {
1960 /* This is a text line that may be partially visible. */
1961 r.x = window_box_left (s->w, s->area);
1962 r.width = window_box_width (s->w, s->area);
1963 r.height = s->row->visible_height;
1964 }
1965
1966 if (s->clip_head)
1967 if (r.x < s->clip_head->x)
1968 {
1969 if (r.width >= s->clip_head->x - r.x)
1970 r.width -= s->clip_head->x - r.x;
1971 else
1972 r.width = 0;
1973 r.x = s->clip_head->x;
1974 }
1975 if (s->clip_tail)
1976 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1977 {
1978 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1979 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1980 else
1981 r.width = 0;
1982 }
1983
1984 /* If S draws overlapping rows, it's sufficient to use the top and
1985 bottom of the window for clipping because this glyph string
1986 intentionally draws over other lines. */
1987 if (s->for_overlaps)
1988 {
1989 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1990 r.height = window_text_bottom_y (s->w) - r.y;
1991
1992 /* Alas, the above simple strategy does not work for the
1993 environments with anti-aliased text: if the same text is
1994 drawn onto the same place multiple times, it gets thicker.
1995 If the overlap we are processing is for the erased cursor, we
1996 take the intersection with the rectagle of the cursor. */
1997 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1998 {
1999 XRectangle rc, r_save = r;
2000
2001 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2002 rc.y = s->w->phys_cursor.y;
2003 rc.width = s->w->phys_cursor_width;
2004 rc.height = s->w->phys_cursor_height;
2005
2006 x_intersect_rectangles (&r_save, &rc, &r);
2007 }
2008 }
2009 else
2010 {
2011 /* Don't use S->y for clipping because it doesn't take partially
2012 visible lines into account. For example, it can be negative for
2013 partially visible lines at the top of a window. */
2014 if (!s->row->full_width_p
2015 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2016 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2017 else
2018 r.y = max (0, s->row->y);
2019 }
2020
2021 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2022
2023 /* If drawing the cursor, don't let glyph draw outside its
2024 advertised boundaries. Cleartype does this under some circumstances. */
2025 if (s->hl == DRAW_CURSOR)
2026 {
2027 struct glyph *glyph = s->first_glyph;
2028 int height, max_y;
2029
2030 if (s->x > r.x)
2031 {
2032 r.width -= s->x - r.x;
2033 r.x = s->x;
2034 }
2035 r.width = min (r.width, glyph->pixel_width);
2036
2037 /* If r.y is below window bottom, ensure that we still see a cursor. */
2038 height = min (glyph->ascent + glyph->descent,
2039 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2040 max_y = window_text_bottom_y (s->w) - height;
2041 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2042 if (s->ybase - glyph->ascent > max_y)
2043 {
2044 r.y = max_y;
2045 r.height = height;
2046 }
2047 else
2048 {
2049 /* Don't draw cursor glyph taller than our actual glyph. */
2050 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2051 if (height < r.height)
2052 {
2053 max_y = r.y + r.height;
2054 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2055 r.height = min (max_y - r.y, height);
2056 }
2057 }
2058 }
2059
2060 if (s->row->clip)
2061 {
2062 XRectangle r_save = r;
2063
2064 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2065 r.width = 0;
2066 }
2067
2068 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2069 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2070 {
2071 #ifdef CONVERT_FROM_XRECT
2072 CONVERT_FROM_XRECT (r, *rects);
2073 #else
2074 *rects = r;
2075 #endif
2076 return 1;
2077 }
2078 else
2079 {
2080 /* If we are processing overlapping and allowed to return
2081 multiple clipping rectangles, we exclude the row of the glyph
2082 string from the clipping rectangle. This is to avoid drawing
2083 the same text on the environment with anti-aliasing. */
2084 #ifdef CONVERT_FROM_XRECT
2085 XRectangle rs[2];
2086 #else
2087 XRectangle *rs = rects;
2088 #endif
2089 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2090
2091 if (s->for_overlaps & OVERLAPS_PRED)
2092 {
2093 rs[i] = r;
2094 if (r.y + r.height > row_y)
2095 {
2096 if (r.y < row_y)
2097 rs[i].height = row_y - r.y;
2098 else
2099 rs[i].height = 0;
2100 }
2101 i++;
2102 }
2103 if (s->for_overlaps & OVERLAPS_SUCC)
2104 {
2105 rs[i] = r;
2106 if (r.y < row_y + s->row->visible_height)
2107 {
2108 if (r.y + r.height > row_y + s->row->visible_height)
2109 {
2110 rs[i].y = row_y + s->row->visible_height;
2111 rs[i].height = r.y + r.height - rs[i].y;
2112 }
2113 else
2114 rs[i].height = 0;
2115 }
2116 i++;
2117 }
2118
2119 n = i;
2120 #ifdef CONVERT_FROM_XRECT
2121 for (i = 0; i < n; i++)
2122 CONVERT_FROM_XRECT (rs[i], rects[i]);
2123 #endif
2124 return n;
2125 }
2126 }
2127
2128 /* EXPORT:
2129 Return in *NR the clipping rectangle for glyph string S. */
2130
2131 void
2132 get_glyph_string_clip_rect (s, nr)
2133 struct glyph_string *s;
2134 NativeRectangle *nr;
2135 {
2136 get_glyph_string_clip_rects (s, nr, 1);
2137 }
2138
2139
2140 /* EXPORT:
2141 Return the position and height of the phys cursor in window W.
2142 Set w->phys_cursor_width to width of phys cursor.
2143 */
2144
2145 void
2146 get_phys_cursor_geometry (w, row, glyph, xp, yp, heightp)
2147 struct window *w;
2148 struct glyph_row *row;
2149 struct glyph *glyph;
2150 int *xp, *yp, *heightp;
2151 {
2152 struct frame *f = XFRAME (WINDOW_FRAME (w));
2153 int x, y, wd, h, h0, y0;
2154
2155 /* Compute the width of the rectangle to draw. If on a stretch
2156 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2157 rectangle as wide as the glyph, but use a canonical character
2158 width instead. */
2159 wd = glyph->pixel_width - 1;
2160 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2161 wd++; /* Why? */
2162 #endif
2163
2164 x = w->phys_cursor.x;
2165 if (x < 0)
2166 {
2167 wd += x;
2168 x = 0;
2169 }
2170
2171 if (glyph->type == STRETCH_GLYPH
2172 && !x_stretch_cursor_p)
2173 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2174 w->phys_cursor_width = wd;
2175
2176 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2177
2178 /* If y is below window bottom, ensure that we still see a cursor. */
2179 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2180
2181 h = max (h0, glyph->ascent + glyph->descent);
2182 h0 = min (h0, glyph->ascent + glyph->descent);
2183
2184 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2185 if (y < y0)
2186 {
2187 h = max (h - (y0 - y) + 1, h0);
2188 y = y0 - 1;
2189 }
2190 else
2191 {
2192 y0 = window_text_bottom_y (w) - h0;
2193 if (y > y0)
2194 {
2195 h += y - y0;
2196 y = y0;
2197 }
2198 }
2199
2200 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2201 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2202 *heightp = h;
2203 }
2204
2205 /*
2206 * Remember which glyph the mouse is over.
2207 */
2208
2209 void
2210 remember_mouse_glyph (f, gx, gy, rect)
2211 struct frame *f;
2212 int gx, gy;
2213 NativeRectangle *rect;
2214 {
2215 Lisp_Object window;
2216 struct window *w;
2217 struct glyph_row *r, *gr, *end_row;
2218 enum window_part part;
2219 enum glyph_row_area area;
2220 int x, y, width, height;
2221
2222 /* Try to determine frame pixel position and size of the glyph under
2223 frame pixel coordinates X/Y on frame F. */
2224
2225 if (!f->glyphs_initialized_p
2226 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2227 NILP (window)))
2228 {
2229 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2230 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2231 goto virtual_glyph;
2232 }
2233
2234 w = XWINDOW (window);
2235 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2236 height = WINDOW_FRAME_LINE_HEIGHT (w);
2237
2238 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2239 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2240
2241 if (w->pseudo_window_p)
2242 {
2243 area = TEXT_AREA;
2244 part = ON_MODE_LINE; /* Don't adjust margin. */
2245 goto text_glyph;
2246 }
2247
2248 switch (part)
2249 {
2250 case ON_LEFT_MARGIN:
2251 area = LEFT_MARGIN_AREA;
2252 goto text_glyph;
2253
2254 case ON_RIGHT_MARGIN:
2255 area = RIGHT_MARGIN_AREA;
2256 goto text_glyph;
2257
2258 case ON_HEADER_LINE:
2259 case ON_MODE_LINE:
2260 gr = (part == ON_HEADER_LINE
2261 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2262 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2263 gy = gr->y;
2264 area = TEXT_AREA;
2265 goto text_glyph_row_found;
2266
2267 case ON_TEXT:
2268 area = TEXT_AREA;
2269
2270 text_glyph:
2271 gr = 0; gy = 0;
2272 for (; r <= end_row && r->enabled_p; ++r)
2273 if (r->y + r->height > y)
2274 {
2275 gr = r; gy = r->y;
2276 break;
2277 }
2278
2279 text_glyph_row_found:
2280 if (gr && gy <= y)
2281 {
2282 struct glyph *g = gr->glyphs[area];
2283 struct glyph *end = g + gr->used[area];
2284
2285 height = gr->height;
2286 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2287 if (gx + g->pixel_width > x)
2288 break;
2289
2290 if (g < end)
2291 {
2292 if (g->type == IMAGE_GLYPH)
2293 {
2294 /* Don't remember when mouse is over image, as
2295 image may have hot-spots. */
2296 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2297 return;
2298 }
2299 width = g->pixel_width;
2300 }
2301 else
2302 {
2303 /* Use nominal char spacing at end of line. */
2304 x -= gx;
2305 gx += (x / width) * width;
2306 }
2307
2308 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2309 gx += window_box_left_offset (w, area);
2310 }
2311 else
2312 {
2313 /* Use nominal line height at end of window. */
2314 gx = (x / width) * width;
2315 y -= gy;
2316 gy += (y / height) * height;
2317 }
2318 break;
2319
2320 case ON_LEFT_FRINGE:
2321 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2322 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2323 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2324 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2325 goto row_glyph;
2326
2327 case ON_RIGHT_FRINGE:
2328 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2329 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2330 : window_box_right_offset (w, TEXT_AREA));
2331 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2332 goto row_glyph;
2333
2334 case ON_SCROLL_BAR:
2335 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2336 ? 0
2337 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2338 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2339 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2340 : 0)));
2341 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2342
2343 row_glyph:
2344 gr = 0, gy = 0;
2345 for (; r <= end_row && r->enabled_p; ++r)
2346 if (r->y + r->height > y)
2347 {
2348 gr = r; gy = r->y;
2349 break;
2350 }
2351
2352 if (gr && gy <= y)
2353 height = gr->height;
2354 else
2355 {
2356 /* Use nominal line height at end of window. */
2357 y -= gy;
2358 gy += (y / height) * height;
2359 }
2360 break;
2361
2362 default:
2363 ;
2364 virtual_glyph:
2365 /* If there is no glyph under the mouse, then we divide the screen
2366 into a grid of the smallest glyph in the frame, and use that
2367 as our "glyph". */
2368
2369 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2370 round down even for negative values. */
2371 if (gx < 0)
2372 gx -= width - 1;
2373 if (gy < 0)
2374 gy -= height - 1;
2375
2376 gx = (gx / width) * width;
2377 gy = (gy / height) * height;
2378
2379 goto store_rect;
2380 }
2381
2382 gx += WINDOW_LEFT_EDGE_X (w);
2383 gy += WINDOW_TOP_EDGE_Y (w);
2384
2385 store_rect:
2386 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2387
2388 /* Visible feedback for debugging. */
2389 #if 0
2390 #if HAVE_X_WINDOWS
2391 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2392 f->output_data.x->normal_gc,
2393 gx, gy, width, height);
2394 #endif
2395 #endif
2396 }
2397
2398
2399 #endif /* HAVE_WINDOW_SYSTEM */
2400
2401 \f
2402 /***********************************************************************
2403 Lisp form evaluation
2404 ***********************************************************************/
2405
2406 /* Error handler for safe_eval and safe_call. */
2407
2408 static Lisp_Object
2409 safe_eval_handler (arg)
2410 Lisp_Object arg;
2411 {
2412 add_to_log ("Error during redisplay: %s", arg, Qnil);
2413 return Qnil;
2414 }
2415
2416
2417 /* Evaluate SEXPR and return the result, or nil if something went
2418 wrong. Prevent redisplay during the evaluation. */
2419
2420 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2421 Return the result, or nil if something went wrong. Prevent
2422 redisplay during the evaluation. */
2423
2424 Lisp_Object
2425 safe_call (nargs, args)
2426 int nargs;
2427 Lisp_Object *args;
2428 {
2429 Lisp_Object val;
2430
2431 if (inhibit_eval_during_redisplay)
2432 val = Qnil;
2433 else
2434 {
2435 int count = SPECPDL_INDEX ();
2436 struct gcpro gcpro1;
2437
2438 GCPRO1 (args[0]);
2439 gcpro1.nvars = nargs;
2440 specbind (Qinhibit_redisplay, Qt);
2441 /* Use Qt to ensure debugger does not run,
2442 so there is no possibility of wanting to redisplay. */
2443 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2444 safe_eval_handler);
2445 UNGCPRO;
2446 val = unbind_to (count, val);
2447 }
2448
2449 return val;
2450 }
2451
2452
2453 /* Call function FN with one argument ARG.
2454 Return the result, or nil if something went wrong. */
2455
2456 Lisp_Object
2457 safe_call1 (fn, arg)
2458 Lisp_Object fn, arg;
2459 {
2460 Lisp_Object args[2];
2461 args[0] = fn;
2462 args[1] = arg;
2463 return safe_call (2, args);
2464 }
2465
2466 static Lisp_Object Qeval;
2467
2468 Lisp_Object
2469 safe_eval (Lisp_Object sexpr)
2470 {
2471 return safe_call1 (Qeval, sexpr);
2472 }
2473
2474 /* Call function FN with one argument ARG.
2475 Return the result, or nil if something went wrong. */
2476
2477 Lisp_Object
2478 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2479 {
2480 Lisp_Object args[3];
2481 args[0] = fn;
2482 args[1] = arg1;
2483 args[2] = arg2;
2484 return safe_call (3, args);
2485 }
2486
2487
2488 \f
2489 /***********************************************************************
2490 Debugging
2491 ***********************************************************************/
2492
2493 #if 0
2494
2495 /* Define CHECK_IT to perform sanity checks on iterators.
2496 This is for debugging. It is too slow to do unconditionally. */
2497
2498 static void
2499 check_it (it)
2500 struct it *it;
2501 {
2502 if (it->method == GET_FROM_STRING)
2503 {
2504 xassert (STRINGP (it->string));
2505 xassert (IT_STRING_CHARPOS (*it) >= 0);
2506 }
2507 else
2508 {
2509 xassert (IT_STRING_CHARPOS (*it) < 0);
2510 if (it->method == GET_FROM_BUFFER)
2511 {
2512 /* Check that character and byte positions agree. */
2513 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2514 }
2515 }
2516
2517 if (it->dpvec)
2518 xassert (it->current.dpvec_index >= 0);
2519 else
2520 xassert (it->current.dpvec_index < 0);
2521 }
2522
2523 #define CHECK_IT(IT) check_it ((IT))
2524
2525 #else /* not 0 */
2526
2527 #define CHECK_IT(IT) (void) 0
2528
2529 #endif /* not 0 */
2530
2531
2532 #if GLYPH_DEBUG
2533
2534 /* Check that the window end of window W is what we expect it
2535 to be---the last row in the current matrix displaying text. */
2536
2537 static void
2538 check_window_end (w)
2539 struct window *w;
2540 {
2541 if (!MINI_WINDOW_P (w)
2542 && !NILP (w->window_end_valid))
2543 {
2544 struct glyph_row *row;
2545 xassert ((row = MATRIX_ROW (w->current_matrix,
2546 XFASTINT (w->window_end_vpos)),
2547 !row->enabled_p
2548 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2549 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2550 }
2551 }
2552
2553 #define CHECK_WINDOW_END(W) check_window_end ((W))
2554
2555 #else /* not GLYPH_DEBUG */
2556
2557 #define CHECK_WINDOW_END(W) (void) 0
2558
2559 #endif /* not GLYPH_DEBUG */
2560
2561
2562 \f
2563 /***********************************************************************
2564 Iterator initialization
2565 ***********************************************************************/
2566
2567 /* Initialize IT for displaying current_buffer in window W, starting
2568 at character position CHARPOS. CHARPOS < 0 means that no buffer
2569 position is specified which is useful when the iterator is assigned
2570 a position later. BYTEPOS is the byte position corresponding to
2571 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2572
2573 If ROW is not null, calls to produce_glyphs with IT as parameter
2574 will produce glyphs in that row.
2575
2576 BASE_FACE_ID is the id of a base face to use. It must be one of
2577 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2578 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2579 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2580
2581 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2582 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2583 will be initialized to use the corresponding mode line glyph row of
2584 the desired matrix of W. */
2585
2586 void
2587 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2588 struct it *it;
2589 struct window *w;
2590 int charpos, bytepos;
2591 struct glyph_row *row;
2592 enum face_id base_face_id;
2593 {
2594 int highlight_region_p;
2595 enum face_id remapped_base_face_id = base_face_id;
2596
2597 /* Some precondition checks. */
2598 xassert (w != NULL && it != NULL);
2599 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2600 && charpos <= ZV));
2601
2602 /* If face attributes have been changed since the last redisplay,
2603 free realized faces now because they depend on face definitions
2604 that might have changed. Don't free faces while there might be
2605 desired matrices pending which reference these faces. */
2606 if (face_change_count && !inhibit_free_realized_faces)
2607 {
2608 face_change_count = 0;
2609 free_all_realized_faces (Qnil);
2610 }
2611
2612 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2613 if (! NILP (Vface_remapping_alist))
2614 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2615
2616 /* Use one of the mode line rows of W's desired matrix if
2617 appropriate. */
2618 if (row == NULL)
2619 {
2620 if (base_face_id == MODE_LINE_FACE_ID
2621 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2622 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2623 else if (base_face_id == HEADER_LINE_FACE_ID)
2624 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2625 }
2626
2627 /* Clear IT. */
2628 bzero (it, sizeof *it);
2629 it->current.overlay_string_index = -1;
2630 it->current.dpvec_index = -1;
2631 it->base_face_id = remapped_base_face_id;
2632 it->string = Qnil;
2633 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2634
2635 /* The window in which we iterate over current_buffer: */
2636 XSETWINDOW (it->window, w);
2637 it->w = w;
2638 it->f = XFRAME (w->frame);
2639
2640 it->cmp_it.id = -1;
2641
2642 /* Extra space between lines (on window systems only). */
2643 if (base_face_id == DEFAULT_FACE_ID
2644 && FRAME_WINDOW_P (it->f))
2645 {
2646 if (NATNUMP (current_buffer->extra_line_spacing))
2647 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2648 else if (FLOATP (current_buffer->extra_line_spacing))
2649 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2650 * FRAME_LINE_HEIGHT (it->f));
2651 else if (it->f->extra_line_spacing > 0)
2652 it->extra_line_spacing = it->f->extra_line_spacing;
2653 it->max_extra_line_spacing = 0;
2654 }
2655
2656 /* If realized faces have been removed, e.g. because of face
2657 attribute changes of named faces, recompute them. When running
2658 in batch mode, the face cache of the initial frame is null. If
2659 we happen to get called, make a dummy face cache. */
2660 if (FRAME_FACE_CACHE (it->f) == NULL)
2661 init_frame_faces (it->f);
2662 if (FRAME_FACE_CACHE (it->f)->used == 0)
2663 recompute_basic_faces (it->f);
2664
2665 /* Current value of the `slice', `space-width', and 'height' properties. */
2666 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2667 it->space_width = Qnil;
2668 it->font_height = Qnil;
2669 it->override_ascent = -1;
2670
2671 /* Are control characters displayed as `^C'? */
2672 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2673
2674 /* -1 means everything between a CR and the following line end
2675 is invisible. >0 means lines indented more than this value are
2676 invisible. */
2677 it->selective = (INTEGERP (current_buffer->selective_display)
2678 ? XFASTINT (current_buffer->selective_display)
2679 : (!NILP (current_buffer->selective_display)
2680 ? -1 : 0));
2681 it->selective_display_ellipsis_p
2682 = !NILP (current_buffer->selective_display_ellipses);
2683
2684 /* Display table to use. */
2685 it->dp = window_display_table (w);
2686
2687 /* Are multibyte characters enabled in current_buffer? */
2688 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2689
2690 /* Do we need to reorder bidirectional text? */
2691 it->bidi_p = !NILP (current_buffer->bidi_display_reordering);
2692
2693 /* Non-zero if we should highlight the region. */
2694 highlight_region_p
2695 = (!NILP (Vtransient_mark_mode)
2696 && !NILP (current_buffer->mark_active)
2697 && XMARKER (current_buffer->mark)->buffer != 0);
2698
2699 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2700 start and end of a visible region in window IT->w. Set both to
2701 -1 to indicate no region. */
2702 if (highlight_region_p
2703 /* Maybe highlight only in selected window. */
2704 && (/* Either show region everywhere. */
2705 highlight_nonselected_windows
2706 /* Or show region in the selected window. */
2707 || w == XWINDOW (selected_window)
2708 /* Or show the region if we are in the mini-buffer and W is
2709 the window the mini-buffer refers to. */
2710 || (MINI_WINDOW_P (XWINDOW (selected_window))
2711 && WINDOWP (minibuf_selected_window)
2712 && w == XWINDOW (minibuf_selected_window))))
2713 {
2714 int charpos = marker_position (current_buffer->mark);
2715 it->region_beg_charpos = min (PT, charpos);
2716 it->region_end_charpos = max (PT, charpos);
2717 }
2718 else
2719 it->region_beg_charpos = it->region_end_charpos = -1;
2720
2721 /* Get the position at which the redisplay_end_trigger hook should
2722 be run, if it is to be run at all. */
2723 if (MARKERP (w->redisplay_end_trigger)
2724 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2725 it->redisplay_end_trigger_charpos
2726 = marker_position (w->redisplay_end_trigger);
2727 else if (INTEGERP (w->redisplay_end_trigger))
2728 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2729
2730 /* Correct bogus values of tab_width. */
2731 it->tab_width = XINT (current_buffer->tab_width);
2732 if (it->tab_width <= 0 || it->tab_width > 1000)
2733 it->tab_width = 8;
2734
2735 /* Are lines in the display truncated? */
2736 if (base_face_id != DEFAULT_FACE_ID
2737 || XINT (it->w->hscroll)
2738 || (! WINDOW_FULL_WIDTH_P (it->w)
2739 && ((!NILP (Vtruncate_partial_width_windows)
2740 && !INTEGERP (Vtruncate_partial_width_windows))
2741 || (INTEGERP (Vtruncate_partial_width_windows)
2742 && (WINDOW_TOTAL_COLS (it->w)
2743 < XINT (Vtruncate_partial_width_windows))))))
2744 it->line_wrap = TRUNCATE;
2745 else if (NILP (current_buffer->truncate_lines))
2746 it->line_wrap = NILP (current_buffer->word_wrap)
2747 ? WINDOW_WRAP : WORD_WRAP;
2748 else
2749 it->line_wrap = TRUNCATE;
2750
2751 /* Get dimensions of truncation and continuation glyphs. These are
2752 displayed as fringe bitmaps under X, so we don't need them for such
2753 frames. */
2754 if (!FRAME_WINDOW_P (it->f))
2755 {
2756 if (it->line_wrap == TRUNCATE)
2757 {
2758 /* We will need the truncation glyph. */
2759 xassert (it->glyph_row == NULL);
2760 produce_special_glyphs (it, IT_TRUNCATION);
2761 it->truncation_pixel_width = it->pixel_width;
2762 }
2763 else
2764 {
2765 /* We will need the continuation glyph. */
2766 xassert (it->glyph_row == NULL);
2767 produce_special_glyphs (it, IT_CONTINUATION);
2768 it->continuation_pixel_width = it->pixel_width;
2769 }
2770
2771 /* Reset these values to zero because the produce_special_glyphs
2772 above has changed them. */
2773 it->pixel_width = it->ascent = it->descent = 0;
2774 it->phys_ascent = it->phys_descent = 0;
2775 }
2776
2777 /* Set this after getting the dimensions of truncation and
2778 continuation glyphs, so that we don't produce glyphs when calling
2779 produce_special_glyphs, above. */
2780 it->glyph_row = row;
2781 it->area = TEXT_AREA;
2782
2783 /* Forget any previous info about this row being reversed. */
2784 if (it->glyph_row)
2785 it->glyph_row->reversed_p = 0;
2786
2787 /* Get the dimensions of the display area. The display area
2788 consists of the visible window area plus a horizontally scrolled
2789 part to the left of the window. All x-values are relative to the
2790 start of this total display area. */
2791 if (base_face_id != DEFAULT_FACE_ID)
2792 {
2793 /* Mode lines, menu bar in terminal frames. */
2794 it->first_visible_x = 0;
2795 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2796 }
2797 else
2798 {
2799 it->first_visible_x
2800 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2801 it->last_visible_x = (it->first_visible_x
2802 + window_box_width (w, TEXT_AREA));
2803
2804 /* If we truncate lines, leave room for the truncator glyph(s) at
2805 the right margin. Otherwise, leave room for the continuation
2806 glyph(s). Truncation and continuation glyphs are not inserted
2807 for window-based redisplay. */
2808 if (!FRAME_WINDOW_P (it->f))
2809 {
2810 if (it->line_wrap == TRUNCATE)
2811 it->last_visible_x -= it->truncation_pixel_width;
2812 else
2813 it->last_visible_x -= it->continuation_pixel_width;
2814 }
2815
2816 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2817 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2818 }
2819
2820 /* Leave room for a border glyph. */
2821 if (!FRAME_WINDOW_P (it->f)
2822 && !WINDOW_RIGHTMOST_P (it->w))
2823 it->last_visible_x -= 1;
2824
2825 it->last_visible_y = window_text_bottom_y (w);
2826
2827 /* For mode lines and alike, arrange for the first glyph having a
2828 left box line if the face specifies a box. */
2829 if (base_face_id != DEFAULT_FACE_ID)
2830 {
2831 struct face *face;
2832
2833 it->face_id = remapped_base_face_id;
2834
2835 /* If we have a boxed mode line, make the first character appear
2836 with a left box line. */
2837 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2838 if (face->box != FACE_NO_BOX)
2839 it->start_of_box_run_p = 1;
2840 }
2841
2842 /* If we are to reorder bidirectional text, init the bidi
2843 iterator. */
2844 if (it->bidi_p)
2845 {
2846 /* Note the paragraph direction that this buffer wants to
2847 use. */
2848 if (EQ (current_buffer->bidi_paragraph_direction, Qleft_to_right))
2849 it->paragraph_embedding = L2R;
2850 else if (EQ (current_buffer->bidi_paragraph_direction, Qright_to_left))
2851 it->paragraph_embedding = R2L;
2852 else
2853 it->paragraph_embedding = NEUTRAL_DIR;
2854 bidi_init_it (charpos, bytepos, &it->bidi_it);
2855 }
2856
2857 /* If a buffer position was specified, set the iterator there,
2858 getting overlays and face properties from that position. */
2859 if (charpos >= BUF_BEG (current_buffer))
2860 {
2861 it->end_charpos = ZV;
2862 it->face_id = -1;
2863 IT_CHARPOS (*it) = charpos;
2864
2865 /* Compute byte position if not specified. */
2866 if (bytepos < charpos)
2867 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2868 else
2869 IT_BYTEPOS (*it) = bytepos;
2870
2871 it->start = it->current;
2872
2873 /* Compute faces etc. */
2874 reseat (it, it->current.pos, 1);
2875 }
2876
2877 CHECK_IT (it);
2878 }
2879
2880
2881 /* Initialize IT for the display of window W with window start POS. */
2882
2883 void
2884 start_display (it, w, pos)
2885 struct it *it;
2886 struct window *w;
2887 struct text_pos pos;
2888 {
2889 struct glyph_row *row;
2890 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2891
2892 row = w->desired_matrix->rows + first_vpos;
2893 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2894 it->first_vpos = first_vpos;
2895
2896 /* Don't reseat to previous visible line start if current start
2897 position is in a string or image. */
2898 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2899 {
2900 int start_at_line_beg_p;
2901 int first_y = it->current_y;
2902
2903 /* If window start is not at a line start, skip forward to POS to
2904 get the correct continuation lines width. */
2905 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2906 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2907 if (!start_at_line_beg_p)
2908 {
2909 int new_x;
2910
2911 reseat_at_previous_visible_line_start (it);
2912 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2913
2914 new_x = it->current_x + it->pixel_width;
2915
2916 /* If lines are continued, this line may end in the middle
2917 of a multi-glyph character (e.g. a control character
2918 displayed as \003, or in the middle of an overlay
2919 string). In this case move_it_to above will not have
2920 taken us to the start of the continuation line but to the
2921 end of the continued line. */
2922 if (it->current_x > 0
2923 && it->line_wrap != TRUNCATE /* Lines are continued. */
2924 && (/* And glyph doesn't fit on the line. */
2925 new_x > it->last_visible_x
2926 /* Or it fits exactly and we're on a window
2927 system frame. */
2928 || (new_x == it->last_visible_x
2929 && FRAME_WINDOW_P (it->f))))
2930 {
2931 if (it->current.dpvec_index >= 0
2932 || it->current.overlay_string_index >= 0)
2933 {
2934 set_iterator_to_next (it, 1);
2935 move_it_in_display_line_to (it, -1, -1, 0);
2936 }
2937
2938 it->continuation_lines_width += it->current_x;
2939 }
2940
2941 /* We're starting a new display line, not affected by the
2942 height of the continued line, so clear the appropriate
2943 fields in the iterator structure. */
2944 it->max_ascent = it->max_descent = 0;
2945 it->max_phys_ascent = it->max_phys_descent = 0;
2946
2947 it->current_y = first_y;
2948 it->vpos = 0;
2949 it->current_x = it->hpos = 0;
2950 }
2951 }
2952 }
2953
2954
2955 /* Return 1 if POS is a position in ellipses displayed for invisible
2956 text. W is the window we display, for text property lookup. */
2957
2958 static int
2959 in_ellipses_for_invisible_text_p (pos, w)
2960 struct display_pos *pos;
2961 struct window *w;
2962 {
2963 Lisp_Object prop, window;
2964 int ellipses_p = 0;
2965 int charpos = CHARPOS (pos->pos);
2966
2967 /* If POS specifies a position in a display vector, this might
2968 be for an ellipsis displayed for invisible text. We won't
2969 get the iterator set up for delivering that ellipsis unless
2970 we make sure that it gets aware of the invisible text. */
2971 if (pos->dpvec_index >= 0
2972 && pos->overlay_string_index < 0
2973 && CHARPOS (pos->string_pos) < 0
2974 && charpos > BEGV
2975 && (XSETWINDOW (window, w),
2976 prop = Fget_char_property (make_number (charpos),
2977 Qinvisible, window),
2978 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2979 {
2980 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2981 window);
2982 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2983 }
2984
2985 return ellipses_p;
2986 }
2987
2988
2989 /* Initialize IT for stepping through current_buffer in window W,
2990 starting at position POS that includes overlay string and display
2991 vector/ control character translation position information. Value
2992 is zero if there are overlay strings with newlines at POS. */
2993
2994 static int
2995 init_from_display_pos (it, w, pos)
2996 struct it *it;
2997 struct window *w;
2998 struct display_pos *pos;
2999 {
3000 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3001 int i, overlay_strings_with_newlines = 0;
3002
3003 /* If POS specifies a position in a display vector, this might
3004 be for an ellipsis displayed for invisible text. We won't
3005 get the iterator set up for delivering that ellipsis unless
3006 we make sure that it gets aware of the invisible text. */
3007 if (in_ellipses_for_invisible_text_p (pos, w))
3008 {
3009 --charpos;
3010 bytepos = 0;
3011 }
3012
3013 /* Keep in mind: the call to reseat in init_iterator skips invisible
3014 text, so we might end up at a position different from POS. This
3015 is only a problem when POS is a row start after a newline and an
3016 overlay starts there with an after-string, and the overlay has an
3017 invisible property. Since we don't skip invisible text in
3018 display_line and elsewhere immediately after consuming the
3019 newline before the row start, such a POS will not be in a string,
3020 but the call to init_iterator below will move us to the
3021 after-string. */
3022 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3023
3024 /* This only scans the current chunk -- it should scan all chunks.
3025 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3026 to 16 in 22.1 to make this a lesser problem. */
3027 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3028 {
3029 const char *s = SDATA (it->overlay_strings[i]);
3030 const char *e = s + SBYTES (it->overlay_strings[i]);
3031
3032 while (s < e && *s != '\n')
3033 ++s;
3034
3035 if (s < e)
3036 {
3037 overlay_strings_with_newlines = 1;
3038 break;
3039 }
3040 }
3041
3042 /* If position is within an overlay string, set up IT to the right
3043 overlay string. */
3044 if (pos->overlay_string_index >= 0)
3045 {
3046 int relative_index;
3047
3048 /* If the first overlay string happens to have a `display'
3049 property for an image, the iterator will be set up for that
3050 image, and we have to undo that setup first before we can
3051 correct the overlay string index. */
3052 if (it->method == GET_FROM_IMAGE)
3053 pop_it (it);
3054
3055 /* We already have the first chunk of overlay strings in
3056 IT->overlay_strings. Load more until the one for
3057 pos->overlay_string_index is in IT->overlay_strings. */
3058 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3059 {
3060 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3061 it->current.overlay_string_index = 0;
3062 while (n--)
3063 {
3064 load_overlay_strings (it, 0);
3065 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3066 }
3067 }
3068
3069 it->current.overlay_string_index = pos->overlay_string_index;
3070 relative_index = (it->current.overlay_string_index
3071 % OVERLAY_STRING_CHUNK_SIZE);
3072 it->string = it->overlay_strings[relative_index];
3073 xassert (STRINGP (it->string));
3074 it->current.string_pos = pos->string_pos;
3075 it->method = GET_FROM_STRING;
3076 }
3077
3078 if (CHARPOS (pos->string_pos) >= 0)
3079 {
3080 /* Recorded position is not in an overlay string, but in another
3081 string. This can only be a string from a `display' property.
3082 IT should already be filled with that string. */
3083 it->current.string_pos = pos->string_pos;
3084 xassert (STRINGP (it->string));
3085 }
3086
3087 /* Restore position in display vector translations, control
3088 character translations or ellipses. */
3089 if (pos->dpvec_index >= 0)
3090 {
3091 if (it->dpvec == NULL)
3092 get_next_display_element (it);
3093 xassert (it->dpvec && it->current.dpvec_index == 0);
3094 it->current.dpvec_index = pos->dpvec_index;
3095 }
3096
3097 CHECK_IT (it);
3098 return !overlay_strings_with_newlines;
3099 }
3100
3101
3102 /* Initialize IT for stepping through current_buffer in window W
3103 starting at ROW->start. */
3104
3105 static void
3106 init_to_row_start (it, w, row)
3107 struct it *it;
3108 struct window *w;
3109 struct glyph_row *row;
3110 {
3111 init_from_display_pos (it, w, &row->start);
3112 it->start = row->start;
3113 it->continuation_lines_width = row->continuation_lines_width;
3114 CHECK_IT (it);
3115 }
3116
3117
3118 /* Initialize IT for stepping through current_buffer in window W
3119 starting in the line following ROW, i.e. starting at ROW->end.
3120 Value is zero if there are overlay strings with newlines at ROW's
3121 end position. */
3122
3123 static int
3124 init_to_row_end (it, w, row)
3125 struct it *it;
3126 struct window *w;
3127 struct glyph_row *row;
3128 {
3129 int success = 0;
3130
3131 if (init_from_display_pos (it, w, &row->end))
3132 {
3133 if (row->continued_p)
3134 it->continuation_lines_width
3135 = row->continuation_lines_width + row->pixel_width;
3136 CHECK_IT (it);
3137 success = 1;
3138 }
3139
3140 return success;
3141 }
3142
3143
3144
3145 \f
3146 /***********************************************************************
3147 Text properties
3148 ***********************************************************************/
3149
3150 /* Called when IT reaches IT->stop_charpos. Handle text property and
3151 overlay changes. Set IT->stop_charpos to the next position where
3152 to stop. */
3153
3154 static void
3155 handle_stop (it)
3156 struct it *it;
3157 {
3158 enum prop_handled handled;
3159 int handle_overlay_change_p;
3160 struct props *p;
3161
3162 it->dpvec = NULL;
3163 it->current.dpvec_index = -1;
3164 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3165 it->ignore_overlay_strings_at_pos_p = 0;
3166 it->ellipsis_p = 0;
3167
3168 /* Use face of preceding text for ellipsis (if invisible) */
3169 if (it->selective_display_ellipsis_p)
3170 it->saved_face_id = it->face_id;
3171
3172 do
3173 {
3174 handled = HANDLED_NORMALLY;
3175
3176 /* Call text property handlers. */
3177 for (p = it_props; p->handler; ++p)
3178 {
3179 handled = p->handler (it);
3180
3181 if (handled == HANDLED_RECOMPUTE_PROPS)
3182 break;
3183 else if (handled == HANDLED_RETURN)
3184 {
3185 /* We still want to show before and after strings from
3186 overlays even if the actual buffer text is replaced. */
3187 if (!handle_overlay_change_p
3188 || it->sp > 1
3189 || !get_overlay_strings_1 (it, 0, 0))
3190 {
3191 if (it->ellipsis_p)
3192 setup_for_ellipsis (it, 0);
3193 /* When handling a display spec, we might load an
3194 empty string. In that case, discard it here. We
3195 used to discard it in handle_single_display_spec,
3196 but that causes get_overlay_strings_1, above, to
3197 ignore overlay strings that we must check. */
3198 if (STRINGP (it->string) && !SCHARS (it->string))
3199 pop_it (it);
3200 return;
3201 }
3202 else if (STRINGP (it->string) && !SCHARS (it->string))
3203 pop_it (it);
3204 else
3205 {
3206 it->ignore_overlay_strings_at_pos_p = 1;
3207 it->string_from_display_prop_p = 0;
3208 handle_overlay_change_p = 0;
3209 }
3210 handled = HANDLED_RECOMPUTE_PROPS;
3211 break;
3212 }
3213 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3214 handle_overlay_change_p = 0;
3215 }
3216
3217 if (handled != HANDLED_RECOMPUTE_PROPS)
3218 {
3219 /* Don't check for overlay strings below when set to deliver
3220 characters from a display vector. */
3221 if (it->method == GET_FROM_DISPLAY_VECTOR)
3222 handle_overlay_change_p = 0;
3223
3224 /* Handle overlay changes.
3225 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3226 if it finds overlays. */
3227 if (handle_overlay_change_p)
3228 handled = handle_overlay_change (it);
3229 }
3230
3231 if (it->ellipsis_p)
3232 {
3233 setup_for_ellipsis (it, 0);
3234 break;
3235 }
3236 }
3237 while (handled == HANDLED_RECOMPUTE_PROPS);
3238
3239 /* Determine where to stop next. */
3240 if (handled == HANDLED_NORMALLY)
3241 compute_stop_pos (it);
3242 }
3243
3244
3245 /* Compute IT->stop_charpos from text property and overlay change
3246 information for IT's current position. */
3247
3248 static void
3249 compute_stop_pos (it)
3250 struct it *it;
3251 {
3252 register INTERVAL iv, next_iv;
3253 Lisp_Object object, limit, position;
3254 EMACS_INT charpos, bytepos;
3255
3256 /* If nowhere else, stop at the end. */
3257 it->stop_charpos = it->end_charpos;
3258
3259 if (STRINGP (it->string))
3260 {
3261 /* Strings are usually short, so don't limit the search for
3262 properties. */
3263 object = it->string;
3264 limit = Qnil;
3265 charpos = IT_STRING_CHARPOS (*it);
3266 bytepos = IT_STRING_BYTEPOS (*it);
3267 }
3268 else
3269 {
3270 EMACS_INT pos;
3271
3272 /* If next overlay change is in front of the current stop pos
3273 (which is IT->end_charpos), stop there. Note: value of
3274 next_overlay_change is point-max if no overlay change
3275 follows. */
3276 charpos = IT_CHARPOS (*it);
3277 bytepos = IT_BYTEPOS (*it);
3278 pos = next_overlay_change (charpos);
3279 if (pos < it->stop_charpos)
3280 it->stop_charpos = pos;
3281
3282 /* If showing the region, we have to stop at the region
3283 start or end because the face might change there. */
3284 if (it->region_beg_charpos > 0)
3285 {
3286 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3287 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3288 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3289 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3290 }
3291
3292 /* Set up variables for computing the stop position from text
3293 property changes. */
3294 XSETBUFFER (object, current_buffer);
3295 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3296 }
3297
3298 /* Get the interval containing IT's position. Value is a null
3299 interval if there isn't such an interval. */
3300 position = make_number (charpos);
3301 iv = validate_interval_range (object, &position, &position, 0);
3302 if (!NULL_INTERVAL_P (iv))
3303 {
3304 Lisp_Object values_here[LAST_PROP_IDX];
3305 struct props *p;
3306
3307 /* Get properties here. */
3308 for (p = it_props; p->handler; ++p)
3309 values_here[p->idx] = textget (iv->plist, *p->name);
3310
3311 /* Look for an interval following iv that has different
3312 properties. */
3313 for (next_iv = next_interval (iv);
3314 (!NULL_INTERVAL_P (next_iv)
3315 && (NILP (limit)
3316 || XFASTINT (limit) > next_iv->position));
3317 next_iv = next_interval (next_iv))
3318 {
3319 for (p = it_props; p->handler; ++p)
3320 {
3321 Lisp_Object new_value;
3322
3323 new_value = textget (next_iv->plist, *p->name);
3324 if (!EQ (values_here[p->idx], new_value))
3325 break;
3326 }
3327
3328 if (p->handler)
3329 break;
3330 }
3331
3332 if (!NULL_INTERVAL_P (next_iv))
3333 {
3334 if (INTEGERP (limit)
3335 && next_iv->position >= XFASTINT (limit))
3336 /* No text property change up to limit. */
3337 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3338 else
3339 /* Text properties change in next_iv. */
3340 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3341 }
3342 }
3343
3344 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3345 it->stop_charpos, it->string);
3346
3347 xassert (STRINGP (it->string)
3348 || (it->stop_charpos >= BEGV
3349 && it->stop_charpos >= IT_CHARPOS (*it)));
3350 }
3351
3352
3353 /* Return the position of the next overlay change after POS in
3354 current_buffer. Value is point-max if no overlay change
3355 follows. This is like `next-overlay-change' but doesn't use
3356 xmalloc. */
3357
3358 static EMACS_INT
3359 next_overlay_change (pos)
3360 EMACS_INT pos;
3361 {
3362 int noverlays;
3363 EMACS_INT endpos;
3364 Lisp_Object *overlays;
3365 int i;
3366
3367 /* Get all overlays at the given position. */
3368 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3369
3370 /* If any of these overlays ends before endpos,
3371 use its ending point instead. */
3372 for (i = 0; i < noverlays; ++i)
3373 {
3374 Lisp_Object oend;
3375 EMACS_INT oendpos;
3376
3377 oend = OVERLAY_END (overlays[i]);
3378 oendpos = OVERLAY_POSITION (oend);
3379 endpos = min (endpos, oendpos);
3380 }
3381
3382 return endpos;
3383 }
3384
3385
3386 \f
3387 /***********************************************************************
3388 Fontification
3389 ***********************************************************************/
3390
3391 /* Handle changes in the `fontified' property of the current buffer by
3392 calling hook functions from Qfontification_functions to fontify
3393 regions of text. */
3394
3395 static enum prop_handled
3396 handle_fontified_prop (it)
3397 struct it *it;
3398 {
3399 Lisp_Object prop, pos;
3400 enum prop_handled handled = HANDLED_NORMALLY;
3401
3402 if (!NILP (Vmemory_full))
3403 return handled;
3404
3405 /* Get the value of the `fontified' property at IT's current buffer
3406 position. (The `fontified' property doesn't have a special
3407 meaning in strings.) If the value is nil, call functions from
3408 Qfontification_functions. */
3409 if (!STRINGP (it->string)
3410 && it->s == NULL
3411 && !NILP (Vfontification_functions)
3412 && !NILP (Vrun_hooks)
3413 && (pos = make_number (IT_CHARPOS (*it)),
3414 prop = Fget_char_property (pos, Qfontified, Qnil),
3415 /* Ignore the special cased nil value always present at EOB since
3416 no amount of fontifying will be able to change it. */
3417 NILP (prop) && IT_CHARPOS (*it) < Z))
3418 {
3419 int count = SPECPDL_INDEX ();
3420 Lisp_Object val;
3421
3422 val = Vfontification_functions;
3423 specbind (Qfontification_functions, Qnil);
3424
3425 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3426 safe_call1 (val, pos);
3427 else
3428 {
3429 Lisp_Object globals, fn;
3430 struct gcpro gcpro1, gcpro2;
3431
3432 globals = Qnil;
3433 GCPRO2 (val, globals);
3434
3435 for (; CONSP (val); val = XCDR (val))
3436 {
3437 fn = XCAR (val);
3438
3439 if (EQ (fn, Qt))
3440 {
3441 /* A value of t indicates this hook has a local
3442 binding; it means to run the global binding too.
3443 In a global value, t should not occur. If it
3444 does, we must ignore it to avoid an endless
3445 loop. */
3446 for (globals = Fdefault_value (Qfontification_functions);
3447 CONSP (globals);
3448 globals = XCDR (globals))
3449 {
3450 fn = XCAR (globals);
3451 if (!EQ (fn, Qt))
3452 safe_call1 (fn, pos);
3453 }
3454 }
3455 else
3456 safe_call1 (fn, pos);
3457 }
3458
3459 UNGCPRO;
3460 }
3461
3462 unbind_to (count, Qnil);
3463
3464 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3465 something. This avoids an endless loop if they failed to
3466 fontify the text for which reason ever. */
3467 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3468 handled = HANDLED_RECOMPUTE_PROPS;
3469 }
3470
3471 return handled;
3472 }
3473
3474
3475 \f
3476 /***********************************************************************
3477 Faces
3478 ***********************************************************************/
3479
3480 /* Set up iterator IT from face properties at its current position.
3481 Called from handle_stop. */
3482
3483 static enum prop_handled
3484 handle_face_prop (it)
3485 struct it *it;
3486 {
3487 int new_face_id;
3488 EMACS_INT next_stop;
3489
3490 if (!STRINGP (it->string))
3491 {
3492 new_face_id
3493 = face_at_buffer_position (it->w,
3494 IT_CHARPOS (*it),
3495 it->region_beg_charpos,
3496 it->region_end_charpos,
3497 &next_stop,
3498 (IT_CHARPOS (*it)
3499 + TEXT_PROP_DISTANCE_LIMIT),
3500 0, it->base_face_id);
3501
3502 /* Is this a start of a run of characters with box face?
3503 Caveat: this can be called for a freshly initialized
3504 iterator; face_id is -1 in this case. We know that the new
3505 face will not change until limit, i.e. if the new face has a
3506 box, all characters up to limit will have one. But, as
3507 usual, we don't know whether limit is really the end. */
3508 if (new_face_id != it->face_id)
3509 {
3510 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3511
3512 /* If new face has a box but old face has not, this is
3513 the start of a run of characters with box, i.e. it has
3514 a shadow on the left side. The value of face_id of the
3515 iterator will be -1 if this is the initial call that gets
3516 the face. In this case, we have to look in front of IT's
3517 position and see whether there is a face != new_face_id. */
3518 it->start_of_box_run_p
3519 = (new_face->box != FACE_NO_BOX
3520 && (it->face_id >= 0
3521 || IT_CHARPOS (*it) == BEG
3522 || new_face_id != face_before_it_pos (it)));
3523 it->face_box_p = new_face->box != FACE_NO_BOX;
3524 }
3525 }
3526 else
3527 {
3528 int base_face_id, bufpos;
3529 int i;
3530 Lisp_Object from_overlay
3531 = (it->current.overlay_string_index >= 0
3532 ? it->string_overlays[it->current.overlay_string_index]
3533 : Qnil);
3534
3535 /* See if we got to this string directly or indirectly from
3536 an overlay property. That includes the before-string or
3537 after-string of an overlay, strings in display properties
3538 provided by an overlay, their text properties, etc.
3539
3540 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3541 if (! NILP (from_overlay))
3542 for (i = it->sp - 1; i >= 0; i--)
3543 {
3544 if (it->stack[i].current.overlay_string_index >= 0)
3545 from_overlay
3546 = it->string_overlays[it->stack[i].current.overlay_string_index];
3547 else if (! NILP (it->stack[i].from_overlay))
3548 from_overlay = it->stack[i].from_overlay;
3549
3550 if (!NILP (from_overlay))
3551 break;
3552 }
3553
3554 if (! NILP (from_overlay))
3555 {
3556 bufpos = IT_CHARPOS (*it);
3557 /* For a string from an overlay, the base face depends
3558 only on text properties and ignores overlays. */
3559 base_face_id
3560 = face_for_overlay_string (it->w,
3561 IT_CHARPOS (*it),
3562 it->region_beg_charpos,
3563 it->region_end_charpos,
3564 &next_stop,
3565 (IT_CHARPOS (*it)
3566 + TEXT_PROP_DISTANCE_LIMIT),
3567 0,
3568 from_overlay);
3569 }
3570 else
3571 {
3572 bufpos = 0;
3573
3574 /* For strings from a `display' property, use the face at
3575 IT's current buffer position as the base face to merge
3576 with, so that overlay strings appear in the same face as
3577 surrounding text, unless they specify their own
3578 faces. */
3579 base_face_id = underlying_face_id (it);
3580 }
3581
3582 new_face_id = face_at_string_position (it->w,
3583 it->string,
3584 IT_STRING_CHARPOS (*it),
3585 bufpos,
3586 it->region_beg_charpos,
3587 it->region_end_charpos,
3588 &next_stop,
3589 base_face_id, 0);
3590
3591 /* Is this a start of a run of characters with box? Caveat:
3592 this can be called for a freshly allocated iterator; face_id
3593 is -1 is this case. We know that the new face will not
3594 change until the next check pos, i.e. if the new face has a
3595 box, all characters up to that position will have a
3596 box. But, as usual, we don't know whether that position
3597 is really the end. */
3598 if (new_face_id != it->face_id)
3599 {
3600 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3601 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3602
3603 /* If new face has a box but old face hasn't, this is the
3604 start of a run of characters with box, i.e. it has a
3605 shadow on the left side. */
3606 it->start_of_box_run_p
3607 = new_face->box && (old_face == NULL || !old_face->box);
3608 it->face_box_p = new_face->box != FACE_NO_BOX;
3609 }
3610 }
3611
3612 it->face_id = new_face_id;
3613 return HANDLED_NORMALLY;
3614 }
3615
3616
3617 /* Return the ID of the face ``underlying'' IT's current position,
3618 which is in a string. If the iterator is associated with a
3619 buffer, return the face at IT's current buffer position.
3620 Otherwise, use the iterator's base_face_id. */
3621
3622 static int
3623 underlying_face_id (it)
3624 struct it *it;
3625 {
3626 int face_id = it->base_face_id, i;
3627
3628 xassert (STRINGP (it->string));
3629
3630 for (i = it->sp - 1; i >= 0; --i)
3631 if (NILP (it->stack[i].string))
3632 face_id = it->stack[i].face_id;
3633
3634 return face_id;
3635 }
3636
3637
3638 /* Compute the face one character before or after the current position
3639 of IT. BEFORE_P non-zero means get the face in front of IT's
3640 position. Value is the id of the face. */
3641
3642 static int
3643 face_before_or_after_it_pos (it, before_p)
3644 struct it *it;
3645 int before_p;
3646 {
3647 int face_id, limit;
3648 EMACS_INT next_check_charpos;
3649 struct text_pos pos;
3650
3651 xassert (it->s == NULL);
3652
3653 if (STRINGP (it->string))
3654 {
3655 int bufpos, base_face_id;
3656
3657 /* No face change past the end of the string (for the case
3658 we are padding with spaces). No face change before the
3659 string start. */
3660 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3661 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3662 return it->face_id;
3663
3664 /* Set pos to the position before or after IT's current position. */
3665 if (before_p)
3666 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3667 else
3668 /* For composition, we must check the character after the
3669 composition. */
3670 pos = (it->what == IT_COMPOSITION
3671 ? string_pos (IT_STRING_CHARPOS (*it)
3672 + it->cmp_it.nchars, it->string)
3673 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3674
3675 if (it->current.overlay_string_index >= 0)
3676 bufpos = IT_CHARPOS (*it);
3677 else
3678 bufpos = 0;
3679
3680 base_face_id = underlying_face_id (it);
3681
3682 /* Get the face for ASCII, or unibyte. */
3683 face_id = face_at_string_position (it->w,
3684 it->string,
3685 CHARPOS (pos),
3686 bufpos,
3687 it->region_beg_charpos,
3688 it->region_end_charpos,
3689 &next_check_charpos,
3690 base_face_id, 0);
3691
3692 /* Correct the face for charsets different from ASCII. Do it
3693 for the multibyte case only. The face returned above is
3694 suitable for unibyte text if IT->string is unibyte. */
3695 if (STRING_MULTIBYTE (it->string))
3696 {
3697 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3698 int rest = SBYTES (it->string) - BYTEPOS (pos);
3699 int c, len;
3700 struct face *face = FACE_FROM_ID (it->f, face_id);
3701
3702 c = string_char_and_length (p, &len);
3703 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3704 }
3705 }
3706 else
3707 {
3708 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3709 || (IT_CHARPOS (*it) <= BEGV && before_p))
3710 return it->face_id;
3711
3712 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3713 pos = it->current.pos;
3714
3715 if (before_p)
3716 DEC_TEXT_POS (pos, it->multibyte_p);
3717 else
3718 {
3719 if (it->what == IT_COMPOSITION)
3720 /* For composition, we must check the position after the
3721 composition. */
3722 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3723 else
3724 INC_TEXT_POS (pos, it->multibyte_p);
3725 }
3726
3727 /* Determine face for CHARSET_ASCII, or unibyte. */
3728 face_id = face_at_buffer_position (it->w,
3729 CHARPOS (pos),
3730 it->region_beg_charpos,
3731 it->region_end_charpos,
3732 &next_check_charpos,
3733 limit, 0, -1);
3734
3735 /* Correct the face for charsets different from ASCII. Do it
3736 for the multibyte case only. The face returned above is
3737 suitable for unibyte text if current_buffer is unibyte. */
3738 if (it->multibyte_p)
3739 {
3740 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3741 struct face *face = FACE_FROM_ID (it->f, face_id);
3742 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3743 }
3744 }
3745
3746 return face_id;
3747 }
3748
3749
3750 \f
3751 /***********************************************************************
3752 Invisible text
3753 ***********************************************************************/
3754
3755 /* Set up iterator IT from invisible properties at its current
3756 position. Called from handle_stop. */
3757
3758 static enum prop_handled
3759 handle_invisible_prop (it)
3760 struct it *it;
3761 {
3762 enum prop_handled handled = HANDLED_NORMALLY;
3763
3764 if (STRINGP (it->string))
3765 {
3766 extern Lisp_Object Qinvisible;
3767 Lisp_Object prop, end_charpos, limit, charpos;
3768
3769 /* Get the value of the invisible text property at the
3770 current position. Value will be nil if there is no such
3771 property. */
3772 charpos = make_number (IT_STRING_CHARPOS (*it));
3773 prop = Fget_text_property (charpos, Qinvisible, it->string);
3774
3775 if (!NILP (prop)
3776 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3777 {
3778 handled = HANDLED_RECOMPUTE_PROPS;
3779
3780 /* Get the position at which the next change of the
3781 invisible text property can be found in IT->string.
3782 Value will be nil if the property value is the same for
3783 all the rest of IT->string. */
3784 XSETINT (limit, SCHARS (it->string));
3785 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3786 it->string, limit);
3787
3788 /* Text at current position is invisible. The next
3789 change in the property is at position end_charpos.
3790 Move IT's current position to that position. */
3791 if (INTEGERP (end_charpos)
3792 && XFASTINT (end_charpos) < XFASTINT (limit))
3793 {
3794 struct text_pos old;
3795 old = it->current.string_pos;
3796 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3797 compute_string_pos (&it->current.string_pos, old, it->string);
3798 }
3799 else
3800 {
3801 /* The rest of the string is invisible. If this is an
3802 overlay string, proceed with the next overlay string
3803 or whatever comes and return a character from there. */
3804 if (it->current.overlay_string_index >= 0)
3805 {
3806 next_overlay_string (it);
3807 /* Don't check for overlay strings when we just
3808 finished processing them. */
3809 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3810 }
3811 else
3812 {
3813 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3814 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3815 }
3816 }
3817 }
3818 }
3819 else
3820 {
3821 int invis_p;
3822 EMACS_INT newpos, next_stop, start_charpos, tem;
3823 Lisp_Object pos, prop, overlay;
3824
3825 /* First of all, is there invisible text at this position? */
3826 tem = start_charpos = IT_CHARPOS (*it);
3827 pos = make_number (tem);
3828 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3829 &overlay);
3830 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3831
3832 /* If we are on invisible text, skip over it. */
3833 if (invis_p && start_charpos < it->end_charpos)
3834 {
3835 /* Record whether we have to display an ellipsis for the
3836 invisible text. */
3837 int display_ellipsis_p = invis_p == 2;
3838
3839 handled = HANDLED_RECOMPUTE_PROPS;
3840
3841 /* Loop skipping over invisible text. The loop is left at
3842 ZV or with IT on the first char being visible again. */
3843 do
3844 {
3845 /* Try to skip some invisible text. Return value is the
3846 position reached which can be equal to where we start
3847 if there is nothing invisible there. This skips both
3848 over invisible text properties and overlays with
3849 invisible property. */
3850 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3851
3852 /* If we skipped nothing at all we weren't at invisible
3853 text in the first place. If everything to the end of
3854 the buffer was skipped, end the loop. */
3855 if (newpos == tem || newpos >= ZV)
3856 invis_p = 0;
3857 else
3858 {
3859 /* We skipped some characters but not necessarily
3860 all there are. Check if we ended up on visible
3861 text. Fget_char_property returns the property of
3862 the char before the given position, i.e. if we
3863 get invis_p = 0, this means that the char at
3864 newpos is visible. */
3865 pos = make_number (newpos);
3866 prop = Fget_char_property (pos, Qinvisible, it->window);
3867 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3868 }
3869
3870 /* If we ended up on invisible text, proceed to
3871 skip starting with next_stop. */
3872 if (invis_p)
3873 tem = next_stop;
3874
3875 /* If there are adjacent invisible texts, don't lose the
3876 second one's ellipsis. */
3877 if (invis_p == 2)
3878 display_ellipsis_p = 1;
3879 }
3880 while (invis_p);
3881
3882 /* The position newpos is now either ZV or on visible text. */
3883 if (it->bidi_p && newpos < ZV)
3884 {
3885 /* With bidi iteration, the region of invisible text
3886 could start and/or end in the middle of a non-base
3887 embedding level. Therefore, we need to skip
3888 invisible text using the bidi iterator, starting at
3889 IT's current position, until we find ourselves
3890 outside the invisible text. Skipping invisible text
3891 _after_ bidi iteration avoids affecting the visual
3892 order of the displayed text when invisible properties
3893 are added or removed. */
3894 if (it->bidi_it.first_elt)
3895 {
3896 /* If we were `reseat'ed to a new paragraph,
3897 determine the paragraph base direction. We need
3898 to do it now because next_element_from_buffer may
3899 not have a chance to do it, if we are going to
3900 skip any text at the beginning, which resets the
3901 FIRST_ELT flag. */
3902 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
3903 }
3904 do
3905 {
3906 bidi_get_next_char_visually (&it->bidi_it);
3907 }
3908 while (it->stop_charpos <= it->bidi_it.charpos
3909 && it->bidi_it.charpos < newpos);
3910 IT_CHARPOS (*it) = it->bidi_it.charpos;
3911 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3912 /* If we overstepped NEWPOS, record its position in the
3913 iterator, so that we skip invisible text if later the
3914 bidi iteration lands us in the invisible region
3915 again. */
3916 if (IT_CHARPOS (*it) >= newpos)
3917 it->prev_stop = newpos;
3918 }
3919 else
3920 {
3921 IT_CHARPOS (*it) = newpos;
3922 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3923 }
3924
3925 /* If there are before-strings at the start of invisible
3926 text, and the text is invisible because of a text
3927 property, arrange to show before-strings because 20.x did
3928 it that way. (If the text is invisible because of an
3929 overlay property instead of a text property, this is
3930 already handled in the overlay code.) */
3931 if (NILP (overlay)
3932 && get_overlay_strings (it, it->stop_charpos))
3933 {
3934 handled = HANDLED_RECOMPUTE_PROPS;
3935 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3936 }
3937 else if (display_ellipsis_p)
3938 {
3939 /* Make sure that the glyphs of the ellipsis will get
3940 correct `charpos' values. If we would not update
3941 it->position here, the glyphs would belong to the
3942 last visible character _before_ the invisible
3943 text, which confuses `set_cursor_from_row'.
3944
3945 We use the last invisible position instead of the
3946 first because this way the cursor is always drawn on
3947 the first "." of the ellipsis, whenever PT is inside
3948 the invisible text. Otherwise the cursor would be
3949 placed _after_ the ellipsis when the point is after the
3950 first invisible character. */
3951 if (!STRINGP (it->object))
3952 {
3953 it->position.charpos = newpos - 1;
3954 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3955 }
3956 it->ellipsis_p = 1;
3957 /* Let the ellipsis display before
3958 considering any properties of the following char.
3959 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3960 handled = HANDLED_RETURN;
3961 }
3962 }
3963 }
3964
3965 return handled;
3966 }
3967
3968
3969 /* Make iterator IT return `...' next.
3970 Replaces LEN characters from buffer. */
3971
3972 static void
3973 setup_for_ellipsis (it, len)
3974 struct it *it;
3975 int len;
3976 {
3977 /* Use the display table definition for `...'. Invalid glyphs
3978 will be handled by the method returning elements from dpvec. */
3979 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3980 {
3981 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3982 it->dpvec = v->contents;
3983 it->dpend = v->contents + v->size;
3984 }
3985 else
3986 {
3987 /* Default `...'. */
3988 it->dpvec = default_invis_vector;
3989 it->dpend = default_invis_vector + 3;
3990 }
3991
3992 it->dpvec_char_len = len;
3993 it->current.dpvec_index = 0;
3994 it->dpvec_face_id = -1;
3995
3996 /* Remember the current face id in case glyphs specify faces.
3997 IT's face is restored in set_iterator_to_next.
3998 saved_face_id was set to preceding char's face in handle_stop. */
3999 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4000 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4001
4002 it->method = GET_FROM_DISPLAY_VECTOR;
4003 it->ellipsis_p = 1;
4004 }
4005
4006
4007 \f
4008 /***********************************************************************
4009 'display' property
4010 ***********************************************************************/
4011
4012 /* Set up iterator IT from `display' property at its current position.
4013 Called from handle_stop.
4014 We return HANDLED_RETURN if some part of the display property
4015 overrides the display of the buffer text itself.
4016 Otherwise we return HANDLED_NORMALLY. */
4017
4018 static enum prop_handled
4019 handle_display_prop (it)
4020 struct it *it;
4021 {
4022 Lisp_Object prop, object, overlay;
4023 struct text_pos *position;
4024 /* Nonzero if some property replaces the display of the text itself. */
4025 int display_replaced_p = 0;
4026
4027 if (STRINGP (it->string))
4028 {
4029 object = it->string;
4030 position = &it->current.string_pos;
4031 }
4032 else
4033 {
4034 XSETWINDOW (object, it->w);
4035 position = &it->current.pos;
4036 }
4037
4038 /* Reset those iterator values set from display property values. */
4039 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4040 it->space_width = Qnil;
4041 it->font_height = Qnil;
4042 it->voffset = 0;
4043
4044 /* We don't support recursive `display' properties, i.e. string
4045 values that have a string `display' property, that have a string
4046 `display' property etc. */
4047 if (!it->string_from_display_prop_p)
4048 it->area = TEXT_AREA;
4049
4050 prop = get_char_property_and_overlay (make_number (position->charpos),
4051 Qdisplay, object, &overlay);
4052 if (NILP (prop))
4053 return HANDLED_NORMALLY;
4054 /* Now OVERLAY is the overlay that gave us this property, or nil
4055 if it was a text property. */
4056
4057 if (!STRINGP (it->string))
4058 object = it->w->buffer;
4059
4060 if (CONSP (prop)
4061 /* Simple properties. */
4062 && !EQ (XCAR (prop), Qimage)
4063 && !EQ (XCAR (prop), Qspace)
4064 && !EQ (XCAR (prop), Qwhen)
4065 && !EQ (XCAR (prop), Qslice)
4066 && !EQ (XCAR (prop), Qspace_width)
4067 && !EQ (XCAR (prop), Qheight)
4068 && !EQ (XCAR (prop), Qraise)
4069 /* Marginal area specifications. */
4070 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
4071 && !EQ (XCAR (prop), Qleft_fringe)
4072 && !EQ (XCAR (prop), Qright_fringe)
4073 && !NILP (XCAR (prop)))
4074 {
4075 for (; CONSP (prop); prop = XCDR (prop))
4076 {
4077 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
4078 position, display_replaced_p))
4079 {
4080 display_replaced_p = 1;
4081 /* If some text in a string is replaced, `position' no
4082 longer points to the position of `object'. */
4083 if (STRINGP (object))
4084 break;
4085 }
4086 }
4087 }
4088 else if (VECTORP (prop))
4089 {
4090 int i;
4091 for (i = 0; i < ASIZE (prop); ++i)
4092 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
4093 position, display_replaced_p))
4094 {
4095 display_replaced_p = 1;
4096 /* If some text in a string is replaced, `position' no
4097 longer points to the position of `object'. */
4098 if (STRINGP (object))
4099 break;
4100 }
4101 }
4102 else
4103 {
4104 if (handle_single_display_spec (it, prop, object, overlay,
4105 position, 0))
4106 display_replaced_p = 1;
4107 }
4108
4109 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4110 }
4111
4112
4113 /* Value is the position of the end of the `display' property starting
4114 at START_POS in OBJECT. */
4115
4116 static struct text_pos
4117 display_prop_end (it, object, start_pos)
4118 struct it *it;
4119 Lisp_Object object;
4120 struct text_pos start_pos;
4121 {
4122 Lisp_Object end;
4123 struct text_pos end_pos;
4124
4125 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4126 Qdisplay, object, Qnil);
4127 CHARPOS (end_pos) = XFASTINT (end);
4128 if (STRINGP (object))
4129 compute_string_pos (&end_pos, start_pos, it->string);
4130 else
4131 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4132
4133 return end_pos;
4134 }
4135
4136
4137 /* Set up IT from a single `display' specification PROP. OBJECT
4138 is the object in which the `display' property was found. *POSITION
4139 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4140 means that we previously saw a display specification which already
4141 replaced text display with something else, for example an image;
4142 we ignore such properties after the first one has been processed.
4143
4144 OVERLAY is the overlay this `display' property came from,
4145 or nil if it was a text property.
4146
4147 If PROP is a `space' or `image' specification, and in some other
4148 cases too, set *POSITION to the position where the `display'
4149 property ends.
4150
4151 Value is non-zero if something was found which replaces the display
4152 of buffer or string text. */
4153
4154 static int
4155 handle_single_display_spec (it, spec, object, overlay, position,
4156 display_replaced_before_p)
4157 struct it *it;
4158 Lisp_Object spec;
4159 Lisp_Object object;
4160 Lisp_Object overlay;
4161 struct text_pos *position;
4162 int display_replaced_before_p;
4163 {
4164 Lisp_Object form;
4165 Lisp_Object location, value;
4166 struct text_pos start_pos, save_pos;
4167 int valid_p;
4168
4169 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4170 If the result is non-nil, use VALUE instead of SPEC. */
4171 form = Qt;
4172 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4173 {
4174 spec = XCDR (spec);
4175 if (!CONSP (spec))
4176 return 0;
4177 form = XCAR (spec);
4178 spec = XCDR (spec);
4179 }
4180
4181 if (!NILP (form) && !EQ (form, Qt))
4182 {
4183 int count = SPECPDL_INDEX ();
4184 struct gcpro gcpro1;
4185
4186 /* Bind `object' to the object having the `display' property, a
4187 buffer or string. Bind `position' to the position in the
4188 object where the property was found, and `buffer-position'
4189 to the current position in the buffer. */
4190 specbind (Qobject, object);
4191 specbind (Qposition, make_number (CHARPOS (*position)));
4192 specbind (Qbuffer_position,
4193 make_number (STRINGP (object)
4194 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4195 GCPRO1 (form);
4196 form = safe_eval (form);
4197 UNGCPRO;
4198 unbind_to (count, Qnil);
4199 }
4200
4201 if (NILP (form))
4202 return 0;
4203
4204 /* Handle `(height HEIGHT)' specifications. */
4205 if (CONSP (spec)
4206 && EQ (XCAR (spec), Qheight)
4207 && CONSP (XCDR (spec)))
4208 {
4209 if (!FRAME_WINDOW_P (it->f))
4210 return 0;
4211
4212 it->font_height = XCAR (XCDR (spec));
4213 if (!NILP (it->font_height))
4214 {
4215 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4216 int new_height = -1;
4217
4218 if (CONSP (it->font_height)
4219 && (EQ (XCAR (it->font_height), Qplus)
4220 || EQ (XCAR (it->font_height), Qminus))
4221 && CONSP (XCDR (it->font_height))
4222 && INTEGERP (XCAR (XCDR (it->font_height))))
4223 {
4224 /* `(+ N)' or `(- N)' where N is an integer. */
4225 int steps = XINT (XCAR (XCDR (it->font_height)));
4226 if (EQ (XCAR (it->font_height), Qplus))
4227 steps = - steps;
4228 it->face_id = smaller_face (it->f, it->face_id, steps);
4229 }
4230 else if (FUNCTIONP (it->font_height))
4231 {
4232 /* Call function with current height as argument.
4233 Value is the new height. */
4234 Lisp_Object height;
4235 height = safe_call1 (it->font_height,
4236 face->lface[LFACE_HEIGHT_INDEX]);
4237 if (NUMBERP (height))
4238 new_height = XFLOATINT (height);
4239 }
4240 else if (NUMBERP (it->font_height))
4241 {
4242 /* Value is a multiple of the canonical char height. */
4243 struct face *face;
4244
4245 face = FACE_FROM_ID (it->f,
4246 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4247 new_height = (XFLOATINT (it->font_height)
4248 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4249 }
4250 else
4251 {
4252 /* Evaluate IT->font_height with `height' bound to the
4253 current specified height to get the new height. */
4254 int count = SPECPDL_INDEX ();
4255
4256 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4257 value = safe_eval (it->font_height);
4258 unbind_to (count, Qnil);
4259
4260 if (NUMBERP (value))
4261 new_height = XFLOATINT (value);
4262 }
4263
4264 if (new_height > 0)
4265 it->face_id = face_with_height (it->f, it->face_id, new_height);
4266 }
4267
4268 return 0;
4269 }
4270
4271 /* Handle `(space-width WIDTH)'. */
4272 if (CONSP (spec)
4273 && EQ (XCAR (spec), Qspace_width)
4274 && CONSP (XCDR (spec)))
4275 {
4276 if (!FRAME_WINDOW_P (it->f))
4277 return 0;
4278
4279 value = XCAR (XCDR (spec));
4280 if (NUMBERP (value) && XFLOATINT (value) > 0)
4281 it->space_width = value;
4282
4283 return 0;
4284 }
4285
4286 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4287 if (CONSP (spec)
4288 && EQ (XCAR (spec), Qslice))
4289 {
4290 Lisp_Object tem;
4291
4292 if (!FRAME_WINDOW_P (it->f))
4293 return 0;
4294
4295 if (tem = XCDR (spec), CONSP (tem))
4296 {
4297 it->slice.x = XCAR (tem);
4298 if (tem = XCDR (tem), CONSP (tem))
4299 {
4300 it->slice.y = XCAR (tem);
4301 if (tem = XCDR (tem), CONSP (tem))
4302 {
4303 it->slice.width = XCAR (tem);
4304 if (tem = XCDR (tem), CONSP (tem))
4305 it->slice.height = XCAR (tem);
4306 }
4307 }
4308 }
4309
4310 return 0;
4311 }
4312
4313 /* Handle `(raise FACTOR)'. */
4314 if (CONSP (spec)
4315 && EQ (XCAR (spec), Qraise)
4316 && CONSP (XCDR (spec)))
4317 {
4318 if (!FRAME_WINDOW_P (it->f))
4319 return 0;
4320
4321 #ifdef HAVE_WINDOW_SYSTEM
4322 value = XCAR (XCDR (spec));
4323 if (NUMBERP (value))
4324 {
4325 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4326 it->voffset = - (XFLOATINT (value)
4327 * (FONT_HEIGHT (face->font)));
4328 }
4329 #endif /* HAVE_WINDOW_SYSTEM */
4330
4331 return 0;
4332 }
4333
4334 /* Don't handle the other kinds of display specifications
4335 inside a string that we got from a `display' property. */
4336 if (it->string_from_display_prop_p)
4337 return 0;
4338
4339 /* Characters having this form of property are not displayed, so
4340 we have to find the end of the property. */
4341 start_pos = *position;
4342 *position = display_prop_end (it, object, start_pos);
4343 value = Qnil;
4344
4345 /* Stop the scan at that end position--we assume that all
4346 text properties change there. */
4347 it->stop_charpos = position->charpos;
4348
4349 /* Handle `(left-fringe BITMAP [FACE])'
4350 and `(right-fringe BITMAP [FACE])'. */
4351 if (CONSP (spec)
4352 && (EQ (XCAR (spec), Qleft_fringe)
4353 || EQ (XCAR (spec), Qright_fringe))
4354 && CONSP (XCDR (spec)))
4355 {
4356 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4357 int fringe_bitmap;
4358
4359 if (!FRAME_WINDOW_P (it->f))
4360 /* If we return here, POSITION has been advanced
4361 across the text with this property. */
4362 return 0;
4363
4364 #ifdef HAVE_WINDOW_SYSTEM
4365 value = XCAR (XCDR (spec));
4366 if (!SYMBOLP (value)
4367 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4368 /* If we return here, POSITION has been advanced
4369 across the text with this property. */
4370 return 0;
4371
4372 if (CONSP (XCDR (XCDR (spec))))
4373 {
4374 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4375 int face_id2 = lookup_derived_face (it->f, face_name,
4376 FRINGE_FACE_ID, 0);
4377 if (face_id2 >= 0)
4378 face_id = face_id2;
4379 }
4380
4381 /* Save current settings of IT so that we can restore them
4382 when we are finished with the glyph property value. */
4383
4384 save_pos = it->position;
4385 it->position = *position;
4386 push_it (it);
4387 it->position = save_pos;
4388
4389 it->area = TEXT_AREA;
4390 it->what = IT_IMAGE;
4391 it->image_id = -1; /* no image */
4392 it->position = start_pos;
4393 it->object = NILP (object) ? it->w->buffer : object;
4394 it->method = GET_FROM_IMAGE;
4395 it->from_overlay = Qnil;
4396 it->face_id = face_id;
4397
4398 /* Say that we haven't consumed the characters with
4399 `display' property yet. The call to pop_it in
4400 set_iterator_to_next will clean this up. */
4401 *position = start_pos;
4402
4403 if (EQ (XCAR (spec), Qleft_fringe))
4404 {
4405 it->left_user_fringe_bitmap = fringe_bitmap;
4406 it->left_user_fringe_face_id = face_id;
4407 }
4408 else
4409 {
4410 it->right_user_fringe_bitmap = fringe_bitmap;
4411 it->right_user_fringe_face_id = face_id;
4412 }
4413 #endif /* HAVE_WINDOW_SYSTEM */
4414 return 1;
4415 }
4416
4417 /* Prepare to handle `((margin left-margin) ...)',
4418 `((margin right-margin) ...)' and `((margin nil) ...)'
4419 prefixes for display specifications. */
4420 location = Qunbound;
4421 if (CONSP (spec) && CONSP (XCAR (spec)))
4422 {
4423 Lisp_Object tem;
4424
4425 value = XCDR (spec);
4426 if (CONSP (value))
4427 value = XCAR (value);
4428
4429 tem = XCAR (spec);
4430 if (EQ (XCAR (tem), Qmargin)
4431 && (tem = XCDR (tem),
4432 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4433 (NILP (tem)
4434 || EQ (tem, Qleft_margin)
4435 || EQ (tem, Qright_margin))))
4436 location = tem;
4437 }
4438
4439 if (EQ (location, Qunbound))
4440 {
4441 location = Qnil;
4442 value = spec;
4443 }
4444
4445 /* After this point, VALUE is the property after any
4446 margin prefix has been stripped. It must be a string,
4447 an image specification, or `(space ...)'.
4448
4449 LOCATION specifies where to display: `left-margin',
4450 `right-margin' or nil. */
4451
4452 valid_p = (STRINGP (value)
4453 #ifdef HAVE_WINDOW_SYSTEM
4454 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4455 #endif /* not HAVE_WINDOW_SYSTEM */
4456 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4457
4458 if (valid_p && !display_replaced_before_p)
4459 {
4460 /* Save current settings of IT so that we can restore them
4461 when we are finished with the glyph property value. */
4462 save_pos = it->position;
4463 it->position = *position;
4464 push_it (it);
4465 it->position = save_pos;
4466 it->from_overlay = overlay;
4467
4468 if (NILP (location))
4469 it->area = TEXT_AREA;
4470 else if (EQ (location, Qleft_margin))
4471 it->area = LEFT_MARGIN_AREA;
4472 else
4473 it->area = RIGHT_MARGIN_AREA;
4474
4475 if (STRINGP (value))
4476 {
4477 it->string = value;
4478 it->multibyte_p = STRING_MULTIBYTE (it->string);
4479 it->current.overlay_string_index = -1;
4480 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4481 it->end_charpos = it->string_nchars = SCHARS (it->string);
4482 it->method = GET_FROM_STRING;
4483 it->stop_charpos = 0;
4484 it->string_from_display_prop_p = 1;
4485 /* Say that we haven't consumed the characters with
4486 `display' property yet. The call to pop_it in
4487 set_iterator_to_next will clean this up. */
4488 if (BUFFERP (object))
4489 *position = start_pos;
4490 }
4491 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4492 {
4493 it->method = GET_FROM_STRETCH;
4494 it->object = value;
4495 *position = it->position = start_pos;
4496 }
4497 #ifdef HAVE_WINDOW_SYSTEM
4498 else
4499 {
4500 it->what = IT_IMAGE;
4501 it->image_id = lookup_image (it->f, value);
4502 it->position = start_pos;
4503 it->object = NILP (object) ? it->w->buffer : object;
4504 it->method = GET_FROM_IMAGE;
4505
4506 /* Say that we haven't consumed the characters with
4507 `display' property yet. The call to pop_it in
4508 set_iterator_to_next will clean this up. */
4509 *position = start_pos;
4510 }
4511 #endif /* HAVE_WINDOW_SYSTEM */
4512
4513 return 1;
4514 }
4515
4516 /* Invalid property or property not supported. Restore
4517 POSITION to what it was before. */
4518 *position = start_pos;
4519 return 0;
4520 }
4521
4522
4523 /* Check if SPEC is a display sub-property value whose text should be
4524 treated as intangible. */
4525
4526 static int
4527 single_display_spec_intangible_p (prop)
4528 Lisp_Object prop;
4529 {
4530 /* Skip over `when FORM'. */
4531 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4532 {
4533 prop = XCDR (prop);
4534 if (!CONSP (prop))
4535 return 0;
4536 prop = XCDR (prop);
4537 }
4538
4539 if (STRINGP (prop))
4540 return 1;
4541
4542 if (!CONSP (prop))
4543 return 0;
4544
4545 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4546 we don't need to treat text as intangible. */
4547 if (EQ (XCAR (prop), Qmargin))
4548 {
4549 prop = XCDR (prop);
4550 if (!CONSP (prop))
4551 return 0;
4552
4553 prop = XCDR (prop);
4554 if (!CONSP (prop)
4555 || EQ (XCAR (prop), Qleft_margin)
4556 || EQ (XCAR (prop), Qright_margin))
4557 return 0;
4558 }
4559
4560 return (CONSP (prop)
4561 && (EQ (XCAR (prop), Qimage)
4562 || EQ (XCAR (prop), Qspace)));
4563 }
4564
4565
4566 /* Check if PROP is a display property value whose text should be
4567 treated as intangible. */
4568
4569 int
4570 display_prop_intangible_p (prop)
4571 Lisp_Object prop;
4572 {
4573 if (CONSP (prop)
4574 && CONSP (XCAR (prop))
4575 && !EQ (Qmargin, XCAR (XCAR (prop))))
4576 {
4577 /* A list of sub-properties. */
4578 while (CONSP (prop))
4579 {
4580 if (single_display_spec_intangible_p (XCAR (prop)))
4581 return 1;
4582 prop = XCDR (prop);
4583 }
4584 }
4585 else if (VECTORP (prop))
4586 {
4587 /* A vector of sub-properties. */
4588 int i;
4589 for (i = 0; i < ASIZE (prop); ++i)
4590 if (single_display_spec_intangible_p (AREF (prop, i)))
4591 return 1;
4592 }
4593 else
4594 return single_display_spec_intangible_p (prop);
4595
4596 return 0;
4597 }
4598
4599
4600 /* Return 1 if PROP is a display sub-property value containing STRING. */
4601
4602 static int
4603 single_display_spec_string_p (prop, string)
4604 Lisp_Object prop, string;
4605 {
4606 if (EQ (string, prop))
4607 return 1;
4608
4609 /* Skip over `when FORM'. */
4610 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4611 {
4612 prop = XCDR (prop);
4613 if (!CONSP (prop))
4614 return 0;
4615 prop = XCDR (prop);
4616 }
4617
4618 if (CONSP (prop))
4619 /* Skip over `margin LOCATION'. */
4620 if (EQ (XCAR (prop), Qmargin))
4621 {
4622 prop = XCDR (prop);
4623 if (!CONSP (prop))
4624 return 0;
4625
4626 prop = XCDR (prop);
4627 if (!CONSP (prop))
4628 return 0;
4629 }
4630
4631 return CONSP (prop) && EQ (XCAR (prop), string);
4632 }
4633
4634
4635 /* Return 1 if STRING appears in the `display' property PROP. */
4636
4637 static int
4638 display_prop_string_p (prop, string)
4639 Lisp_Object prop, string;
4640 {
4641 if (CONSP (prop)
4642 && CONSP (XCAR (prop))
4643 && !EQ (Qmargin, XCAR (XCAR (prop))))
4644 {
4645 /* A list of sub-properties. */
4646 while (CONSP (prop))
4647 {
4648 if (single_display_spec_string_p (XCAR (prop), string))
4649 return 1;
4650 prop = XCDR (prop);
4651 }
4652 }
4653 else if (VECTORP (prop))
4654 {
4655 /* A vector of sub-properties. */
4656 int i;
4657 for (i = 0; i < ASIZE (prop); ++i)
4658 if (single_display_spec_string_p (AREF (prop, i), string))
4659 return 1;
4660 }
4661 else
4662 return single_display_spec_string_p (prop, string);
4663
4664 return 0;
4665 }
4666
4667 /* Look for STRING in overlays and text properties in W's buffer,
4668 between character positions FROM and TO (excluding TO).
4669 BACK_P non-zero means look back (in this case, TO is supposed to be
4670 less than FROM).
4671 Value is the first character position where STRING was found, or
4672 zero if it wasn't found before hitting TO.
4673
4674 W's buffer must be current.
4675
4676 This function may only use code that doesn't eval because it is
4677 called asynchronously from note_mouse_highlight. */
4678
4679 static EMACS_INT
4680 string_buffer_position_lim (w, string, from, to, back_p)
4681 struct window *w;
4682 Lisp_Object string;
4683 EMACS_INT from, to;
4684 int back_p;
4685 {
4686 Lisp_Object limit, prop, pos;
4687 int found = 0;
4688
4689 pos = make_number (from);
4690
4691 if (!back_p) /* looking forward */
4692 {
4693 limit = make_number (min (to, ZV));
4694 while (!found && !EQ (pos, limit))
4695 {
4696 prop = Fget_char_property (pos, Qdisplay, Qnil);
4697 if (!NILP (prop) && display_prop_string_p (prop, string))
4698 found = 1;
4699 else
4700 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4701 limit);
4702 }
4703 }
4704 else /* looking back */
4705 {
4706 limit = make_number (max (to, BEGV));
4707 while (!found && !EQ (pos, limit))
4708 {
4709 prop = Fget_char_property (pos, Qdisplay, Qnil);
4710 if (!NILP (prop) && display_prop_string_p (prop, string))
4711 found = 1;
4712 else
4713 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4714 limit);
4715 }
4716 }
4717
4718 return found ? XINT (pos) : 0;
4719 }
4720
4721 /* Determine which buffer position in W's buffer STRING comes from.
4722 AROUND_CHARPOS is an approximate position where it could come from.
4723 Value is the buffer position or 0 if it couldn't be determined.
4724
4725 W's buffer must be current.
4726
4727 This function is necessary because we don't record buffer positions
4728 in glyphs generated from strings (to keep struct glyph small).
4729 This function may only use code that doesn't eval because it is
4730 called asynchronously from note_mouse_highlight. */
4731
4732 EMACS_INT
4733 string_buffer_position (w, string, around_charpos)
4734 struct window *w;
4735 Lisp_Object string;
4736 EMACS_INT around_charpos;
4737 {
4738 Lisp_Object limit, prop, pos;
4739 const int MAX_DISTANCE = 1000;
4740 EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
4741 around_charpos + MAX_DISTANCE,
4742 0);
4743
4744 if (!found)
4745 found = string_buffer_position_lim (w, string, around_charpos,
4746 around_charpos - MAX_DISTANCE, 1);
4747 return found;
4748 }
4749
4750
4751 \f
4752 /***********************************************************************
4753 `composition' property
4754 ***********************************************************************/
4755
4756 /* Set up iterator IT from `composition' property at its current
4757 position. Called from handle_stop. */
4758
4759 static enum prop_handled
4760 handle_composition_prop (it)
4761 struct it *it;
4762 {
4763 Lisp_Object prop, string;
4764 EMACS_INT pos, pos_byte, start, end;
4765
4766 if (STRINGP (it->string))
4767 {
4768 unsigned char *s;
4769
4770 pos = IT_STRING_CHARPOS (*it);
4771 pos_byte = IT_STRING_BYTEPOS (*it);
4772 string = it->string;
4773 s = SDATA (string) + pos_byte;
4774 it->c = STRING_CHAR (s);
4775 }
4776 else
4777 {
4778 pos = IT_CHARPOS (*it);
4779 pos_byte = IT_BYTEPOS (*it);
4780 string = Qnil;
4781 it->c = FETCH_CHAR (pos_byte);
4782 }
4783
4784 /* If there's a valid composition and point is not inside of the
4785 composition (in the case that the composition is from the current
4786 buffer), draw a glyph composed from the composition components. */
4787 if (find_composition (pos, -1, &start, &end, &prop, string)
4788 && COMPOSITION_VALID_P (start, end, prop)
4789 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4790 {
4791 if (start != pos)
4792 {
4793 if (STRINGP (it->string))
4794 pos_byte = string_char_to_byte (it->string, start);
4795 else
4796 pos_byte = CHAR_TO_BYTE (start);
4797 }
4798 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4799 prop, string);
4800
4801 if (it->cmp_it.id >= 0)
4802 {
4803 it->cmp_it.ch = -1;
4804 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4805 it->cmp_it.nglyphs = -1;
4806 }
4807 }
4808
4809 return HANDLED_NORMALLY;
4810 }
4811
4812
4813 \f
4814 /***********************************************************************
4815 Overlay strings
4816 ***********************************************************************/
4817
4818 /* The following structure is used to record overlay strings for
4819 later sorting in load_overlay_strings. */
4820
4821 struct overlay_entry
4822 {
4823 Lisp_Object overlay;
4824 Lisp_Object string;
4825 int priority;
4826 int after_string_p;
4827 };
4828
4829
4830 /* Set up iterator IT from overlay strings at its current position.
4831 Called from handle_stop. */
4832
4833 static enum prop_handled
4834 handle_overlay_change (it)
4835 struct it *it;
4836 {
4837 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4838 return HANDLED_RECOMPUTE_PROPS;
4839 else
4840 return HANDLED_NORMALLY;
4841 }
4842
4843
4844 /* Set up the next overlay string for delivery by IT, if there is an
4845 overlay string to deliver. Called by set_iterator_to_next when the
4846 end of the current overlay string is reached. If there are more
4847 overlay strings to display, IT->string and
4848 IT->current.overlay_string_index are set appropriately here.
4849 Otherwise IT->string is set to nil. */
4850
4851 static void
4852 next_overlay_string (it)
4853 struct it *it;
4854 {
4855 ++it->current.overlay_string_index;
4856 if (it->current.overlay_string_index == it->n_overlay_strings)
4857 {
4858 /* No more overlay strings. Restore IT's settings to what
4859 they were before overlay strings were processed, and
4860 continue to deliver from current_buffer. */
4861
4862 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4863 pop_it (it);
4864 xassert (it->sp > 0
4865 || (NILP (it->string)
4866 && it->method == GET_FROM_BUFFER
4867 && it->stop_charpos >= BEGV
4868 && it->stop_charpos <= it->end_charpos));
4869 it->current.overlay_string_index = -1;
4870 it->n_overlay_strings = 0;
4871
4872 /* If we're at the end of the buffer, record that we have
4873 processed the overlay strings there already, so that
4874 next_element_from_buffer doesn't try it again. */
4875 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4876 it->overlay_strings_at_end_processed_p = 1;
4877 }
4878 else
4879 {
4880 /* There are more overlay strings to process. If
4881 IT->current.overlay_string_index has advanced to a position
4882 where we must load IT->overlay_strings with more strings, do
4883 it. */
4884 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4885
4886 if (it->current.overlay_string_index && i == 0)
4887 load_overlay_strings (it, 0);
4888
4889 /* Initialize IT to deliver display elements from the overlay
4890 string. */
4891 it->string = it->overlay_strings[i];
4892 it->multibyte_p = STRING_MULTIBYTE (it->string);
4893 SET_TEXT_POS (it->current.string_pos, 0, 0);
4894 it->method = GET_FROM_STRING;
4895 it->stop_charpos = 0;
4896 if (it->cmp_it.stop_pos >= 0)
4897 it->cmp_it.stop_pos = 0;
4898 }
4899
4900 CHECK_IT (it);
4901 }
4902
4903
4904 /* Compare two overlay_entry structures E1 and E2. Used as a
4905 comparison function for qsort in load_overlay_strings. Overlay
4906 strings for the same position are sorted so that
4907
4908 1. All after-strings come in front of before-strings, except
4909 when they come from the same overlay.
4910
4911 2. Within after-strings, strings are sorted so that overlay strings
4912 from overlays with higher priorities come first.
4913
4914 2. Within before-strings, strings are sorted so that overlay
4915 strings from overlays with higher priorities come last.
4916
4917 Value is analogous to strcmp. */
4918
4919
4920 static int
4921 compare_overlay_entries (e1, e2)
4922 void *e1, *e2;
4923 {
4924 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4925 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4926 int result;
4927
4928 if (entry1->after_string_p != entry2->after_string_p)
4929 {
4930 /* Let after-strings appear in front of before-strings if
4931 they come from different overlays. */
4932 if (EQ (entry1->overlay, entry2->overlay))
4933 result = entry1->after_string_p ? 1 : -1;
4934 else
4935 result = entry1->after_string_p ? -1 : 1;
4936 }
4937 else if (entry1->after_string_p)
4938 /* After-strings sorted in order of decreasing priority. */
4939 result = entry2->priority - entry1->priority;
4940 else
4941 /* Before-strings sorted in order of increasing priority. */
4942 result = entry1->priority - entry2->priority;
4943
4944 return result;
4945 }
4946
4947
4948 /* Load the vector IT->overlay_strings with overlay strings from IT's
4949 current buffer position, or from CHARPOS if that is > 0. Set
4950 IT->n_overlays to the total number of overlay strings found.
4951
4952 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4953 a time. On entry into load_overlay_strings,
4954 IT->current.overlay_string_index gives the number of overlay
4955 strings that have already been loaded by previous calls to this
4956 function.
4957
4958 IT->add_overlay_start contains an additional overlay start
4959 position to consider for taking overlay strings from, if non-zero.
4960 This position comes into play when the overlay has an `invisible'
4961 property, and both before and after-strings. When we've skipped to
4962 the end of the overlay, because of its `invisible' property, we
4963 nevertheless want its before-string to appear.
4964 IT->add_overlay_start will contain the overlay start position
4965 in this case.
4966
4967 Overlay strings are sorted so that after-string strings come in
4968 front of before-string strings. Within before and after-strings,
4969 strings are sorted by overlay priority. See also function
4970 compare_overlay_entries. */
4971
4972 static void
4973 load_overlay_strings (it, charpos)
4974 struct it *it;
4975 int charpos;
4976 {
4977 extern Lisp_Object Qwindow, Qpriority;
4978 Lisp_Object overlay, window, str, invisible;
4979 struct Lisp_Overlay *ov;
4980 int start, end;
4981 int size = 20;
4982 int n = 0, i, j, invis_p;
4983 struct overlay_entry *entries
4984 = (struct overlay_entry *) alloca (size * sizeof *entries);
4985
4986 if (charpos <= 0)
4987 charpos = IT_CHARPOS (*it);
4988
4989 /* Append the overlay string STRING of overlay OVERLAY to vector
4990 `entries' which has size `size' and currently contains `n'
4991 elements. AFTER_P non-zero means STRING is an after-string of
4992 OVERLAY. */
4993 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4994 do \
4995 { \
4996 Lisp_Object priority; \
4997 \
4998 if (n == size) \
4999 { \
5000 int new_size = 2 * size; \
5001 struct overlay_entry *old = entries; \
5002 entries = \
5003 (struct overlay_entry *) alloca (new_size \
5004 * sizeof *entries); \
5005 bcopy (old, entries, size * sizeof *entries); \
5006 size = new_size; \
5007 } \
5008 \
5009 entries[n].string = (STRING); \
5010 entries[n].overlay = (OVERLAY); \
5011 priority = Foverlay_get ((OVERLAY), Qpriority); \
5012 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5013 entries[n].after_string_p = (AFTER_P); \
5014 ++n; \
5015 } \
5016 while (0)
5017
5018 /* Process overlay before the overlay center. */
5019 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5020 {
5021 XSETMISC (overlay, ov);
5022 xassert (OVERLAYP (overlay));
5023 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5024 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5025
5026 if (end < charpos)
5027 break;
5028
5029 /* Skip this overlay if it doesn't start or end at IT's current
5030 position. */
5031 if (end != charpos && start != charpos)
5032 continue;
5033
5034 /* Skip this overlay if it doesn't apply to IT->w. */
5035 window = Foverlay_get (overlay, Qwindow);
5036 if (WINDOWP (window) && XWINDOW (window) != it->w)
5037 continue;
5038
5039 /* If the text ``under'' the overlay is invisible, both before-
5040 and after-strings from this overlay are visible; start and
5041 end position are indistinguishable. */
5042 invisible = Foverlay_get (overlay, Qinvisible);
5043 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5044
5045 /* If overlay has a non-empty before-string, record it. */
5046 if ((start == charpos || (end == charpos && invis_p))
5047 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5048 && SCHARS (str))
5049 RECORD_OVERLAY_STRING (overlay, str, 0);
5050
5051 /* If overlay has a non-empty after-string, record it. */
5052 if ((end == charpos || (start == charpos && invis_p))
5053 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5054 && SCHARS (str))
5055 RECORD_OVERLAY_STRING (overlay, str, 1);
5056 }
5057
5058 /* Process overlays after the overlay center. */
5059 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5060 {
5061 XSETMISC (overlay, ov);
5062 xassert (OVERLAYP (overlay));
5063 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5064 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5065
5066 if (start > charpos)
5067 break;
5068
5069 /* Skip this overlay if it doesn't start or end at IT's current
5070 position. */
5071 if (end != charpos && start != charpos)
5072 continue;
5073
5074 /* Skip this overlay if it doesn't apply to IT->w. */
5075 window = Foverlay_get (overlay, Qwindow);
5076 if (WINDOWP (window) && XWINDOW (window) != it->w)
5077 continue;
5078
5079 /* If the text ``under'' the overlay is invisible, it has a zero
5080 dimension, and both before- and after-strings apply. */
5081 invisible = Foverlay_get (overlay, Qinvisible);
5082 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5083
5084 /* If overlay has a non-empty before-string, record it. */
5085 if ((start == charpos || (end == charpos && invis_p))
5086 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5087 && SCHARS (str))
5088 RECORD_OVERLAY_STRING (overlay, str, 0);
5089
5090 /* If overlay has a non-empty after-string, record it. */
5091 if ((end == charpos || (start == charpos && invis_p))
5092 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5093 && SCHARS (str))
5094 RECORD_OVERLAY_STRING (overlay, str, 1);
5095 }
5096
5097 #undef RECORD_OVERLAY_STRING
5098
5099 /* Sort entries. */
5100 if (n > 1)
5101 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5102
5103 /* Record the total number of strings to process. */
5104 it->n_overlay_strings = n;
5105
5106 /* IT->current.overlay_string_index is the number of overlay strings
5107 that have already been consumed by IT. Copy some of the
5108 remaining overlay strings to IT->overlay_strings. */
5109 i = 0;
5110 j = it->current.overlay_string_index;
5111 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5112 {
5113 it->overlay_strings[i] = entries[j].string;
5114 it->string_overlays[i++] = entries[j++].overlay;
5115 }
5116
5117 CHECK_IT (it);
5118 }
5119
5120
5121 /* Get the first chunk of overlay strings at IT's current buffer
5122 position, or at CHARPOS if that is > 0. Value is non-zero if at
5123 least one overlay string was found. */
5124
5125 static int
5126 get_overlay_strings_1 (it, charpos, compute_stop_p)
5127 struct it *it;
5128 int charpos;
5129 int compute_stop_p;
5130 {
5131 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5132 process. This fills IT->overlay_strings with strings, and sets
5133 IT->n_overlay_strings to the total number of strings to process.
5134 IT->pos.overlay_string_index has to be set temporarily to zero
5135 because load_overlay_strings needs this; it must be set to -1
5136 when no overlay strings are found because a zero value would
5137 indicate a position in the first overlay string. */
5138 it->current.overlay_string_index = 0;
5139 load_overlay_strings (it, charpos);
5140
5141 /* If we found overlay strings, set up IT to deliver display
5142 elements from the first one. Otherwise set up IT to deliver
5143 from current_buffer. */
5144 if (it->n_overlay_strings)
5145 {
5146 /* Make sure we know settings in current_buffer, so that we can
5147 restore meaningful values when we're done with the overlay
5148 strings. */
5149 if (compute_stop_p)
5150 compute_stop_pos (it);
5151 xassert (it->face_id >= 0);
5152
5153 /* Save IT's settings. They are restored after all overlay
5154 strings have been processed. */
5155 xassert (!compute_stop_p || it->sp == 0);
5156
5157 /* When called from handle_stop, there might be an empty display
5158 string loaded. In that case, don't bother saving it. */
5159 if (!STRINGP (it->string) || SCHARS (it->string))
5160 push_it (it);
5161
5162 /* Set up IT to deliver display elements from the first overlay
5163 string. */
5164 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5165 it->string = it->overlay_strings[0];
5166 it->from_overlay = Qnil;
5167 it->stop_charpos = 0;
5168 xassert (STRINGP (it->string));
5169 it->end_charpos = SCHARS (it->string);
5170 it->multibyte_p = STRING_MULTIBYTE (it->string);
5171 it->method = GET_FROM_STRING;
5172 return 1;
5173 }
5174
5175 it->current.overlay_string_index = -1;
5176 return 0;
5177 }
5178
5179 static int
5180 get_overlay_strings (it, charpos)
5181 struct it *it;
5182 int charpos;
5183 {
5184 it->string = Qnil;
5185 it->method = GET_FROM_BUFFER;
5186
5187 (void) get_overlay_strings_1 (it, charpos, 1);
5188
5189 CHECK_IT (it);
5190
5191 /* Value is non-zero if we found at least one overlay string. */
5192 return STRINGP (it->string);
5193 }
5194
5195
5196 \f
5197 /***********************************************************************
5198 Saving and restoring state
5199 ***********************************************************************/
5200
5201 /* Save current settings of IT on IT->stack. Called, for example,
5202 before setting up IT for an overlay string, to be able to restore
5203 IT's settings to what they were after the overlay string has been
5204 processed. */
5205
5206 static void
5207 push_it (it)
5208 struct it *it;
5209 {
5210 struct iterator_stack_entry *p;
5211
5212 xassert (it->sp < IT_STACK_SIZE);
5213 p = it->stack + it->sp;
5214
5215 p->stop_charpos = it->stop_charpos;
5216 p->prev_stop = it->prev_stop;
5217 p->base_level_stop = it->base_level_stop;
5218 p->cmp_it = it->cmp_it;
5219 xassert (it->face_id >= 0);
5220 p->face_id = it->face_id;
5221 p->string = it->string;
5222 p->method = it->method;
5223 p->from_overlay = it->from_overlay;
5224 switch (p->method)
5225 {
5226 case GET_FROM_IMAGE:
5227 p->u.image.object = it->object;
5228 p->u.image.image_id = it->image_id;
5229 p->u.image.slice = it->slice;
5230 break;
5231 case GET_FROM_STRETCH:
5232 p->u.stretch.object = it->object;
5233 break;
5234 }
5235 p->position = it->position;
5236 p->current = it->current;
5237 p->end_charpos = it->end_charpos;
5238 p->string_nchars = it->string_nchars;
5239 p->area = it->area;
5240 p->multibyte_p = it->multibyte_p;
5241 p->avoid_cursor_p = it->avoid_cursor_p;
5242 p->space_width = it->space_width;
5243 p->font_height = it->font_height;
5244 p->voffset = it->voffset;
5245 p->string_from_display_prop_p = it->string_from_display_prop_p;
5246 p->display_ellipsis_p = 0;
5247 p->line_wrap = it->line_wrap;
5248 ++it->sp;
5249 }
5250
5251
5252 /* Restore IT's settings from IT->stack. Called, for example, when no
5253 more overlay strings must be processed, and we return to delivering
5254 display elements from a buffer, or when the end of a string from a
5255 `display' property is reached and we return to delivering display
5256 elements from an overlay string, or from a buffer. */
5257
5258 static void
5259 pop_it (it)
5260 struct it *it;
5261 {
5262 struct iterator_stack_entry *p;
5263
5264 xassert (it->sp > 0);
5265 --it->sp;
5266 p = it->stack + it->sp;
5267 it->stop_charpos = p->stop_charpos;
5268 it->prev_stop = p->prev_stop;
5269 it->base_level_stop = p->base_level_stop;
5270 it->cmp_it = p->cmp_it;
5271 it->face_id = p->face_id;
5272 it->current = p->current;
5273 it->position = p->position;
5274 it->string = p->string;
5275 it->from_overlay = p->from_overlay;
5276 if (NILP (it->string))
5277 SET_TEXT_POS (it->current.string_pos, -1, -1);
5278 it->method = p->method;
5279 switch (it->method)
5280 {
5281 case GET_FROM_IMAGE:
5282 it->image_id = p->u.image.image_id;
5283 it->object = p->u.image.object;
5284 it->slice = p->u.image.slice;
5285 break;
5286 case GET_FROM_STRETCH:
5287 it->object = p->u.comp.object;
5288 break;
5289 case GET_FROM_BUFFER:
5290 it->object = it->w->buffer;
5291 break;
5292 case GET_FROM_STRING:
5293 it->object = it->string;
5294 break;
5295 case GET_FROM_DISPLAY_VECTOR:
5296 if (it->s)
5297 it->method = GET_FROM_C_STRING;
5298 else if (STRINGP (it->string))
5299 it->method = GET_FROM_STRING;
5300 else
5301 {
5302 it->method = GET_FROM_BUFFER;
5303 it->object = it->w->buffer;
5304 }
5305 }
5306 it->end_charpos = p->end_charpos;
5307 it->string_nchars = p->string_nchars;
5308 it->area = p->area;
5309 it->multibyte_p = p->multibyte_p;
5310 it->avoid_cursor_p = p->avoid_cursor_p;
5311 it->space_width = p->space_width;
5312 it->font_height = p->font_height;
5313 it->voffset = p->voffset;
5314 it->string_from_display_prop_p = p->string_from_display_prop_p;
5315 it->line_wrap = p->line_wrap;
5316 }
5317
5318
5319 \f
5320 /***********************************************************************
5321 Moving over lines
5322 ***********************************************************************/
5323
5324 /* Set IT's current position to the previous line start. */
5325
5326 static void
5327 back_to_previous_line_start (it)
5328 struct it *it;
5329 {
5330 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5331 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5332 }
5333
5334
5335 /* Move IT to the next line start.
5336
5337 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5338 we skipped over part of the text (as opposed to moving the iterator
5339 continuously over the text). Otherwise, don't change the value
5340 of *SKIPPED_P.
5341
5342 Newlines may come from buffer text, overlay strings, or strings
5343 displayed via the `display' property. That's the reason we can't
5344 simply use find_next_newline_no_quit.
5345
5346 Note that this function may not skip over invisible text that is so
5347 because of text properties and immediately follows a newline. If
5348 it would, function reseat_at_next_visible_line_start, when called
5349 from set_iterator_to_next, would effectively make invisible
5350 characters following a newline part of the wrong glyph row, which
5351 leads to wrong cursor motion. */
5352
5353 static int
5354 forward_to_next_line_start (it, skipped_p)
5355 struct it *it;
5356 int *skipped_p;
5357 {
5358 int old_selective, newline_found_p, n;
5359 const int MAX_NEWLINE_DISTANCE = 500;
5360
5361 /* If already on a newline, just consume it to avoid unintended
5362 skipping over invisible text below. */
5363 if (it->what == IT_CHARACTER
5364 && it->c == '\n'
5365 && CHARPOS (it->position) == IT_CHARPOS (*it))
5366 {
5367 set_iterator_to_next (it, 0);
5368 it->c = 0;
5369 return 1;
5370 }
5371
5372 /* Don't handle selective display in the following. It's (a)
5373 unnecessary because it's done by the caller, and (b) leads to an
5374 infinite recursion because next_element_from_ellipsis indirectly
5375 calls this function. */
5376 old_selective = it->selective;
5377 it->selective = 0;
5378
5379 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5380 from buffer text. */
5381 for (n = newline_found_p = 0;
5382 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5383 n += STRINGP (it->string) ? 0 : 1)
5384 {
5385 if (!get_next_display_element (it))
5386 return 0;
5387 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5388 set_iterator_to_next (it, 0);
5389 }
5390
5391 /* If we didn't find a newline near enough, see if we can use a
5392 short-cut. */
5393 if (!newline_found_p)
5394 {
5395 int start = IT_CHARPOS (*it);
5396 int limit = find_next_newline_no_quit (start, 1);
5397 Lisp_Object pos;
5398
5399 xassert (!STRINGP (it->string));
5400
5401 /* If there isn't any `display' property in sight, and no
5402 overlays, we can just use the position of the newline in
5403 buffer text. */
5404 if (it->stop_charpos >= limit
5405 || ((pos = Fnext_single_property_change (make_number (start),
5406 Qdisplay,
5407 Qnil, make_number (limit)),
5408 NILP (pos))
5409 && next_overlay_change (start) == ZV))
5410 {
5411 IT_CHARPOS (*it) = limit;
5412 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5413 *skipped_p = newline_found_p = 1;
5414 }
5415 else
5416 {
5417 while (get_next_display_element (it)
5418 && !newline_found_p)
5419 {
5420 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5421 set_iterator_to_next (it, 0);
5422 }
5423 }
5424 }
5425
5426 it->selective = old_selective;
5427 return newline_found_p;
5428 }
5429
5430
5431 /* Set IT's current position to the previous visible line start. Skip
5432 invisible text that is so either due to text properties or due to
5433 selective display. Caution: this does not change IT->current_x and
5434 IT->hpos. */
5435
5436 static void
5437 back_to_previous_visible_line_start (it)
5438 struct it *it;
5439 {
5440 while (IT_CHARPOS (*it) > BEGV)
5441 {
5442 back_to_previous_line_start (it);
5443
5444 if (IT_CHARPOS (*it) <= BEGV)
5445 break;
5446
5447 /* If selective > 0, then lines indented more than its value are
5448 invisible. */
5449 if (it->selective > 0
5450 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5451 (double) it->selective)) /* iftc */
5452 continue;
5453
5454 /* Check the newline before point for invisibility. */
5455 {
5456 Lisp_Object prop;
5457 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5458 Qinvisible, it->window);
5459 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5460 continue;
5461 }
5462
5463 if (IT_CHARPOS (*it) <= BEGV)
5464 break;
5465
5466 {
5467 struct it it2;
5468 int pos;
5469 EMACS_INT beg, end;
5470 Lisp_Object val, overlay;
5471
5472 /* If newline is part of a composition, continue from start of composition */
5473 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5474 && beg < IT_CHARPOS (*it))
5475 goto replaced;
5476
5477 /* If newline is replaced by a display property, find start of overlay
5478 or interval and continue search from that point. */
5479 it2 = *it;
5480 pos = --IT_CHARPOS (it2);
5481 --IT_BYTEPOS (it2);
5482 it2.sp = 0;
5483 it2.string_from_display_prop_p = 0;
5484 if (handle_display_prop (&it2) == HANDLED_RETURN
5485 && !NILP (val = get_char_property_and_overlay
5486 (make_number (pos), Qdisplay, Qnil, &overlay))
5487 && (OVERLAYP (overlay)
5488 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5489 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5490 goto replaced;
5491
5492 /* Newline is not replaced by anything -- so we are done. */
5493 break;
5494
5495 replaced:
5496 if (beg < BEGV)
5497 beg = BEGV;
5498 IT_CHARPOS (*it) = beg;
5499 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5500 }
5501 }
5502
5503 it->continuation_lines_width = 0;
5504
5505 xassert (IT_CHARPOS (*it) >= BEGV);
5506 xassert (IT_CHARPOS (*it) == BEGV
5507 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5508 CHECK_IT (it);
5509 }
5510
5511
5512 /* Reseat iterator IT at the previous visible line start. Skip
5513 invisible text that is so either due to text properties or due to
5514 selective display. At the end, update IT's overlay information,
5515 face information etc. */
5516
5517 void
5518 reseat_at_previous_visible_line_start (it)
5519 struct it *it;
5520 {
5521 back_to_previous_visible_line_start (it);
5522 reseat (it, it->current.pos, 1);
5523 CHECK_IT (it);
5524 }
5525
5526
5527 /* Reseat iterator IT on the next visible line start in the current
5528 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5529 preceding the line start. Skip over invisible text that is so
5530 because of selective display. Compute faces, overlays etc at the
5531 new position. Note that this function does not skip over text that
5532 is invisible because of text properties. */
5533
5534 static void
5535 reseat_at_next_visible_line_start (it, on_newline_p)
5536 struct it *it;
5537 int on_newline_p;
5538 {
5539 int newline_found_p, skipped_p = 0;
5540
5541 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5542
5543 /* Skip over lines that are invisible because they are indented
5544 more than the value of IT->selective. */
5545 if (it->selective > 0)
5546 while (IT_CHARPOS (*it) < ZV
5547 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5548 (double) it->selective)) /* iftc */
5549 {
5550 xassert (IT_BYTEPOS (*it) == BEGV
5551 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5552 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5553 }
5554
5555 /* Position on the newline if that's what's requested. */
5556 if (on_newline_p && newline_found_p)
5557 {
5558 if (STRINGP (it->string))
5559 {
5560 if (IT_STRING_CHARPOS (*it) > 0)
5561 {
5562 --IT_STRING_CHARPOS (*it);
5563 --IT_STRING_BYTEPOS (*it);
5564 }
5565 }
5566 else if (IT_CHARPOS (*it) > BEGV)
5567 {
5568 --IT_CHARPOS (*it);
5569 --IT_BYTEPOS (*it);
5570 reseat (it, it->current.pos, 0);
5571 }
5572 }
5573 else if (skipped_p)
5574 reseat (it, it->current.pos, 0);
5575
5576 CHECK_IT (it);
5577 }
5578
5579
5580 \f
5581 /***********************************************************************
5582 Changing an iterator's position
5583 ***********************************************************************/
5584
5585 /* Change IT's current position to POS in current_buffer. If FORCE_P
5586 is non-zero, always check for text properties at the new position.
5587 Otherwise, text properties are only looked up if POS >=
5588 IT->check_charpos of a property. */
5589
5590 static void
5591 reseat (it, pos, force_p)
5592 struct it *it;
5593 struct text_pos pos;
5594 int force_p;
5595 {
5596 int original_pos = IT_CHARPOS (*it);
5597
5598 reseat_1 (it, pos, 0);
5599
5600 /* Determine where to check text properties. Avoid doing it
5601 where possible because text property lookup is very expensive. */
5602 if (force_p
5603 || CHARPOS (pos) > it->stop_charpos
5604 || CHARPOS (pos) < original_pos)
5605 {
5606 if (it->bidi_p)
5607 {
5608 /* For bidi iteration, we need to prime prev_stop and
5609 base_level_stop with our best estimations. */
5610 if (CHARPOS (pos) < it->prev_stop)
5611 {
5612 handle_stop_backwards (it, BEGV);
5613 if (CHARPOS (pos) < it->base_level_stop)
5614 it->base_level_stop = 0;
5615 }
5616 else if (CHARPOS (pos) > it->stop_charpos
5617 && it->stop_charpos >= BEGV)
5618 handle_stop_backwards (it, it->stop_charpos);
5619 else /* force_p */
5620 handle_stop (it);
5621 }
5622 else
5623 {
5624 handle_stop (it);
5625 it->prev_stop = it->base_level_stop = 0;
5626 }
5627
5628 }
5629
5630 CHECK_IT (it);
5631 }
5632
5633
5634 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5635 IT->stop_pos to POS, also. */
5636
5637 static void
5638 reseat_1 (it, pos, set_stop_p)
5639 struct it *it;
5640 struct text_pos pos;
5641 int set_stop_p;
5642 {
5643 /* Don't call this function when scanning a C string. */
5644 xassert (it->s == NULL);
5645
5646 /* POS must be a reasonable value. */
5647 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5648
5649 it->current.pos = it->position = pos;
5650 it->end_charpos = ZV;
5651 it->dpvec = NULL;
5652 it->current.dpvec_index = -1;
5653 it->current.overlay_string_index = -1;
5654 IT_STRING_CHARPOS (*it) = -1;
5655 IT_STRING_BYTEPOS (*it) = -1;
5656 it->string = Qnil;
5657 it->string_from_display_prop_p = 0;
5658 it->method = GET_FROM_BUFFER;
5659 it->object = it->w->buffer;
5660 it->area = TEXT_AREA;
5661 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5662 it->sp = 0;
5663 it->string_from_display_prop_p = 0;
5664 it->face_before_selective_p = 0;
5665 if (it->bidi_p)
5666 it->bidi_it.first_elt = 1;
5667
5668 if (set_stop_p)
5669 {
5670 it->stop_charpos = CHARPOS (pos);
5671 it->base_level_stop = CHARPOS (pos);
5672 }
5673 }
5674
5675
5676 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5677 If S is non-null, it is a C string to iterate over. Otherwise,
5678 STRING gives a Lisp string to iterate over.
5679
5680 If PRECISION > 0, don't return more then PRECISION number of
5681 characters from the string.
5682
5683 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5684 characters have been returned. FIELD_WIDTH < 0 means an infinite
5685 field width.
5686
5687 MULTIBYTE = 0 means disable processing of multibyte characters,
5688 MULTIBYTE > 0 means enable it,
5689 MULTIBYTE < 0 means use IT->multibyte_p.
5690
5691 IT must be initialized via a prior call to init_iterator before
5692 calling this function. */
5693
5694 static void
5695 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
5696 struct it *it;
5697 unsigned char *s;
5698 Lisp_Object string;
5699 int charpos;
5700 int precision, field_width, multibyte;
5701 {
5702 /* No region in strings. */
5703 it->region_beg_charpos = it->region_end_charpos = -1;
5704
5705 /* No text property checks performed by default, but see below. */
5706 it->stop_charpos = -1;
5707
5708 /* Set iterator position and end position. */
5709 bzero (&it->current, sizeof it->current);
5710 it->current.overlay_string_index = -1;
5711 it->current.dpvec_index = -1;
5712 xassert (charpos >= 0);
5713
5714 /* If STRING is specified, use its multibyteness, otherwise use the
5715 setting of MULTIBYTE, if specified. */
5716 if (multibyte >= 0)
5717 it->multibyte_p = multibyte > 0;
5718
5719 if (s == NULL)
5720 {
5721 xassert (STRINGP (string));
5722 it->string = string;
5723 it->s = NULL;
5724 it->end_charpos = it->string_nchars = SCHARS (string);
5725 it->method = GET_FROM_STRING;
5726 it->current.string_pos = string_pos (charpos, string);
5727 }
5728 else
5729 {
5730 it->s = s;
5731 it->string = Qnil;
5732
5733 /* Note that we use IT->current.pos, not it->current.string_pos,
5734 for displaying C strings. */
5735 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5736 if (it->multibyte_p)
5737 {
5738 it->current.pos = c_string_pos (charpos, s, 1);
5739 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5740 }
5741 else
5742 {
5743 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5744 it->end_charpos = it->string_nchars = strlen (s);
5745 }
5746
5747 it->method = GET_FROM_C_STRING;
5748 }
5749
5750 /* PRECISION > 0 means don't return more than PRECISION characters
5751 from the string. */
5752 if (precision > 0 && it->end_charpos - charpos > precision)
5753 it->end_charpos = it->string_nchars = charpos + precision;
5754
5755 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5756 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5757 FIELD_WIDTH < 0 means infinite field width. This is useful for
5758 padding with `-' at the end of a mode line. */
5759 if (field_width < 0)
5760 field_width = INFINITY;
5761 if (field_width > it->end_charpos - charpos)
5762 it->end_charpos = charpos + field_width;
5763
5764 /* Use the standard display table for displaying strings. */
5765 if (DISP_TABLE_P (Vstandard_display_table))
5766 it->dp = XCHAR_TABLE (Vstandard_display_table);
5767
5768 it->stop_charpos = charpos;
5769 if (s == NULL && it->multibyte_p)
5770 {
5771 EMACS_INT endpos = SCHARS (it->string);
5772 if (endpos > it->end_charpos)
5773 endpos = it->end_charpos;
5774 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5775 it->string);
5776 }
5777 CHECK_IT (it);
5778 }
5779
5780
5781 \f
5782 /***********************************************************************
5783 Iteration
5784 ***********************************************************************/
5785
5786 /* Map enum it_method value to corresponding next_element_from_* function. */
5787
5788 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5789 {
5790 next_element_from_buffer,
5791 next_element_from_display_vector,
5792 next_element_from_string,
5793 next_element_from_c_string,
5794 next_element_from_image,
5795 next_element_from_stretch
5796 };
5797
5798 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5799
5800
5801 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5802 (possibly with the following characters). */
5803
5804 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5805 ((IT)->cmp_it.id >= 0 \
5806 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5807 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5808 END_CHARPOS, (IT)->w, \
5809 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5810 (IT)->string)))
5811
5812
5813 /* Load IT's display element fields with information about the next
5814 display element from the current position of IT. Value is zero if
5815 end of buffer (or C string) is reached. */
5816
5817 static struct frame *last_escape_glyph_frame = NULL;
5818 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5819 static int last_escape_glyph_merged_face_id = 0;
5820
5821 int
5822 get_next_display_element (it)
5823 struct it *it;
5824 {
5825 /* Non-zero means that we found a display element. Zero means that
5826 we hit the end of what we iterate over. Performance note: the
5827 function pointer `method' used here turns out to be faster than
5828 using a sequence of if-statements. */
5829 int success_p;
5830
5831 get_next:
5832 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5833
5834 if (it->what == IT_CHARACTER)
5835 {
5836 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5837 and only if (a) the resolved directionality of that character
5838 is R..." */
5839 /* FIXME: Do we need an exception for characters from display
5840 tables? */
5841 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5842 it->c = bidi_mirror_char (it->c);
5843 /* Map via display table or translate control characters.
5844 IT->c, IT->len etc. have been set to the next character by
5845 the function call above. If we have a display table, and it
5846 contains an entry for IT->c, translate it. Don't do this if
5847 IT->c itself comes from a display table, otherwise we could
5848 end up in an infinite recursion. (An alternative could be to
5849 count the recursion depth of this function and signal an
5850 error when a certain maximum depth is reached.) Is it worth
5851 it? */
5852 if (success_p && it->dpvec == NULL)
5853 {
5854 Lisp_Object dv;
5855 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5856 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5857 nbsp_or_shy = char_is_other;
5858 int decoded = it->c;
5859
5860 if (it->dp
5861 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5862 VECTORP (dv)))
5863 {
5864 struct Lisp_Vector *v = XVECTOR (dv);
5865
5866 /* Return the first character from the display table
5867 entry, if not empty. If empty, don't display the
5868 current character. */
5869 if (v->size)
5870 {
5871 it->dpvec_char_len = it->len;
5872 it->dpvec = v->contents;
5873 it->dpend = v->contents + v->size;
5874 it->current.dpvec_index = 0;
5875 it->dpvec_face_id = -1;
5876 it->saved_face_id = it->face_id;
5877 it->method = GET_FROM_DISPLAY_VECTOR;
5878 it->ellipsis_p = 0;
5879 }
5880 else
5881 {
5882 set_iterator_to_next (it, 0);
5883 }
5884 goto get_next;
5885 }
5886
5887 if (unibyte_display_via_language_environment
5888 && !ASCII_CHAR_P (it->c))
5889 decoded = DECODE_CHAR (unibyte, it->c);
5890
5891 if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
5892 {
5893 if (it->multibyte_p)
5894 nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
5895 : it->c == 0xAD ? char_is_soft_hyphen
5896 : char_is_other);
5897 else if (unibyte_display_via_language_environment)
5898 nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
5899 : decoded == 0xAD ? char_is_soft_hyphen
5900 : char_is_other);
5901 }
5902
5903 /* Translate control characters into `\003' or `^C' form.
5904 Control characters coming from a display table entry are
5905 currently not translated because we use IT->dpvec to hold
5906 the translation. This could easily be changed but I
5907 don't believe that it is worth doing.
5908
5909 If it->multibyte_p is nonzero, non-printable non-ASCII
5910 characters are also translated to octal form.
5911
5912 If it->multibyte_p is zero, eight-bit characters that
5913 don't have corresponding multibyte char code are also
5914 translated to octal form. */
5915 if ((it->c < ' '
5916 ? (it->area != TEXT_AREA
5917 /* In mode line, treat \n, \t like other crl chars. */
5918 || (it->c != '\t'
5919 && it->glyph_row
5920 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5921 || (it->c != '\n' && it->c != '\t'))
5922 : (nbsp_or_shy
5923 || (it->multibyte_p
5924 ? ! CHAR_PRINTABLE_P (it->c)
5925 : (! unibyte_display_via_language_environment
5926 ? it->c >= 0x80
5927 : (decoded >= 0x80 && decoded < 0xA0))))))
5928 {
5929 /* IT->c is a control character which must be displayed
5930 either as '\003' or as `^C' where the '\\' and '^'
5931 can be defined in the display table. Fill
5932 IT->ctl_chars with glyphs for what we have to
5933 display. Then, set IT->dpvec to these glyphs. */
5934 Lisp_Object gc;
5935 int ctl_len;
5936 int face_id, lface_id = 0 ;
5937 int escape_glyph;
5938
5939 /* Handle control characters with ^. */
5940
5941 if (it->c < 128 && it->ctl_arrow_p)
5942 {
5943 int g;
5944
5945 g = '^'; /* default glyph for Control */
5946 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5947 if (it->dp
5948 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5949 && GLYPH_CODE_CHAR_VALID_P (gc))
5950 {
5951 g = GLYPH_CODE_CHAR (gc);
5952 lface_id = GLYPH_CODE_FACE (gc);
5953 }
5954 if (lface_id)
5955 {
5956 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5957 }
5958 else if (it->f == last_escape_glyph_frame
5959 && it->face_id == last_escape_glyph_face_id)
5960 {
5961 face_id = last_escape_glyph_merged_face_id;
5962 }
5963 else
5964 {
5965 /* Merge the escape-glyph face into the current face. */
5966 face_id = merge_faces (it->f, Qescape_glyph, 0,
5967 it->face_id);
5968 last_escape_glyph_frame = it->f;
5969 last_escape_glyph_face_id = it->face_id;
5970 last_escape_glyph_merged_face_id = face_id;
5971 }
5972
5973 XSETINT (it->ctl_chars[0], g);
5974 XSETINT (it->ctl_chars[1], it->c ^ 0100);
5975 ctl_len = 2;
5976 goto display_control;
5977 }
5978
5979 /* Handle non-break space in the mode where it only gets
5980 highlighting. */
5981
5982 if (EQ (Vnobreak_char_display, Qt)
5983 && nbsp_or_shy == char_is_nbsp)
5984 {
5985 /* Merge the no-break-space face into the current face. */
5986 face_id = merge_faces (it->f, Qnobreak_space, 0,
5987 it->face_id);
5988
5989 it->c = ' ';
5990 XSETINT (it->ctl_chars[0], ' ');
5991 ctl_len = 1;
5992 goto display_control;
5993 }
5994
5995 /* Handle sequences that start with the "escape glyph". */
5996
5997 /* the default escape glyph is \. */
5998 escape_glyph = '\\';
5999
6000 if (it->dp
6001 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
6002 && GLYPH_CODE_CHAR_VALID_P (gc))
6003 {
6004 escape_glyph = GLYPH_CODE_CHAR (gc);
6005 lface_id = GLYPH_CODE_FACE (gc);
6006 }
6007 if (lface_id)
6008 {
6009 /* The display table specified a face.
6010 Merge it into face_id and also into escape_glyph. */
6011 face_id = merge_faces (it->f, Qt, lface_id,
6012 it->face_id);
6013 }
6014 else if (it->f == last_escape_glyph_frame
6015 && it->face_id == last_escape_glyph_face_id)
6016 {
6017 face_id = last_escape_glyph_merged_face_id;
6018 }
6019 else
6020 {
6021 /* Merge the escape-glyph face into the current face. */
6022 face_id = merge_faces (it->f, Qescape_glyph, 0,
6023 it->face_id);
6024 last_escape_glyph_frame = it->f;
6025 last_escape_glyph_face_id = it->face_id;
6026 last_escape_glyph_merged_face_id = face_id;
6027 }
6028
6029 /* Handle soft hyphens in the mode where they only get
6030 highlighting. */
6031
6032 if (EQ (Vnobreak_char_display, Qt)
6033 && nbsp_or_shy == char_is_soft_hyphen)
6034 {
6035 it->c = '-';
6036 XSETINT (it->ctl_chars[0], '-');
6037 ctl_len = 1;
6038 goto display_control;
6039 }
6040
6041 /* Handle non-break space and soft hyphen
6042 with the escape glyph. */
6043
6044 if (nbsp_or_shy)
6045 {
6046 XSETINT (it->ctl_chars[0], escape_glyph);
6047 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
6048 XSETINT (it->ctl_chars[1], it->c);
6049 ctl_len = 2;
6050 goto display_control;
6051 }
6052
6053 {
6054 unsigned char str[MAX_MULTIBYTE_LENGTH];
6055 int len;
6056 int i;
6057
6058 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
6059 if (CHAR_BYTE8_P (it->c))
6060 {
6061 str[0] = CHAR_TO_BYTE8 (it->c);
6062 len = 1;
6063 }
6064 else if (it->c < 256)
6065 {
6066 str[0] = it->c;
6067 len = 1;
6068 }
6069 else
6070 {
6071 /* It's an invalid character, which shouldn't
6072 happen actually, but due to bugs it may
6073 happen. Let's print the char as is, there's
6074 not much meaningful we can do with it. */
6075 str[0] = it->c;
6076 str[1] = it->c >> 8;
6077 str[2] = it->c >> 16;
6078 str[3] = it->c >> 24;
6079 len = 4;
6080 }
6081
6082 for (i = 0; i < len; i++)
6083 {
6084 int g;
6085 XSETINT (it->ctl_chars[i * 4], escape_glyph);
6086 /* Insert three more glyphs into IT->ctl_chars for
6087 the octal display of the character. */
6088 g = ((str[i] >> 6) & 7) + '0';
6089 XSETINT (it->ctl_chars[i * 4 + 1], g);
6090 g = ((str[i] >> 3) & 7) + '0';
6091 XSETINT (it->ctl_chars[i * 4 + 2], g);
6092 g = (str[i] & 7) + '0';
6093 XSETINT (it->ctl_chars[i * 4 + 3], g);
6094 }
6095 ctl_len = len * 4;
6096 }
6097
6098 display_control:
6099 /* Set up IT->dpvec and return first character from it. */
6100 it->dpvec_char_len = it->len;
6101 it->dpvec = it->ctl_chars;
6102 it->dpend = it->dpvec + ctl_len;
6103 it->current.dpvec_index = 0;
6104 it->dpvec_face_id = face_id;
6105 it->saved_face_id = it->face_id;
6106 it->method = GET_FROM_DISPLAY_VECTOR;
6107 it->ellipsis_p = 0;
6108 goto get_next;
6109 }
6110 }
6111 }
6112
6113 #ifdef HAVE_WINDOW_SYSTEM
6114 /* Adjust face id for a multibyte character. There are no multibyte
6115 character in unibyte text. */
6116 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6117 && it->multibyte_p
6118 && success_p
6119 && FRAME_WINDOW_P (it->f))
6120 {
6121 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6122
6123 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6124 {
6125 /* Automatic composition with glyph-string. */
6126 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6127
6128 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6129 }
6130 else
6131 {
6132 int pos = (it->s ? -1
6133 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6134 : IT_CHARPOS (*it));
6135
6136 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
6137 }
6138 }
6139 #endif
6140
6141 /* Is this character the last one of a run of characters with
6142 box? If yes, set IT->end_of_box_run_p to 1. */
6143 if (it->face_box_p
6144 && it->s == NULL)
6145 {
6146 if (it->method == GET_FROM_STRING && it->sp)
6147 {
6148 int face_id = underlying_face_id (it);
6149 struct face *face = FACE_FROM_ID (it->f, face_id);
6150
6151 if (face)
6152 {
6153 if (face->box == FACE_NO_BOX)
6154 {
6155 /* If the box comes from face properties in a
6156 display string, check faces in that string. */
6157 int string_face_id = face_after_it_pos (it);
6158 it->end_of_box_run_p
6159 = (FACE_FROM_ID (it->f, string_face_id)->box
6160 == FACE_NO_BOX);
6161 }
6162 /* Otherwise, the box comes from the underlying face.
6163 If this is the last string character displayed, check
6164 the next buffer location. */
6165 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6166 && (it->current.overlay_string_index
6167 == it->n_overlay_strings - 1))
6168 {
6169 EMACS_INT ignore;
6170 int next_face_id;
6171 struct text_pos pos = it->current.pos;
6172 INC_TEXT_POS (pos, it->multibyte_p);
6173
6174 next_face_id = face_at_buffer_position
6175 (it->w, CHARPOS (pos), it->region_beg_charpos,
6176 it->region_end_charpos, &ignore,
6177 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6178 -1);
6179 it->end_of_box_run_p
6180 = (FACE_FROM_ID (it->f, next_face_id)->box
6181 == FACE_NO_BOX);
6182 }
6183 }
6184 }
6185 else
6186 {
6187 int face_id = face_after_it_pos (it);
6188 it->end_of_box_run_p
6189 = (face_id != it->face_id
6190 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6191 }
6192 }
6193
6194 /* Value is 0 if end of buffer or string reached. */
6195 return success_p;
6196 }
6197
6198
6199 /* Move IT to the next display element.
6200
6201 RESEAT_P non-zero means if called on a newline in buffer text,
6202 skip to the next visible line start.
6203
6204 Functions get_next_display_element and set_iterator_to_next are
6205 separate because I find this arrangement easier to handle than a
6206 get_next_display_element function that also increments IT's
6207 position. The way it is we can first look at an iterator's current
6208 display element, decide whether it fits on a line, and if it does,
6209 increment the iterator position. The other way around we probably
6210 would either need a flag indicating whether the iterator has to be
6211 incremented the next time, or we would have to implement a
6212 decrement position function which would not be easy to write. */
6213
6214 void
6215 set_iterator_to_next (it, reseat_p)
6216 struct it *it;
6217 int reseat_p;
6218 {
6219 /* Reset flags indicating start and end of a sequence of characters
6220 with box. Reset them at the start of this function because
6221 moving the iterator to a new position might set them. */
6222 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6223
6224 switch (it->method)
6225 {
6226 case GET_FROM_BUFFER:
6227 /* The current display element of IT is a character from
6228 current_buffer. Advance in the buffer, and maybe skip over
6229 invisible lines that are so because of selective display. */
6230 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6231 reseat_at_next_visible_line_start (it, 0);
6232 else if (it->cmp_it.id >= 0)
6233 {
6234 IT_CHARPOS (*it) += it->cmp_it.nchars;
6235 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6236 if (it->cmp_it.to < it->cmp_it.nglyphs)
6237 it->cmp_it.from = it->cmp_it.to;
6238 else
6239 {
6240 it->cmp_it.id = -1;
6241 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6242 IT_BYTEPOS (*it), it->stop_charpos,
6243 Qnil);
6244 }
6245 }
6246 else
6247 {
6248 xassert (it->len != 0);
6249
6250 if (!it->bidi_p)
6251 {
6252 IT_BYTEPOS (*it) += it->len;
6253 IT_CHARPOS (*it) += 1;
6254 }
6255 else
6256 {
6257 /* If this is a new paragraph, determine its base
6258 direction (a.k.a. its base embedding level). */
6259 if (it->bidi_it.new_paragraph)
6260 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6261 bidi_get_next_char_visually (&it->bidi_it);
6262 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6263 IT_CHARPOS (*it) = it->bidi_it.charpos;
6264 }
6265 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6266 }
6267 break;
6268
6269 case GET_FROM_C_STRING:
6270 /* Current display element of IT is from a C string. */
6271 IT_BYTEPOS (*it) += it->len;
6272 IT_CHARPOS (*it) += 1;
6273 break;
6274
6275 case GET_FROM_DISPLAY_VECTOR:
6276 /* Current display element of IT is from a display table entry.
6277 Advance in the display table definition. Reset it to null if
6278 end reached, and continue with characters from buffers/
6279 strings. */
6280 ++it->current.dpvec_index;
6281
6282 /* Restore face of the iterator to what they were before the
6283 display vector entry (these entries may contain faces). */
6284 it->face_id = it->saved_face_id;
6285
6286 if (it->dpvec + it->current.dpvec_index == it->dpend)
6287 {
6288 int recheck_faces = it->ellipsis_p;
6289
6290 if (it->s)
6291 it->method = GET_FROM_C_STRING;
6292 else if (STRINGP (it->string))
6293 it->method = GET_FROM_STRING;
6294 else
6295 {
6296 it->method = GET_FROM_BUFFER;
6297 it->object = it->w->buffer;
6298 }
6299
6300 it->dpvec = NULL;
6301 it->current.dpvec_index = -1;
6302
6303 /* Skip over characters which were displayed via IT->dpvec. */
6304 if (it->dpvec_char_len < 0)
6305 reseat_at_next_visible_line_start (it, 1);
6306 else if (it->dpvec_char_len > 0)
6307 {
6308 if (it->method == GET_FROM_STRING
6309 && it->n_overlay_strings > 0)
6310 it->ignore_overlay_strings_at_pos_p = 1;
6311 it->len = it->dpvec_char_len;
6312 set_iterator_to_next (it, reseat_p);
6313 }
6314
6315 /* Maybe recheck faces after display vector */
6316 if (recheck_faces)
6317 it->stop_charpos = IT_CHARPOS (*it);
6318 }
6319 break;
6320
6321 case GET_FROM_STRING:
6322 /* Current display element is a character from a Lisp string. */
6323 xassert (it->s == NULL && STRINGP (it->string));
6324 if (it->cmp_it.id >= 0)
6325 {
6326 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6327 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6328 if (it->cmp_it.to < it->cmp_it.nglyphs)
6329 it->cmp_it.from = it->cmp_it.to;
6330 else
6331 {
6332 it->cmp_it.id = -1;
6333 composition_compute_stop_pos (&it->cmp_it,
6334 IT_STRING_CHARPOS (*it),
6335 IT_STRING_BYTEPOS (*it),
6336 it->stop_charpos, it->string);
6337 }
6338 }
6339 else
6340 {
6341 IT_STRING_BYTEPOS (*it) += it->len;
6342 IT_STRING_CHARPOS (*it) += 1;
6343 }
6344
6345 consider_string_end:
6346
6347 if (it->current.overlay_string_index >= 0)
6348 {
6349 /* IT->string is an overlay string. Advance to the
6350 next, if there is one. */
6351 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6352 {
6353 it->ellipsis_p = 0;
6354 next_overlay_string (it);
6355 if (it->ellipsis_p)
6356 setup_for_ellipsis (it, 0);
6357 }
6358 }
6359 else
6360 {
6361 /* IT->string is not an overlay string. If we reached
6362 its end, and there is something on IT->stack, proceed
6363 with what is on the stack. This can be either another
6364 string, this time an overlay string, or a buffer. */
6365 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6366 && it->sp > 0)
6367 {
6368 pop_it (it);
6369 if (it->method == GET_FROM_STRING)
6370 goto consider_string_end;
6371 }
6372 }
6373 break;
6374
6375 case GET_FROM_IMAGE:
6376 case GET_FROM_STRETCH:
6377 /* The position etc with which we have to proceed are on
6378 the stack. The position may be at the end of a string,
6379 if the `display' property takes up the whole string. */
6380 xassert (it->sp > 0);
6381 pop_it (it);
6382 if (it->method == GET_FROM_STRING)
6383 goto consider_string_end;
6384 break;
6385
6386 default:
6387 /* There are no other methods defined, so this should be a bug. */
6388 abort ();
6389 }
6390
6391 xassert (it->method != GET_FROM_STRING
6392 || (STRINGP (it->string)
6393 && IT_STRING_CHARPOS (*it) >= 0));
6394 }
6395
6396 /* Load IT's display element fields with information about the next
6397 display element which comes from a display table entry or from the
6398 result of translating a control character to one of the forms `^C'
6399 or `\003'.
6400
6401 IT->dpvec holds the glyphs to return as characters.
6402 IT->saved_face_id holds the face id before the display vector--it
6403 is restored into IT->face_id in set_iterator_to_next. */
6404
6405 static int
6406 next_element_from_display_vector (it)
6407 struct it *it;
6408 {
6409 Lisp_Object gc;
6410
6411 /* Precondition. */
6412 xassert (it->dpvec && it->current.dpvec_index >= 0);
6413
6414 it->face_id = it->saved_face_id;
6415
6416 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6417 That seemed totally bogus - so I changed it... */
6418 gc = it->dpvec[it->current.dpvec_index];
6419
6420 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6421 {
6422 it->c = GLYPH_CODE_CHAR (gc);
6423 it->len = CHAR_BYTES (it->c);
6424
6425 /* The entry may contain a face id to use. Such a face id is
6426 the id of a Lisp face, not a realized face. A face id of
6427 zero means no face is specified. */
6428 if (it->dpvec_face_id >= 0)
6429 it->face_id = it->dpvec_face_id;
6430 else
6431 {
6432 int lface_id = GLYPH_CODE_FACE (gc);
6433 if (lface_id > 0)
6434 it->face_id = merge_faces (it->f, Qt, lface_id,
6435 it->saved_face_id);
6436 }
6437 }
6438 else
6439 /* Display table entry is invalid. Return a space. */
6440 it->c = ' ', it->len = 1;
6441
6442 /* Don't change position and object of the iterator here. They are
6443 still the values of the character that had this display table
6444 entry or was translated, and that's what we want. */
6445 it->what = IT_CHARACTER;
6446 return 1;
6447 }
6448
6449
6450 /* Load IT with the next display element from Lisp string IT->string.
6451 IT->current.string_pos is the current position within the string.
6452 If IT->current.overlay_string_index >= 0, the Lisp string is an
6453 overlay string. */
6454
6455 static int
6456 next_element_from_string (it)
6457 struct it *it;
6458 {
6459 struct text_pos position;
6460
6461 xassert (STRINGP (it->string));
6462 xassert (IT_STRING_CHARPOS (*it) >= 0);
6463 position = it->current.string_pos;
6464
6465 /* Time to check for invisible text? */
6466 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6467 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6468 {
6469 handle_stop (it);
6470
6471 /* Since a handler may have changed IT->method, we must
6472 recurse here. */
6473 return GET_NEXT_DISPLAY_ELEMENT (it);
6474 }
6475
6476 if (it->current.overlay_string_index >= 0)
6477 {
6478 /* Get the next character from an overlay string. In overlay
6479 strings, There is no field width or padding with spaces to
6480 do. */
6481 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6482 {
6483 it->what = IT_EOB;
6484 return 0;
6485 }
6486 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6487 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6488 && next_element_from_composition (it))
6489 {
6490 return 1;
6491 }
6492 else if (STRING_MULTIBYTE (it->string))
6493 {
6494 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6495 const unsigned char *s = (SDATA (it->string)
6496 + IT_STRING_BYTEPOS (*it));
6497 it->c = string_char_and_length (s, &it->len);
6498 }
6499 else
6500 {
6501 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6502 it->len = 1;
6503 }
6504 }
6505 else
6506 {
6507 /* Get the next character from a Lisp string that is not an
6508 overlay string. Such strings come from the mode line, for
6509 example. We may have to pad with spaces, or truncate the
6510 string. See also next_element_from_c_string. */
6511 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6512 {
6513 it->what = IT_EOB;
6514 return 0;
6515 }
6516 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6517 {
6518 /* Pad with spaces. */
6519 it->c = ' ', it->len = 1;
6520 CHARPOS (position) = BYTEPOS (position) = -1;
6521 }
6522 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6523 IT_STRING_BYTEPOS (*it), it->string_nchars)
6524 && next_element_from_composition (it))
6525 {
6526 return 1;
6527 }
6528 else if (STRING_MULTIBYTE (it->string))
6529 {
6530 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6531 const unsigned char *s = (SDATA (it->string)
6532 + IT_STRING_BYTEPOS (*it));
6533 it->c = string_char_and_length (s, &it->len);
6534 }
6535 else
6536 {
6537 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6538 it->len = 1;
6539 }
6540 }
6541
6542 /* Record what we have and where it came from. */
6543 it->what = IT_CHARACTER;
6544 it->object = it->string;
6545 it->position = position;
6546 return 1;
6547 }
6548
6549
6550 /* Load IT with next display element from C string IT->s.
6551 IT->string_nchars is the maximum number of characters to return
6552 from the string. IT->end_charpos may be greater than
6553 IT->string_nchars when this function is called, in which case we
6554 may have to return padding spaces. Value is zero if end of string
6555 reached, including padding spaces. */
6556
6557 static int
6558 next_element_from_c_string (it)
6559 struct it *it;
6560 {
6561 int success_p = 1;
6562
6563 xassert (it->s);
6564 it->what = IT_CHARACTER;
6565 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6566 it->object = Qnil;
6567
6568 /* IT's position can be greater IT->string_nchars in case a field
6569 width or precision has been specified when the iterator was
6570 initialized. */
6571 if (IT_CHARPOS (*it) >= it->end_charpos)
6572 {
6573 /* End of the game. */
6574 it->what = IT_EOB;
6575 success_p = 0;
6576 }
6577 else if (IT_CHARPOS (*it) >= it->string_nchars)
6578 {
6579 /* Pad with spaces. */
6580 it->c = ' ', it->len = 1;
6581 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6582 }
6583 else if (it->multibyte_p)
6584 {
6585 /* Implementation note: The calls to strlen apparently aren't a
6586 performance problem because there is no noticeable performance
6587 difference between Emacs running in unibyte or multibyte mode. */
6588 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6589 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6590 }
6591 else
6592 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6593
6594 return success_p;
6595 }
6596
6597
6598 /* Set up IT to return characters from an ellipsis, if appropriate.
6599 The definition of the ellipsis glyphs may come from a display table
6600 entry. This function fills IT with the first glyph from the
6601 ellipsis if an ellipsis is to be displayed. */
6602
6603 static int
6604 next_element_from_ellipsis (it)
6605 struct it *it;
6606 {
6607 if (it->selective_display_ellipsis_p)
6608 setup_for_ellipsis (it, it->len);
6609 else
6610 {
6611 /* The face at the current position may be different from the
6612 face we find after the invisible text. Remember what it
6613 was in IT->saved_face_id, and signal that it's there by
6614 setting face_before_selective_p. */
6615 it->saved_face_id = it->face_id;
6616 it->method = GET_FROM_BUFFER;
6617 it->object = it->w->buffer;
6618 reseat_at_next_visible_line_start (it, 1);
6619 it->face_before_selective_p = 1;
6620 }
6621
6622 return GET_NEXT_DISPLAY_ELEMENT (it);
6623 }
6624
6625
6626 /* Deliver an image display element. The iterator IT is already
6627 filled with image information (done in handle_display_prop). Value
6628 is always 1. */
6629
6630
6631 static int
6632 next_element_from_image (it)
6633 struct it *it;
6634 {
6635 it->what = IT_IMAGE;
6636 return 1;
6637 }
6638
6639
6640 /* Fill iterator IT with next display element from a stretch glyph
6641 property. IT->object is the value of the text property. Value is
6642 always 1. */
6643
6644 static int
6645 next_element_from_stretch (it)
6646 struct it *it;
6647 {
6648 it->what = IT_STRETCH;
6649 return 1;
6650 }
6651
6652 /* Scan forward from CHARPOS in the current buffer, until we find a
6653 stop position > current IT's position. Then handle the stop
6654 position before that. This is called when we bump into a stop
6655 position while reordering bidirectional text. CHARPOS should be
6656 the last previously processed stop_pos (or BEGV, if none were
6657 processed yet) whose position is less that IT's current
6658 position. */
6659
6660 static void
6661 handle_stop_backwards (it, charpos)
6662 struct it *it;
6663 EMACS_INT charpos;
6664 {
6665 EMACS_INT where_we_are = IT_CHARPOS (*it);
6666 struct display_pos save_current = it->current;
6667 struct text_pos save_position = it->position;
6668 struct text_pos pos1;
6669 EMACS_INT next_stop;
6670
6671 /* Scan in strict logical order. */
6672 it->bidi_p = 0;
6673 do
6674 {
6675 it->prev_stop = charpos;
6676 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6677 reseat_1 (it, pos1, 0);
6678 compute_stop_pos (it);
6679 /* We must advance forward, right? */
6680 if (it->stop_charpos <= it->prev_stop)
6681 abort ();
6682 charpos = it->stop_charpos;
6683 }
6684 while (charpos <= where_we_are);
6685
6686 next_stop = it->stop_charpos;
6687 it->stop_charpos = it->prev_stop;
6688 it->bidi_p = 1;
6689 it->current = save_current;
6690 it->position = save_position;
6691 handle_stop (it);
6692 it->stop_charpos = next_stop;
6693 }
6694
6695 /* Load IT with the next display element from current_buffer. Value
6696 is zero if end of buffer reached. IT->stop_charpos is the next
6697 position at which to stop and check for text properties or buffer
6698 end. */
6699
6700 static int
6701 next_element_from_buffer (it)
6702 struct it *it;
6703 {
6704 int success_p = 1;
6705
6706 xassert (IT_CHARPOS (*it) >= BEGV);
6707
6708 /* With bidi reordering, the character to display might not be the
6709 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6710 we were reseat()ed to a new buffer position, which is potentially
6711 a different paragraph. */
6712 if (it->bidi_p && it->bidi_it.first_elt)
6713 {
6714 it->bidi_it.charpos = IT_CHARPOS (*it);
6715 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6716 if (it->bidi_it.bytepos == ZV_BYTE)
6717 {
6718 /* Nothing to do, but reset the FIRST_ELT flag, like
6719 bidi_paragraph_init does, because we are not going to
6720 call it. */
6721 it->bidi_it.first_elt = 0;
6722 }
6723 else if (it->bidi_it.bytepos == BEGV_BYTE
6724 /* FIXME: Should support all Unicode line separators. */
6725 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6726 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6727 {
6728 /* If we are at the beginning of a line, we can produce the
6729 next element right away. */
6730 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6731 bidi_get_next_char_visually (&it->bidi_it);
6732 }
6733 else
6734 {
6735 int orig_bytepos = IT_BYTEPOS (*it);
6736
6737 /* We need to prime the bidi iterator starting at the line's
6738 beginning, before we will be able to produce the next
6739 element. */
6740 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6741 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6742 it->bidi_it.charpos = IT_CHARPOS (*it);
6743 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6744 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6745 do
6746 {
6747 /* Now return to buffer position where we were asked to
6748 get the next display element, and produce that. */
6749 bidi_get_next_char_visually (&it->bidi_it);
6750 }
6751 while (it->bidi_it.bytepos != orig_bytepos
6752 && it->bidi_it.bytepos < ZV_BYTE);
6753 }
6754
6755 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6756 /* Adjust IT's position information to where we ended up. */
6757 IT_CHARPOS (*it) = it->bidi_it.charpos;
6758 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6759 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6760 }
6761
6762 if (IT_CHARPOS (*it) >= it->stop_charpos)
6763 {
6764 if (IT_CHARPOS (*it) >= it->end_charpos)
6765 {
6766 int overlay_strings_follow_p;
6767
6768 /* End of the game, except when overlay strings follow that
6769 haven't been returned yet. */
6770 if (it->overlay_strings_at_end_processed_p)
6771 overlay_strings_follow_p = 0;
6772 else
6773 {
6774 it->overlay_strings_at_end_processed_p = 1;
6775 overlay_strings_follow_p = get_overlay_strings (it, 0);
6776 }
6777
6778 if (overlay_strings_follow_p)
6779 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6780 else
6781 {
6782 it->what = IT_EOB;
6783 it->position = it->current.pos;
6784 success_p = 0;
6785 }
6786 }
6787 else if (!(!it->bidi_p
6788 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6789 || IT_CHARPOS (*it) == it->stop_charpos))
6790 {
6791 /* With bidi non-linear iteration, we could find ourselves
6792 far beyond the last computed stop_charpos, with several
6793 other stop positions in between that we missed. Scan
6794 them all now, in buffer's logical order, until we find
6795 and handle the last stop_charpos that precedes our
6796 current position. */
6797 handle_stop_backwards (it, it->stop_charpos);
6798 return GET_NEXT_DISPLAY_ELEMENT (it);
6799 }
6800 else
6801 {
6802 if (it->bidi_p)
6803 {
6804 /* Take note of the stop position we just moved across,
6805 for when we will move back across it. */
6806 it->prev_stop = it->stop_charpos;
6807 /* If we are at base paragraph embedding level, take
6808 note of the last stop position seen at this
6809 level. */
6810 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6811 it->base_level_stop = it->stop_charpos;
6812 }
6813 handle_stop (it);
6814 return GET_NEXT_DISPLAY_ELEMENT (it);
6815 }
6816 }
6817 else if (it->bidi_p
6818 /* We can sometimes back up for reasons that have nothing
6819 to do with bidi reordering. E.g., compositions. The
6820 code below is only needed when we are above the base
6821 embedding level, so test for that explicitly. */
6822 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6823 && IT_CHARPOS (*it) < it->prev_stop)
6824 {
6825 if (it->base_level_stop <= 0)
6826 it->base_level_stop = BEGV;
6827 if (IT_CHARPOS (*it) < it->base_level_stop)
6828 abort ();
6829 handle_stop_backwards (it, it->base_level_stop);
6830 return GET_NEXT_DISPLAY_ELEMENT (it);
6831 }
6832 else
6833 {
6834 /* No face changes, overlays etc. in sight, so just return a
6835 character from current_buffer. */
6836 unsigned char *p;
6837
6838 /* Maybe run the redisplay end trigger hook. Performance note:
6839 This doesn't seem to cost measurable time. */
6840 if (it->redisplay_end_trigger_charpos
6841 && it->glyph_row
6842 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6843 run_redisplay_end_trigger_hook (it);
6844
6845 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6846 it->end_charpos)
6847 && next_element_from_composition (it))
6848 {
6849 return 1;
6850 }
6851
6852 /* Get the next character, maybe multibyte. */
6853 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6854 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6855 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6856 else
6857 it->c = *p, it->len = 1;
6858
6859 /* Record what we have and where it came from. */
6860 it->what = IT_CHARACTER;
6861 it->object = it->w->buffer;
6862 it->position = it->current.pos;
6863
6864 /* Normally we return the character found above, except when we
6865 really want to return an ellipsis for selective display. */
6866 if (it->selective)
6867 {
6868 if (it->c == '\n')
6869 {
6870 /* A value of selective > 0 means hide lines indented more
6871 than that number of columns. */
6872 if (it->selective > 0
6873 && IT_CHARPOS (*it) + 1 < ZV
6874 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6875 IT_BYTEPOS (*it) + 1,
6876 (double) it->selective)) /* iftc */
6877 {
6878 success_p = next_element_from_ellipsis (it);
6879 it->dpvec_char_len = -1;
6880 }
6881 }
6882 else if (it->c == '\r' && it->selective == -1)
6883 {
6884 /* A value of selective == -1 means that everything from the
6885 CR to the end of the line is invisible, with maybe an
6886 ellipsis displayed for it. */
6887 success_p = next_element_from_ellipsis (it);
6888 it->dpvec_char_len = -1;
6889 }
6890 }
6891 }
6892
6893 /* Value is zero if end of buffer reached. */
6894 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6895 return success_p;
6896 }
6897
6898
6899 /* Run the redisplay end trigger hook for IT. */
6900
6901 static void
6902 run_redisplay_end_trigger_hook (it)
6903 struct it *it;
6904 {
6905 Lisp_Object args[3];
6906
6907 /* IT->glyph_row should be non-null, i.e. we should be actually
6908 displaying something, or otherwise we should not run the hook. */
6909 xassert (it->glyph_row);
6910
6911 /* Set up hook arguments. */
6912 args[0] = Qredisplay_end_trigger_functions;
6913 args[1] = it->window;
6914 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6915 it->redisplay_end_trigger_charpos = 0;
6916
6917 /* Since we are *trying* to run these functions, don't try to run
6918 them again, even if they get an error. */
6919 it->w->redisplay_end_trigger = Qnil;
6920 Frun_hook_with_args (3, args);
6921
6922 /* Notice if it changed the face of the character we are on. */
6923 handle_face_prop (it);
6924 }
6925
6926
6927 /* Deliver a composition display element. Unlike the other
6928 next_element_from_XXX, this function is not registered in the array
6929 get_next_element[]. It is called from next_element_from_buffer and
6930 next_element_from_string when necessary. */
6931
6932 static int
6933 next_element_from_composition (it)
6934 struct it *it;
6935 {
6936 it->what = IT_COMPOSITION;
6937 it->len = it->cmp_it.nbytes;
6938 if (STRINGP (it->string))
6939 {
6940 if (it->c < 0)
6941 {
6942 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6943 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6944 return 0;
6945 }
6946 it->position = it->current.string_pos;
6947 it->object = it->string;
6948 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6949 IT_STRING_BYTEPOS (*it), it->string);
6950 }
6951 else
6952 {
6953 if (it->c < 0)
6954 {
6955 IT_CHARPOS (*it) += it->cmp_it.nchars;
6956 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6957 return 0;
6958 }
6959 it->position = it->current.pos;
6960 it->object = it->w->buffer;
6961 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6962 IT_BYTEPOS (*it), Qnil);
6963 }
6964 return 1;
6965 }
6966
6967
6968 \f
6969 /***********************************************************************
6970 Moving an iterator without producing glyphs
6971 ***********************************************************************/
6972
6973 /* Check if iterator is at a position corresponding to a valid buffer
6974 position after some move_it_ call. */
6975
6976 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6977 ((it)->method == GET_FROM_STRING \
6978 ? IT_STRING_CHARPOS (*it) == 0 \
6979 : 1)
6980
6981
6982 /* Move iterator IT to a specified buffer or X position within one
6983 line on the display without producing glyphs.
6984
6985 OP should be a bit mask including some or all of these bits:
6986 MOVE_TO_X: Stop upon reaching x-position TO_X.
6987 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6988 Regardless of OP's value, stop upon reaching the end of the display line.
6989
6990 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6991 This means, in particular, that TO_X includes window's horizontal
6992 scroll amount.
6993
6994 The return value has several possible values that
6995 say what condition caused the scan to stop:
6996
6997 MOVE_POS_MATCH_OR_ZV
6998 - when TO_POS or ZV was reached.
6999
7000 MOVE_X_REACHED
7001 -when TO_X was reached before TO_POS or ZV were reached.
7002
7003 MOVE_LINE_CONTINUED
7004 - when we reached the end of the display area and the line must
7005 be continued.
7006
7007 MOVE_LINE_TRUNCATED
7008 - when we reached the end of the display area and the line is
7009 truncated.
7010
7011 MOVE_NEWLINE_OR_CR
7012 - when we stopped at a line end, i.e. a newline or a CR and selective
7013 display is on. */
7014
7015 static enum move_it_result
7016 move_it_in_display_line_to (struct it *it,
7017 EMACS_INT to_charpos, int to_x,
7018 enum move_operation_enum op)
7019 {
7020 enum move_it_result result = MOVE_UNDEFINED;
7021 struct glyph_row *saved_glyph_row;
7022 struct it wrap_it, atpos_it, atx_it;
7023 int may_wrap = 0;
7024 enum it_method prev_method = it->method;
7025 EMACS_INT prev_pos = IT_CHARPOS (*it);
7026
7027 /* Don't produce glyphs in produce_glyphs. */
7028 saved_glyph_row = it->glyph_row;
7029 it->glyph_row = NULL;
7030
7031 /* Use wrap_it to save a copy of IT wherever a word wrap could
7032 occur. Use atpos_it to save a copy of IT at the desired buffer
7033 position, if found, so that we can scan ahead and check if the
7034 word later overshoots the window edge. Use atx_it similarly, for
7035 pixel positions. */
7036 wrap_it.sp = -1;
7037 atpos_it.sp = -1;
7038 atx_it.sp = -1;
7039
7040 #define BUFFER_POS_REACHED_P() \
7041 ((op & MOVE_TO_POS) != 0 \
7042 && BUFFERP (it->object) \
7043 && (IT_CHARPOS (*it) == to_charpos \
7044 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7045 && (it->method == GET_FROM_BUFFER \
7046 || (it->method == GET_FROM_DISPLAY_VECTOR \
7047 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7048
7049 /* If there's a line-/wrap-prefix, handle it. */
7050 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7051 && it->current_y < it->last_visible_y)
7052 handle_line_prefix (it);
7053
7054 while (1)
7055 {
7056 int x, i, ascent = 0, descent = 0;
7057
7058 /* Utility macro to reset an iterator with x, ascent, and descent. */
7059 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7060 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7061 (IT)->max_descent = descent)
7062
7063 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7064 glyph). */
7065 if ((op & MOVE_TO_POS) != 0
7066 && BUFFERP (it->object)
7067 && it->method == GET_FROM_BUFFER
7068 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7069 || (it->bidi_p
7070 && (prev_method == GET_FROM_IMAGE
7071 || prev_method == GET_FROM_STRETCH)
7072 /* Passed TO_CHARPOS from left to right. */
7073 && ((prev_pos < to_charpos
7074 && IT_CHARPOS (*it) > to_charpos)
7075 /* Passed TO_CHARPOS from right to left. */
7076 || (prev_pos > to_charpos
7077 && IT_CHARPOS (*it) < to_charpos)))))
7078 {
7079 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7080 {
7081 result = MOVE_POS_MATCH_OR_ZV;
7082 break;
7083 }
7084 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7085 /* If wrap_it is valid, the current position might be in a
7086 word that is wrapped. So, save the iterator in
7087 atpos_it and continue to see if wrapping happens. */
7088 atpos_it = *it;
7089 }
7090
7091 prev_method = it->method;
7092 if (it->method == GET_FROM_BUFFER)
7093 prev_pos = IT_CHARPOS (*it);
7094 /* Stop when ZV reached.
7095 We used to stop here when TO_CHARPOS reached as well, but that is
7096 too soon if this glyph does not fit on this line. So we handle it
7097 explicitly below. */
7098 if (!get_next_display_element (it))
7099 {
7100 result = MOVE_POS_MATCH_OR_ZV;
7101 break;
7102 }
7103
7104 if (it->line_wrap == TRUNCATE)
7105 {
7106 if (BUFFER_POS_REACHED_P ())
7107 {
7108 result = MOVE_POS_MATCH_OR_ZV;
7109 break;
7110 }
7111 }
7112 else
7113 {
7114 if (it->line_wrap == WORD_WRAP)
7115 {
7116 if (IT_DISPLAYING_WHITESPACE (it))
7117 may_wrap = 1;
7118 else if (may_wrap)
7119 {
7120 /* We have reached a glyph that follows one or more
7121 whitespace characters. If the position is
7122 already found, we are done. */
7123 if (atpos_it.sp >= 0)
7124 {
7125 *it = atpos_it;
7126 result = MOVE_POS_MATCH_OR_ZV;
7127 goto done;
7128 }
7129 if (atx_it.sp >= 0)
7130 {
7131 *it = atx_it;
7132 result = MOVE_X_REACHED;
7133 goto done;
7134 }
7135 /* Otherwise, we can wrap here. */
7136 wrap_it = *it;
7137 may_wrap = 0;
7138 }
7139 }
7140 }
7141
7142 /* Remember the line height for the current line, in case
7143 the next element doesn't fit on the line. */
7144 ascent = it->max_ascent;
7145 descent = it->max_descent;
7146
7147 /* The call to produce_glyphs will get the metrics of the
7148 display element IT is loaded with. Record the x-position
7149 before this display element, in case it doesn't fit on the
7150 line. */
7151 x = it->current_x;
7152
7153 PRODUCE_GLYPHS (it);
7154
7155 if (it->area != TEXT_AREA)
7156 {
7157 set_iterator_to_next (it, 1);
7158 continue;
7159 }
7160
7161 /* The number of glyphs we get back in IT->nglyphs will normally
7162 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7163 character on a terminal frame, or (iii) a line end. For the
7164 second case, IT->nglyphs - 1 padding glyphs will be present.
7165 (On X frames, there is only one glyph produced for a
7166 composite character.)
7167
7168 The behavior implemented below means, for continuation lines,
7169 that as many spaces of a TAB as fit on the current line are
7170 displayed there. For terminal frames, as many glyphs of a
7171 multi-glyph character are displayed in the current line, too.
7172 This is what the old redisplay code did, and we keep it that
7173 way. Under X, the whole shape of a complex character must
7174 fit on the line or it will be completely displayed in the
7175 next line.
7176
7177 Note that both for tabs and padding glyphs, all glyphs have
7178 the same width. */
7179 if (it->nglyphs)
7180 {
7181 /* More than one glyph or glyph doesn't fit on line. All
7182 glyphs have the same width. */
7183 int single_glyph_width = it->pixel_width / it->nglyphs;
7184 int new_x;
7185 int x_before_this_char = x;
7186 int hpos_before_this_char = it->hpos;
7187
7188 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7189 {
7190 new_x = x + single_glyph_width;
7191
7192 /* We want to leave anything reaching TO_X to the caller. */
7193 if ((op & MOVE_TO_X) && new_x > to_x)
7194 {
7195 if (BUFFER_POS_REACHED_P ())
7196 {
7197 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7198 goto buffer_pos_reached;
7199 if (atpos_it.sp < 0)
7200 {
7201 atpos_it = *it;
7202 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7203 }
7204 }
7205 else
7206 {
7207 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7208 {
7209 it->current_x = x;
7210 result = MOVE_X_REACHED;
7211 break;
7212 }
7213 if (atx_it.sp < 0)
7214 {
7215 atx_it = *it;
7216 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7217 }
7218 }
7219 }
7220
7221 if (/* Lines are continued. */
7222 it->line_wrap != TRUNCATE
7223 && (/* And glyph doesn't fit on the line. */
7224 new_x > it->last_visible_x
7225 /* Or it fits exactly and we're on a window
7226 system frame. */
7227 || (new_x == it->last_visible_x
7228 && FRAME_WINDOW_P (it->f))))
7229 {
7230 if (/* IT->hpos == 0 means the very first glyph
7231 doesn't fit on the line, e.g. a wide image. */
7232 it->hpos == 0
7233 || (new_x == it->last_visible_x
7234 && FRAME_WINDOW_P (it->f)))
7235 {
7236 ++it->hpos;
7237 it->current_x = new_x;
7238
7239 /* The character's last glyph just barely fits
7240 in this row. */
7241 if (i == it->nglyphs - 1)
7242 {
7243 /* If this is the destination position,
7244 return a position *before* it in this row,
7245 now that we know it fits in this row. */
7246 if (BUFFER_POS_REACHED_P ())
7247 {
7248 if (it->line_wrap != WORD_WRAP
7249 || wrap_it.sp < 0)
7250 {
7251 it->hpos = hpos_before_this_char;
7252 it->current_x = x_before_this_char;
7253 result = MOVE_POS_MATCH_OR_ZV;
7254 break;
7255 }
7256 if (it->line_wrap == WORD_WRAP
7257 && atpos_it.sp < 0)
7258 {
7259 atpos_it = *it;
7260 atpos_it.current_x = x_before_this_char;
7261 atpos_it.hpos = hpos_before_this_char;
7262 }
7263 }
7264
7265 set_iterator_to_next (it, 1);
7266 /* On graphical terminals, newlines may
7267 "overflow" into the fringe if
7268 overflow-newline-into-fringe is non-nil.
7269 On text-only terminals, newlines may
7270 overflow into the last glyph on the
7271 display line.*/
7272 if (!FRAME_WINDOW_P (it->f)
7273 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7274 {
7275 if (!get_next_display_element (it))
7276 {
7277 result = MOVE_POS_MATCH_OR_ZV;
7278 break;
7279 }
7280 if (BUFFER_POS_REACHED_P ())
7281 {
7282 if (ITERATOR_AT_END_OF_LINE_P (it))
7283 result = MOVE_POS_MATCH_OR_ZV;
7284 else
7285 result = MOVE_LINE_CONTINUED;
7286 break;
7287 }
7288 if (ITERATOR_AT_END_OF_LINE_P (it))
7289 {
7290 result = MOVE_NEWLINE_OR_CR;
7291 break;
7292 }
7293 }
7294 }
7295 }
7296 else
7297 IT_RESET_X_ASCENT_DESCENT (it);
7298
7299 if (wrap_it.sp >= 0)
7300 {
7301 *it = wrap_it;
7302 atpos_it.sp = -1;
7303 atx_it.sp = -1;
7304 }
7305
7306 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7307 IT_CHARPOS (*it)));
7308 result = MOVE_LINE_CONTINUED;
7309 break;
7310 }
7311
7312 if (BUFFER_POS_REACHED_P ())
7313 {
7314 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7315 goto buffer_pos_reached;
7316 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7317 {
7318 atpos_it = *it;
7319 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7320 }
7321 }
7322
7323 if (new_x > it->first_visible_x)
7324 {
7325 /* Glyph is visible. Increment number of glyphs that
7326 would be displayed. */
7327 ++it->hpos;
7328 }
7329 }
7330
7331 if (result != MOVE_UNDEFINED)
7332 break;
7333 }
7334 else if (BUFFER_POS_REACHED_P ())
7335 {
7336 buffer_pos_reached:
7337 IT_RESET_X_ASCENT_DESCENT (it);
7338 result = MOVE_POS_MATCH_OR_ZV;
7339 break;
7340 }
7341 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7342 {
7343 /* Stop when TO_X specified and reached. This check is
7344 necessary here because of lines consisting of a line end,
7345 only. The line end will not produce any glyphs and we
7346 would never get MOVE_X_REACHED. */
7347 xassert (it->nglyphs == 0);
7348 result = MOVE_X_REACHED;
7349 break;
7350 }
7351
7352 /* Is this a line end? If yes, we're done. */
7353 if (ITERATOR_AT_END_OF_LINE_P (it))
7354 {
7355 result = MOVE_NEWLINE_OR_CR;
7356 break;
7357 }
7358
7359 if (it->method == GET_FROM_BUFFER)
7360 prev_pos = IT_CHARPOS (*it);
7361 /* The current display element has been consumed. Advance
7362 to the next. */
7363 set_iterator_to_next (it, 1);
7364
7365 /* Stop if lines are truncated and IT's current x-position is
7366 past the right edge of the window now. */
7367 if (it->line_wrap == TRUNCATE
7368 && it->current_x >= it->last_visible_x)
7369 {
7370 if (!FRAME_WINDOW_P (it->f)
7371 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7372 {
7373 if (!get_next_display_element (it)
7374 || BUFFER_POS_REACHED_P ())
7375 {
7376 result = MOVE_POS_MATCH_OR_ZV;
7377 break;
7378 }
7379 if (ITERATOR_AT_END_OF_LINE_P (it))
7380 {
7381 result = MOVE_NEWLINE_OR_CR;
7382 break;
7383 }
7384 }
7385 result = MOVE_LINE_TRUNCATED;
7386 break;
7387 }
7388 #undef IT_RESET_X_ASCENT_DESCENT
7389 }
7390
7391 #undef BUFFER_POS_REACHED_P
7392
7393 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7394 restore the saved iterator. */
7395 if (atpos_it.sp >= 0)
7396 *it = atpos_it;
7397 else if (atx_it.sp >= 0)
7398 *it = atx_it;
7399
7400 done:
7401
7402 /* Restore the iterator settings altered at the beginning of this
7403 function. */
7404 it->glyph_row = saved_glyph_row;
7405 return result;
7406 }
7407
7408 /* For external use. */
7409 void
7410 move_it_in_display_line (struct it *it,
7411 EMACS_INT to_charpos, int to_x,
7412 enum move_operation_enum op)
7413 {
7414 if (it->line_wrap == WORD_WRAP
7415 && (op & MOVE_TO_X))
7416 {
7417 struct it save_it = *it;
7418 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7419 /* When word-wrap is on, TO_X may lie past the end
7420 of a wrapped line. Then it->current is the
7421 character on the next line, so backtrack to the
7422 space before the wrap point. */
7423 if (skip == MOVE_LINE_CONTINUED)
7424 {
7425 int prev_x = max (it->current_x - 1, 0);
7426 *it = save_it;
7427 move_it_in_display_line_to
7428 (it, -1, prev_x, MOVE_TO_X);
7429 }
7430 }
7431 else
7432 move_it_in_display_line_to (it, to_charpos, to_x, op);
7433 }
7434
7435
7436 /* Move IT forward until it satisfies one or more of the criteria in
7437 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7438
7439 OP is a bit-mask that specifies where to stop, and in particular,
7440 which of those four position arguments makes a difference. See the
7441 description of enum move_operation_enum.
7442
7443 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7444 screen line, this function will set IT to the next position >
7445 TO_CHARPOS. */
7446
7447 void
7448 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
7449 struct it *it;
7450 int to_charpos, to_x, to_y, to_vpos;
7451 int op;
7452 {
7453 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7454 int line_height, line_start_x = 0, reached = 0;
7455
7456 for (;;)
7457 {
7458 if (op & MOVE_TO_VPOS)
7459 {
7460 /* If no TO_CHARPOS and no TO_X specified, stop at the
7461 start of the line TO_VPOS. */
7462 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7463 {
7464 if (it->vpos == to_vpos)
7465 {
7466 reached = 1;
7467 break;
7468 }
7469 else
7470 skip = move_it_in_display_line_to (it, -1, -1, 0);
7471 }
7472 else
7473 {
7474 /* TO_VPOS >= 0 means stop at TO_X in the line at
7475 TO_VPOS, or at TO_POS, whichever comes first. */
7476 if (it->vpos == to_vpos)
7477 {
7478 reached = 2;
7479 break;
7480 }
7481
7482 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7483
7484 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7485 {
7486 reached = 3;
7487 break;
7488 }
7489 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7490 {
7491 /* We have reached TO_X but not in the line we want. */
7492 skip = move_it_in_display_line_to (it, to_charpos,
7493 -1, MOVE_TO_POS);
7494 if (skip == MOVE_POS_MATCH_OR_ZV)
7495 {
7496 reached = 4;
7497 break;
7498 }
7499 }
7500 }
7501 }
7502 else if (op & MOVE_TO_Y)
7503 {
7504 struct it it_backup;
7505
7506 if (it->line_wrap == WORD_WRAP)
7507 it_backup = *it;
7508
7509 /* TO_Y specified means stop at TO_X in the line containing
7510 TO_Y---or at TO_CHARPOS if this is reached first. The
7511 problem is that we can't really tell whether the line
7512 contains TO_Y before we have completely scanned it, and
7513 this may skip past TO_X. What we do is to first scan to
7514 TO_X.
7515
7516 If TO_X is not specified, use a TO_X of zero. The reason
7517 is to make the outcome of this function more predictable.
7518 If we didn't use TO_X == 0, we would stop at the end of
7519 the line which is probably not what a caller would expect
7520 to happen. */
7521 skip = move_it_in_display_line_to
7522 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7523 (MOVE_TO_X | (op & MOVE_TO_POS)));
7524
7525 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7526 if (skip == MOVE_POS_MATCH_OR_ZV)
7527 reached = 5;
7528 else if (skip == MOVE_X_REACHED)
7529 {
7530 /* If TO_X was reached, we want to know whether TO_Y is
7531 in the line. We know this is the case if the already
7532 scanned glyphs make the line tall enough. Otherwise,
7533 we must check by scanning the rest of the line. */
7534 line_height = it->max_ascent + it->max_descent;
7535 if (to_y >= it->current_y
7536 && to_y < it->current_y + line_height)
7537 {
7538 reached = 6;
7539 break;
7540 }
7541 it_backup = *it;
7542 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7543 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7544 op & MOVE_TO_POS);
7545 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7546 line_height = it->max_ascent + it->max_descent;
7547 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7548
7549 if (to_y >= it->current_y
7550 && to_y < it->current_y + line_height)
7551 {
7552 /* If TO_Y is in this line and TO_X was reached
7553 above, we scanned too far. We have to restore
7554 IT's settings to the ones before skipping. */
7555 *it = it_backup;
7556 reached = 6;
7557 }
7558 else
7559 {
7560 skip = skip2;
7561 if (skip == MOVE_POS_MATCH_OR_ZV)
7562 reached = 7;
7563 }
7564 }
7565 else
7566 {
7567 /* Check whether TO_Y is in this line. */
7568 line_height = it->max_ascent + it->max_descent;
7569 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7570
7571 if (to_y >= it->current_y
7572 && to_y < it->current_y + line_height)
7573 {
7574 /* When word-wrap is on, TO_X may lie past the end
7575 of a wrapped line. Then it->current is the
7576 character on the next line, so backtrack to the
7577 space before the wrap point. */
7578 if (skip == MOVE_LINE_CONTINUED
7579 && it->line_wrap == WORD_WRAP)
7580 {
7581 int prev_x = max (it->current_x - 1, 0);
7582 *it = it_backup;
7583 skip = move_it_in_display_line_to
7584 (it, -1, prev_x, MOVE_TO_X);
7585 }
7586 reached = 6;
7587 }
7588 }
7589
7590 if (reached)
7591 break;
7592 }
7593 else if (BUFFERP (it->object)
7594 && (it->method == GET_FROM_BUFFER
7595 || it->method == GET_FROM_STRETCH)
7596 && IT_CHARPOS (*it) >= to_charpos)
7597 skip = MOVE_POS_MATCH_OR_ZV;
7598 else
7599 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7600
7601 switch (skip)
7602 {
7603 case MOVE_POS_MATCH_OR_ZV:
7604 reached = 8;
7605 goto out;
7606
7607 case MOVE_NEWLINE_OR_CR:
7608 set_iterator_to_next (it, 1);
7609 it->continuation_lines_width = 0;
7610 break;
7611
7612 case MOVE_LINE_TRUNCATED:
7613 it->continuation_lines_width = 0;
7614 reseat_at_next_visible_line_start (it, 0);
7615 if ((op & MOVE_TO_POS) != 0
7616 && IT_CHARPOS (*it) > to_charpos)
7617 {
7618 reached = 9;
7619 goto out;
7620 }
7621 break;
7622
7623 case MOVE_LINE_CONTINUED:
7624 /* For continued lines ending in a tab, some of the glyphs
7625 associated with the tab are displayed on the current
7626 line. Since it->current_x does not include these glyphs,
7627 we use it->last_visible_x instead. */
7628 if (it->c == '\t')
7629 {
7630 it->continuation_lines_width += it->last_visible_x;
7631 /* When moving by vpos, ensure that the iterator really
7632 advances to the next line (bug#847, bug#969). Fixme:
7633 do we need to do this in other circumstances? */
7634 if (it->current_x != it->last_visible_x
7635 && (op & MOVE_TO_VPOS)
7636 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7637 {
7638 line_start_x = it->current_x + it->pixel_width
7639 - it->last_visible_x;
7640 set_iterator_to_next (it, 0);
7641 }
7642 }
7643 else
7644 it->continuation_lines_width += it->current_x;
7645 break;
7646
7647 default:
7648 abort ();
7649 }
7650
7651 /* Reset/increment for the next run. */
7652 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7653 it->current_x = line_start_x;
7654 line_start_x = 0;
7655 it->hpos = 0;
7656 it->current_y += it->max_ascent + it->max_descent;
7657 ++it->vpos;
7658 last_height = it->max_ascent + it->max_descent;
7659 last_max_ascent = it->max_ascent;
7660 it->max_ascent = it->max_descent = 0;
7661 }
7662
7663 out:
7664
7665 /* On text terminals, we may stop at the end of a line in the middle
7666 of a multi-character glyph. If the glyph itself is continued,
7667 i.e. it is actually displayed on the next line, don't treat this
7668 stopping point as valid; move to the next line instead (unless
7669 that brings us offscreen). */
7670 if (!FRAME_WINDOW_P (it->f)
7671 && op & MOVE_TO_POS
7672 && IT_CHARPOS (*it) == to_charpos
7673 && it->what == IT_CHARACTER
7674 && it->nglyphs > 1
7675 && it->line_wrap == WINDOW_WRAP
7676 && it->current_x == it->last_visible_x - 1
7677 && it->c != '\n'
7678 && it->c != '\t'
7679 && it->vpos < XFASTINT (it->w->window_end_vpos))
7680 {
7681 it->continuation_lines_width += it->current_x;
7682 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7683 it->current_y += it->max_ascent + it->max_descent;
7684 ++it->vpos;
7685 last_height = it->max_ascent + it->max_descent;
7686 last_max_ascent = it->max_ascent;
7687 }
7688
7689 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7690 }
7691
7692
7693 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7694
7695 If DY > 0, move IT backward at least that many pixels. DY = 0
7696 means move IT backward to the preceding line start or BEGV. This
7697 function may move over more than DY pixels if IT->current_y - DY
7698 ends up in the middle of a line; in this case IT->current_y will be
7699 set to the top of the line moved to. */
7700
7701 void
7702 move_it_vertically_backward (it, dy)
7703 struct it *it;
7704 int dy;
7705 {
7706 int nlines, h;
7707 struct it it2, it3;
7708 int start_pos;
7709
7710 move_further_back:
7711 xassert (dy >= 0);
7712
7713 start_pos = IT_CHARPOS (*it);
7714
7715 /* Estimate how many newlines we must move back. */
7716 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7717
7718 /* Set the iterator's position that many lines back. */
7719 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7720 back_to_previous_visible_line_start (it);
7721
7722 /* Reseat the iterator here. When moving backward, we don't want
7723 reseat to skip forward over invisible text, set up the iterator
7724 to deliver from overlay strings at the new position etc. So,
7725 use reseat_1 here. */
7726 reseat_1 (it, it->current.pos, 1);
7727
7728 /* We are now surely at a line start. */
7729 it->current_x = it->hpos = 0;
7730 it->continuation_lines_width = 0;
7731
7732 /* Move forward and see what y-distance we moved. First move to the
7733 start of the next line so that we get its height. We need this
7734 height to be able to tell whether we reached the specified
7735 y-distance. */
7736 it2 = *it;
7737 it2.max_ascent = it2.max_descent = 0;
7738 do
7739 {
7740 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7741 MOVE_TO_POS | MOVE_TO_VPOS);
7742 }
7743 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7744 xassert (IT_CHARPOS (*it) >= BEGV);
7745 it3 = it2;
7746
7747 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7748 xassert (IT_CHARPOS (*it) >= BEGV);
7749 /* H is the actual vertical distance from the position in *IT
7750 and the starting position. */
7751 h = it2.current_y - it->current_y;
7752 /* NLINES is the distance in number of lines. */
7753 nlines = it2.vpos - it->vpos;
7754
7755 /* Correct IT's y and vpos position
7756 so that they are relative to the starting point. */
7757 it->vpos -= nlines;
7758 it->current_y -= h;
7759
7760 if (dy == 0)
7761 {
7762 /* DY == 0 means move to the start of the screen line. The
7763 value of nlines is > 0 if continuation lines were involved. */
7764 if (nlines > 0)
7765 move_it_by_lines (it, nlines, 1);
7766 }
7767 else
7768 {
7769 /* The y-position we try to reach, relative to *IT.
7770 Note that H has been subtracted in front of the if-statement. */
7771 int target_y = it->current_y + h - dy;
7772 int y0 = it3.current_y;
7773 int y1 = line_bottom_y (&it3);
7774 int line_height = y1 - y0;
7775
7776 /* If we did not reach target_y, try to move further backward if
7777 we can. If we moved too far backward, try to move forward. */
7778 if (target_y < it->current_y
7779 /* This is heuristic. In a window that's 3 lines high, with
7780 a line height of 13 pixels each, recentering with point
7781 on the bottom line will try to move -39/2 = 19 pixels
7782 backward. Try to avoid moving into the first line. */
7783 && (it->current_y - target_y
7784 > min (window_box_height (it->w), line_height * 2 / 3))
7785 && IT_CHARPOS (*it) > BEGV)
7786 {
7787 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7788 target_y - it->current_y));
7789 dy = it->current_y - target_y;
7790 goto move_further_back;
7791 }
7792 else if (target_y >= it->current_y + line_height
7793 && IT_CHARPOS (*it) < ZV)
7794 {
7795 /* Should move forward by at least one line, maybe more.
7796
7797 Note: Calling move_it_by_lines can be expensive on
7798 terminal frames, where compute_motion is used (via
7799 vmotion) to do the job, when there are very long lines
7800 and truncate-lines is nil. That's the reason for
7801 treating terminal frames specially here. */
7802
7803 if (!FRAME_WINDOW_P (it->f))
7804 move_it_vertically (it, target_y - (it->current_y + line_height));
7805 else
7806 {
7807 do
7808 {
7809 move_it_by_lines (it, 1, 1);
7810 }
7811 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7812 }
7813 }
7814 }
7815 }
7816
7817
7818 /* Move IT by a specified amount of pixel lines DY. DY negative means
7819 move backwards. DY = 0 means move to start of screen line. At the
7820 end, IT will be on the start of a screen line. */
7821
7822 void
7823 move_it_vertically (it, dy)
7824 struct it *it;
7825 int dy;
7826 {
7827 if (dy <= 0)
7828 move_it_vertically_backward (it, -dy);
7829 else
7830 {
7831 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7832 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7833 MOVE_TO_POS | MOVE_TO_Y);
7834 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7835
7836 /* If buffer ends in ZV without a newline, move to the start of
7837 the line to satisfy the post-condition. */
7838 if (IT_CHARPOS (*it) == ZV
7839 && ZV > BEGV
7840 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7841 move_it_by_lines (it, 0, 0);
7842 }
7843 }
7844
7845
7846 /* Move iterator IT past the end of the text line it is in. */
7847
7848 void
7849 move_it_past_eol (it)
7850 struct it *it;
7851 {
7852 enum move_it_result rc;
7853
7854 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7855 if (rc == MOVE_NEWLINE_OR_CR)
7856 set_iterator_to_next (it, 0);
7857 }
7858
7859
7860 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7861 negative means move up. DVPOS == 0 means move to the start of the
7862 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7863 NEED_Y_P is zero, IT->current_y will be left unchanged.
7864
7865 Further optimization ideas: If we would know that IT->f doesn't use
7866 a face with proportional font, we could be faster for
7867 truncate-lines nil. */
7868
7869 void
7870 move_it_by_lines (it, dvpos, need_y_p)
7871 struct it *it;
7872 int dvpos, need_y_p;
7873 {
7874 struct position pos;
7875
7876 /* The commented-out optimization uses vmotion on terminals. This
7877 gives bad results, because elements like it->what, on which
7878 callers such as pos_visible_p rely, aren't updated. */
7879 /* if (!FRAME_WINDOW_P (it->f))
7880 {
7881 struct text_pos textpos;
7882
7883 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7884 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7885 reseat (it, textpos, 1);
7886 it->vpos += pos.vpos;
7887 it->current_y += pos.vpos;
7888 }
7889 else */
7890
7891 if (dvpos == 0)
7892 {
7893 /* DVPOS == 0 means move to the start of the screen line. */
7894 move_it_vertically_backward (it, 0);
7895 xassert (it->current_x == 0 && it->hpos == 0);
7896 /* Let next call to line_bottom_y calculate real line height */
7897 last_height = 0;
7898 }
7899 else if (dvpos > 0)
7900 {
7901 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7902 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7903 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7904 }
7905 else
7906 {
7907 struct it it2;
7908 int start_charpos, i;
7909
7910 /* Start at the beginning of the screen line containing IT's
7911 position. This may actually move vertically backwards,
7912 in case of overlays, so adjust dvpos accordingly. */
7913 dvpos += it->vpos;
7914 move_it_vertically_backward (it, 0);
7915 dvpos -= it->vpos;
7916
7917 /* Go back -DVPOS visible lines and reseat the iterator there. */
7918 start_charpos = IT_CHARPOS (*it);
7919 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7920 back_to_previous_visible_line_start (it);
7921 reseat (it, it->current.pos, 1);
7922
7923 /* Move further back if we end up in a string or an image. */
7924 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7925 {
7926 /* First try to move to start of display line. */
7927 dvpos += it->vpos;
7928 move_it_vertically_backward (it, 0);
7929 dvpos -= it->vpos;
7930 if (IT_POS_VALID_AFTER_MOVE_P (it))
7931 break;
7932 /* If start of line is still in string or image,
7933 move further back. */
7934 back_to_previous_visible_line_start (it);
7935 reseat (it, it->current.pos, 1);
7936 dvpos--;
7937 }
7938
7939 it->current_x = it->hpos = 0;
7940
7941 /* Above call may have moved too far if continuation lines
7942 are involved. Scan forward and see if it did. */
7943 it2 = *it;
7944 it2.vpos = it2.current_y = 0;
7945 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7946 it->vpos -= it2.vpos;
7947 it->current_y -= it2.current_y;
7948 it->current_x = it->hpos = 0;
7949
7950 /* If we moved too far back, move IT some lines forward. */
7951 if (it2.vpos > -dvpos)
7952 {
7953 int delta = it2.vpos + dvpos;
7954 it2 = *it;
7955 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7956 /* Move back again if we got too far ahead. */
7957 if (IT_CHARPOS (*it) >= start_charpos)
7958 *it = it2;
7959 }
7960 }
7961 }
7962
7963 /* Return 1 if IT points into the middle of a display vector. */
7964
7965 int
7966 in_display_vector_p (it)
7967 struct it *it;
7968 {
7969 return (it->method == GET_FROM_DISPLAY_VECTOR
7970 && it->current.dpvec_index > 0
7971 && it->dpvec + it->current.dpvec_index != it->dpend);
7972 }
7973
7974 \f
7975 /***********************************************************************
7976 Messages
7977 ***********************************************************************/
7978
7979
7980 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7981 to *Messages*. */
7982
7983 void
7984 add_to_log (format, arg1, arg2)
7985 char *format;
7986 Lisp_Object arg1, arg2;
7987 {
7988 Lisp_Object args[3];
7989 Lisp_Object msg, fmt;
7990 char *buffer;
7991 int len;
7992 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7993 USE_SAFE_ALLOCA;
7994
7995 /* Do nothing if called asynchronously. Inserting text into
7996 a buffer may call after-change-functions and alike and
7997 that would means running Lisp asynchronously. */
7998 if (handling_signal)
7999 return;
8000
8001 fmt = msg = Qnil;
8002 GCPRO4 (fmt, msg, arg1, arg2);
8003
8004 args[0] = fmt = build_string (format);
8005 args[1] = arg1;
8006 args[2] = arg2;
8007 msg = Fformat (3, args);
8008
8009 len = SBYTES (msg) + 1;
8010 SAFE_ALLOCA (buffer, char *, len);
8011 bcopy (SDATA (msg), buffer, len);
8012
8013 message_dolog (buffer, len - 1, 1, 0);
8014 SAFE_FREE ();
8015
8016 UNGCPRO;
8017 }
8018
8019
8020 /* Output a newline in the *Messages* buffer if "needs" one. */
8021
8022 void
8023 message_log_maybe_newline ()
8024 {
8025 if (message_log_need_newline)
8026 message_dolog ("", 0, 1, 0);
8027 }
8028
8029
8030 /* Add a string M of length NBYTES to the message log, optionally
8031 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8032 nonzero, means interpret the contents of M as multibyte. This
8033 function calls low-level routines in order to bypass text property
8034 hooks, etc. which might not be safe to run.
8035
8036 This may GC (insert may run before/after change hooks),
8037 so the buffer M must NOT point to a Lisp string. */
8038
8039 void
8040 message_dolog (m, nbytes, nlflag, multibyte)
8041 const char *m;
8042 int nbytes, nlflag, multibyte;
8043 {
8044 if (!NILP (Vmemory_full))
8045 return;
8046
8047 if (!NILP (Vmessage_log_max))
8048 {
8049 struct buffer *oldbuf;
8050 Lisp_Object oldpoint, oldbegv, oldzv;
8051 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8052 int point_at_end = 0;
8053 int zv_at_end = 0;
8054 Lisp_Object old_deactivate_mark, tem;
8055 struct gcpro gcpro1;
8056
8057 old_deactivate_mark = Vdeactivate_mark;
8058 oldbuf = current_buffer;
8059 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8060 current_buffer->undo_list = Qt;
8061
8062 oldpoint = message_dolog_marker1;
8063 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8064 oldbegv = message_dolog_marker2;
8065 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8066 oldzv = message_dolog_marker3;
8067 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8068 GCPRO1 (old_deactivate_mark);
8069
8070 if (PT == Z)
8071 point_at_end = 1;
8072 if (ZV == Z)
8073 zv_at_end = 1;
8074
8075 BEGV = BEG;
8076 BEGV_BYTE = BEG_BYTE;
8077 ZV = Z;
8078 ZV_BYTE = Z_BYTE;
8079 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8080
8081 /* Insert the string--maybe converting multibyte to single byte
8082 or vice versa, so that all the text fits the buffer. */
8083 if (multibyte
8084 && NILP (current_buffer->enable_multibyte_characters))
8085 {
8086 int i, c, char_bytes;
8087 unsigned char work[1];
8088
8089 /* Convert a multibyte string to single-byte
8090 for the *Message* buffer. */
8091 for (i = 0; i < nbytes; i += char_bytes)
8092 {
8093 c = string_char_and_length (m + i, &char_bytes);
8094 work[0] = (ASCII_CHAR_P (c)
8095 ? c
8096 : multibyte_char_to_unibyte (c, Qnil));
8097 insert_1_both (work, 1, 1, 1, 0, 0);
8098 }
8099 }
8100 else if (! multibyte
8101 && ! NILP (current_buffer->enable_multibyte_characters))
8102 {
8103 int i, c, char_bytes;
8104 unsigned char *msg = (unsigned char *) m;
8105 unsigned char str[MAX_MULTIBYTE_LENGTH];
8106 /* Convert a single-byte string to multibyte
8107 for the *Message* buffer. */
8108 for (i = 0; i < nbytes; i++)
8109 {
8110 c = msg[i];
8111 MAKE_CHAR_MULTIBYTE (c);
8112 char_bytes = CHAR_STRING (c, str);
8113 insert_1_both (str, 1, char_bytes, 1, 0, 0);
8114 }
8115 }
8116 else if (nbytes)
8117 insert_1 (m, nbytes, 1, 0, 0);
8118
8119 if (nlflag)
8120 {
8121 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
8122 insert_1 ("\n", 1, 1, 0, 0);
8123
8124 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8125 this_bol = PT;
8126 this_bol_byte = PT_BYTE;
8127
8128 /* See if this line duplicates the previous one.
8129 If so, combine duplicates. */
8130 if (this_bol > BEG)
8131 {
8132 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8133 prev_bol = PT;
8134 prev_bol_byte = PT_BYTE;
8135
8136 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
8137 this_bol, this_bol_byte);
8138 if (dup)
8139 {
8140 del_range_both (prev_bol, prev_bol_byte,
8141 this_bol, this_bol_byte, 0);
8142 if (dup > 1)
8143 {
8144 char dupstr[40];
8145 int duplen;
8146
8147 /* If you change this format, don't forget to also
8148 change message_log_check_duplicate. */
8149 sprintf (dupstr, " [%d times]", dup);
8150 duplen = strlen (dupstr);
8151 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8152 insert_1 (dupstr, duplen, 1, 0, 1);
8153 }
8154 }
8155 }
8156
8157 /* If we have more than the desired maximum number of lines
8158 in the *Messages* buffer now, delete the oldest ones.
8159 This is safe because we don't have undo in this buffer. */
8160
8161 if (NATNUMP (Vmessage_log_max))
8162 {
8163 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8164 -XFASTINT (Vmessage_log_max) - 1, 0);
8165 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8166 }
8167 }
8168 BEGV = XMARKER (oldbegv)->charpos;
8169 BEGV_BYTE = marker_byte_position (oldbegv);
8170
8171 if (zv_at_end)
8172 {
8173 ZV = Z;
8174 ZV_BYTE = Z_BYTE;
8175 }
8176 else
8177 {
8178 ZV = XMARKER (oldzv)->charpos;
8179 ZV_BYTE = marker_byte_position (oldzv);
8180 }
8181
8182 if (point_at_end)
8183 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8184 else
8185 /* We can't do Fgoto_char (oldpoint) because it will run some
8186 Lisp code. */
8187 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8188 XMARKER (oldpoint)->bytepos);
8189
8190 UNGCPRO;
8191 unchain_marker (XMARKER (oldpoint));
8192 unchain_marker (XMARKER (oldbegv));
8193 unchain_marker (XMARKER (oldzv));
8194
8195 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8196 set_buffer_internal (oldbuf);
8197 if (NILP (tem))
8198 windows_or_buffers_changed = old_windows_or_buffers_changed;
8199 message_log_need_newline = !nlflag;
8200 Vdeactivate_mark = old_deactivate_mark;
8201 }
8202 }
8203
8204
8205 /* We are at the end of the buffer after just having inserted a newline.
8206 (Note: We depend on the fact we won't be crossing the gap.)
8207 Check to see if the most recent message looks a lot like the previous one.
8208 Return 0 if different, 1 if the new one should just replace it, or a
8209 value N > 1 if we should also append " [N times]". */
8210
8211 static int
8212 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
8213 int prev_bol, this_bol;
8214 int prev_bol_byte, this_bol_byte;
8215 {
8216 int i;
8217 int len = Z_BYTE - 1 - this_bol_byte;
8218 int seen_dots = 0;
8219 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8220 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8221
8222 for (i = 0; i < len; i++)
8223 {
8224 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8225 seen_dots = 1;
8226 if (p1[i] != p2[i])
8227 return seen_dots;
8228 }
8229 p1 += len;
8230 if (*p1 == '\n')
8231 return 2;
8232 if (*p1++ == ' ' && *p1++ == '[')
8233 {
8234 int n = 0;
8235 while (*p1 >= '0' && *p1 <= '9')
8236 n = n * 10 + *p1++ - '0';
8237 if (strncmp (p1, " times]\n", 8) == 0)
8238 return n+1;
8239 }
8240 return 0;
8241 }
8242 \f
8243
8244 /* Display an echo area message M with a specified length of NBYTES
8245 bytes. The string may include null characters. If M is 0, clear
8246 out any existing message, and let the mini-buffer text show
8247 through.
8248
8249 This may GC, so the buffer M must NOT point to a Lisp string. */
8250
8251 void
8252 message2 (m, nbytes, multibyte)
8253 const char *m;
8254 int nbytes;
8255 int multibyte;
8256 {
8257 /* First flush out any partial line written with print. */
8258 message_log_maybe_newline ();
8259 if (m)
8260 message_dolog (m, nbytes, 1, multibyte);
8261 message2_nolog (m, nbytes, multibyte);
8262 }
8263
8264
8265 /* The non-logging counterpart of message2. */
8266
8267 void
8268 message2_nolog (m, nbytes, multibyte)
8269 const char *m;
8270 int nbytes, multibyte;
8271 {
8272 struct frame *sf = SELECTED_FRAME ();
8273 message_enable_multibyte = multibyte;
8274
8275 if (FRAME_INITIAL_P (sf))
8276 {
8277 if (noninteractive_need_newline)
8278 putc ('\n', stderr);
8279 noninteractive_need_newline = 0;
8280 if (m)
8281 fwrite (m, nbytes, 1, stderr);
8282 if (cursor_in_echo_area == 0)
8283 fprintf (stderr, "\n");
8284 fflush (stderr);
8285 }
8286 /* A null message buffer means that the frame hasn't really been
8287 initialized yet. Error messages get reported properly by
8288 cmd_error, so this must be just an informative message; toss it. */
8289 else if (INTERACTIVE
8290 && sf->glyphs_initialized_p
8291 && FRAME_MESSAGE_BUF (sf))
8292 {
8293 Lisp_Object mini_window;
8294 struct frame *f;
8295
8296 /* Get the frame containing the mini-buffer
8297 that the selected frame is using. */
8298 mini_window = FRAME_MINIBUF_WINDOW (sf);
8299 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8300
8301 FRAME_SAMPLE_VISIBILITY (f);
8302 if (FRAME_VISIBLE_P (sf)
8303 && ! FRAME_VISIBLE_P (f))
8304 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8305
8306 if (m)
8307 {
8308 set_message (m, Qnil, nbytes, multibyte);
8309 if (minibuffer_auto_raise)
8310 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8311 }
8312 else
8313 clear_message (1, 1);
8314
8315 do_pending_window_change (0);
8316 echo_area_display (1);
8317 do_pending_window_change (0);
8318 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8319 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8320 }
8321 }
8322
8323
8324 /* Display an echo area message M with a specified length of NBYTES
8325 bytes. The string may include null characters. If M is not a
8326 string, clear out any existing message, and let the mini-buffer
8327 text show through.
8328
8329 This function cancels echoing. */
8330
8331 void
8332 message3 (m, nbytes, multibyte)
8333 Lisp_Object m;
8334 int nbytes;
8335 int multibyte;
8336 {
8337 struct gcpro gcpro1;
8338
8339 GCPRO1 (m);
8340 clear_message (1,1);
8341 cancel_echoing ();
8342
8343 /* First flush out any partial line written with print. */
8344 message_log_maybe_newline ();
8345 if (STRINGP (m))
8346 {
8347 char *buffer;
8348 USE_SAFE_ALLOCA;
8349
8350 SAFE_ALLOCA (buffer, char *, nbytes);
8351 bcopy (SDATA (m), buffer, nbytes);
8352 message_dolog (buffer, nbytes, 1, multibyte);
8353 SAFE_FREE ();
8354 }
8355 message3_nolog (m, nbytes, multibyte);
8356
8357 UNGCPRO;
8358 }
8359
8360
8361 /* The non-logging version of message3.
8362 This does not cancel echoing, because it is used for echoing.
8363 Perhaps we need to make a separate function for echoing
8364 and make this cancel echoing. */
8365
8366 void
8367 message3_nolog (m, nbytes, multibyte)
8368 Lisp_Object m;
8369 int nbytes, multibyte;
8370 {
8371 struct frame *sf = SELECTED_FRAME ();
8372 message_enable_multibyte = multibyte;
8373
8374 if (FRAME_INITIAL_P (sf))
8375 {
8376 if (noninteractive_need_newline)
8377 putc ('\n', stderr);
8378 noninteractive_need_newline = 0;
8379 if (STRINGP (m))
8380 fwrite (SDATA (m), nbytes, 1, stderr);
8381 if (cursor_in_echo_area == 0)
8382 fprintf (stderr, "\n");
8383 fflush (stderr);
8384 }
8385 /* A null message buffer means that the frame hasn't really been
8386 initialized yet. Error messages get reported properly by
8387 cmd_error, so this must be just an informative message; toss it. */
8388 else if (INTERACTIVE
8389 && sf->glyphs_initialized_p
8390 && FRAME_MESSAGE_BUF (sf))
8391 {
8392 Lisp_Object mini_window;
8393 Lisp_Object frame;
8394 struct frame *f;
8395
8396 /* Get the frame containing the mini-buffer
8397 that the selected frame is using. */
8398 mini_window = FRAME_MINIBUF_WINDOW (sf);
8399 frame = XWINDOW (mini_window)->frame;
8400 f = XFRAME (frame);
8401
8402 FRAME_SAMPLE_VISIBILITY (f);
8403 if (FRAME_VISIBLE_P (sf)
8404 && !FRAME_VISIBLE_P (f))
8405 Fmake_frame_visible (frame);
8406
8407 if (STRINGP (m) && SCHARS (m) > 0)
8408 {
8409 set_message (NULL, m, nbytes, multibyte);
8410 if (minibuffer_auto_raise)
8411 Fraise_frame (frame);
8412 /* Assume we are not echoing.
8413 (If we are, echo_now will override this.) */
8414 echo_message_buffer = Qnil;
8415 }
8416 else
8417 clear_message (1, 1);
8418
8419 do_pending_window_change (0);
8420 echo_area_display (1);
8421 do_pending_window_change (0);
8422 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8423 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8424 }
8425 }
8426
8427
8428 /* Display a null-terminated echo area message M. If M is 0, clear
8429 out any existing message, and let the mini-buffer text show through.
8430
8431 The buffer M must continue to exist until after the echo area gets
8432 cleared or some other message gets displayed there. Do not pass
8433 text that is stored in a Lisp string. Do not pass text in a buffer
8434 that was alloca'd. */
8435
8436 void
8437 message1 (m)
8438 char *m;
8439 {
8440 message2 (m, (m ? strlen (m) : 0), 0);
8441 }
8442
8443
8444 /* The non-logging counterpart of message1. */
8445
8446 void
8447 message1_nolog (m)
8448 char *m;
8449 {
8450 message2_nolog (m, (m ? strlen (m) : 0), 0);
8451 }
8452
8453 /* Display a message M which contains a single %s
8454 which gets replaced with STRING. */
8455
8456 void
8457 message_with_string (m, string, log)
8458 char *m;
8459 Lisp_Object string;
8460 int log;
8461 {
8462 CHECK_STRING (string);
8463
8464 if (noninteractive)
8465 {
8466 if (m)
8467 {
8468 if (noninteractive_need_newline)
8469 putc ('\n', stderr);
8470 noninteractive_need_newline = 0;
8471 fprintf (stderr, m, SDATA (string));
8472 if (!cursor_in_echo_area)
8473 fprintf (stderr, "\n");
8474 fflush (stderr);
8475 }
8476 }
8477 else if (INTERACTIVE)
8478 {
8479 /* The frame whose minibuffer we're going to display the message on.
8480 It may be larger than the selected frame, so we need
8481 to use its buffer, not the selected frame's buffer. */
8482 Lisp_Object mini_window;
8483 struct frame *f, *sf = SELECTED_FRAME ();
8484
8485 /* Get the frame containing the minibuffer
8486 that the selected frame is using. */
8487 mini_window = FRAME_MINIBUF_WINDOW (sf);
8488 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8489
8490 /* A null message buffer means that the frame hasn't really been
8491 initialized yet. Error messages get reported properly by
8492 cmd_error, so this must be just an informative message; toss it. */
8493 if (FRAME_MESSAGE_BUF (f))
8494 {
8495 Lisp_Object args[2], message;
8496 struct gcpro gcpro1, gcpro2;
8497
8498 args[0] = build_string (m);
8499 args[1] = message = string;
8500 GCPRO2 (args[0], message);
8501 gcpro1.nvars = 2;
8502
8503 message = Fformat (2, args);
8504
8505 if (log)
8506 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
8507 else
8508 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
8509
8510 UNGCPRO;
8511
8512 /* Print should start at the beginning of the message
8513 buffer next time. */
8514 message_buf_print = 0;
8515 }
8516 }
8517 }
8518
8519
8520 /* Dump an informative message to the minibuf. If M is 0, clear out
8521 any existing message, and let the mini-buffer text show through. */
8522
8523 /* VARARGS 1 */
8524 void
8525 message (m, a1, a2, a3)
8526 char *m;
8527 EMACS_INT a1, a2, a3;
8528 {
8529 if (noninteractive)
8530 {
8531 if (m)
8532 {
8533 if (noninteractive_need_newline)
8534 putc ('\n', stderr);
8535 noninteractive_need_newline = 0;
8536 fprintf (stderr, m, a1, a2, a3);
8537 if (cursor_in_echo_area == 0)
8538 fprintf (stderr, "\n");
8539 fflush (stderr);
8540 }
8541 }
8542 else if (INTERACTIVE)
8543 {
8544 /* The frame whose mini-buffer we're going to display the message
8545 on. It may be larger than the selected frame, so we need to
8546 use its buffer, not the selected frame's buffer. */
8547 Lisp_Object mini_window;
8548 struct frame *f, *sf = SELECTED_FRAME ();
8549
8550 /* Get the frame containing the mini-buffer
8551 that the selected frame is using. */
8552 mini_window = FRAME_MINIBUF_WINDOW (sf);
8553 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8554
8555 /* A null message buffer means that the frame hasn't really been
8556 initialized yet. Error messages get reported properly by
8557 cmd_error, so this must be just an informative message; toss
8558 it. */
8559 if (FRAME_MESSAGE_BUF (f))
8560 {
8561 if (m)
8562 {
8563 int len;
8564 char *a[3];
8565 a[0] = (char *) a1;
8566 a[1] = (char *) a2;
8567 a[2] = (char *) a3;
8568
8569 len = doprnt (FRAME_MESSAGE_BUF (f),
8570 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
8571
8572 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8573 }
8574 else
8575 message1 (0);
8576
8577 /* Print should start at the beginning of the message
8578 buffer next time. */
8579 message_buf_print = 0;
8580 }
8581 }
8582 }
8583
8584
8585 /* The non-logging version of message. */
8586
8587 void
8588 message_nolog (m, a1, a2, a3)
8589 char *m;
8590 EMACS_INT a1, a2, a3;
8591 {
8592 Lisp_Object old_log_max;
8593 old_log_max = Vmessage_log_max;
8594 Vmessage_log_max = Qnil;
8595 message (m, a1, a2, a3);
8596 Vmessage_log_max = old_log_max;
8597 }
8598
8599
8600 /* Display the current message in the current mini-buffer. This is
8601 only called from error handlers in process.c, and is not time
8602 critical. */
8603
8604 void
8605 update_echo_area ()
8606 {
8607 if (!NILP (echo_area_buffer[0]))
8608 {
8609 Lisp_Object string;
8610 string = Fcurrent_message ();
8611 message3 (string, SBYTES (string),
8612 !NILP (current_buffer->enable_multibyte_characters));
8613 }
8614 }
8615
8616
8617 /* Make sure echo area buffers in `echo_buffers' are live.
8618 If they aren't, make new ones. */
8619
8620 static void
8621 ensure_echo_area_buffers ()
8622 {
8623 int i;
8624
8625 for (i = 0; i < 2; ++i)
8626 if (!BUFFERP (echo_buffer[i])
8627 || NILP (XBUFFER (echo_buffer[i])->name))
8628 {
8629 char name[30];
8630 Lisp_Object old_buffer;
8631 int j;
8632
8633 old_buffer = echo_buffer[i];
8634 sprintf (name, " *Echo Area %d*", i);
8635 echo_buffer[i] = Fget_buffer_create (build_string (name));
8636 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8637 /* to force word wrap in echo area -
8638 it was decided to postpone this*/
8639 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8640
8641 for (j = 0; j < 2; ++j)
8642 if (EQ (old_buffer, echo_area_buffer[j]))
8643 echo_area_buffer[j] = echo_buffer[i];
8644 }
8645 }
8646
8647
8648 /* Call FN with args A1..A4 with either the current or last displayed
8649 echo_area_buffer as current buffer.
8650
8651 WHICH zero means use the current message buffer
8652 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8653 from echo_buffer[] and clear it.
8654
8655 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8656 suitable buffer from echo_buffer[] and clear it.
8657
8658 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8659 that the current message becomes the last displayed one, make
8660 choose a suitable buffer for echo_area_buffer[0], and clear it.
8661
8662 Value is what FN returns. */
8663
8664 static int
8665 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
8666 struct window *w;
8667 int which;
8668 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
8669 EMACS_INT a1;
8670 Lisp_Object a2;
8671 EMACS_INT a3, a4;
8672 {
8673 Lisp_Object buffer;
8674 int this_one, the_other, clear_buffer_p, rc;
8675 int count = SPECPDL_INDEX ();
8676
8677 /* If buffers aren't live, make new ones. */
8678 ensure_echo_area_buffers ();
8679
8680 clear_buffer_p = 0;
8681
8682 if (which == 0)
8683 this_one = 0, the_other = 1;
8684 else if (which > 0)
8685 this_one = 1, the_other = 0;
8686 else
8687 {
8688 this_one = 0, the_other = 1;
8689 clear_buffer_p = 1;
8690
8691 /* We need a fresh one in case the current echo buffer equals
8692 the one containing the last displayed echo area message. */
8693 if (!NILP (echo_area_buffer[this_one])
8694 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8695 echo_area_buffer[this_one] = Qnil;
8696 }
8697
8698 /* Choose a suitable buffer from echo_buffer[] is we don't
8699 have one. */
8700 if (NILP (echo_area_buffer[this_one]))
8701 {
8702 echo_area_buffer[this_one]
8703 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8704 ? echo_buffer[the_other]
8705 : echo_buffer[this_one]);
8706 clear_buffer_p = 1;
8707 }
8708
8709 buffer = echo_area_buffer[this_one];
8710
8711 /* Don't get confused by reusing the buffer used for echoing
8712 for a different purpose. */
8713 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8714 cancel_echoing ();
8715
8716 record_unwind_protect (unwind_with_echo_area_buffer,
8717 with_echo_area_buffer_unwind_data (w));
8718
8719 /* Make the echo area buffer current. Note that for display
8720 purposes, it is not necessary that the displayed window's buffer
8721 == current_buffer, except for text property lookup. So, let's
8722 only set that buffer temporarily here without doing a full
8723 Fset_window_buffer. We must also change w->pointm, though,
8724 because otherwise an assertions in unshow_buffer fails, and Emacs
8725 aborts. */
8726 set_buffer_internal_1 (XBUFFER (buffer));
8727 if (w)
8728 {
8729 w->buffer = buffer;
8730 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8731 }
8732
8733 current_buffer->undo_list = Qt;
8734 current_buffer->read_only = Qnil;
8735 specbind (Qinhibit_read_only, Qt);
8736 specbind (Qinhibit_modification_hooks, Qt);
8737
8738 if (clear_buffer_p && Z > BEG)
8739 del_range (BEG, Z);
8740
8741 xassert (BEGV >= BEG);
8742 xassert (ZV <= Z && ZV >= BEGV);
8743
8744 rc = fn (a1, a2, a3, a4);
8745
8746 xassert (BEGV >= BEG);
8747 xassert (ZV <= Z && ZV >= BEGV);
8748
8749 unbind_to (count, Qnil);
8750 return rc;
8751 }
8752
8753
8754 /* Save state that should be preserved around the call to the function
8755 FN called in with_echo_area_buffer. */
8756
8757 static Lisp_Object
8758 with_echo_area_buffer_unwind_data (w)
8759 struct window *w;
8760 {
8761 int i = 0;
8762 Lisp_Object vector, tmp;
8763
8764 /* Reduce consing by keeping one vector in
8765 Vwith_echo_area_save_vector. */
8766 vector = Vwith_echo_area_save_vector;
8767 Vwith_echo_area_save_vector = Qnil;
8768
8769 if (NILP (vector))
8770 vector = Fmake_vector (make_number (7), Qnil);
8771
8772 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8773 ASET (vector, i, Vdeactivate_mark); ++i;
8774 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8775
8776 if (w)
8777 {
8778 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8779 ASET (vector, i, w->buffer); ++i;
8780 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8781 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8782 }
8783 else
8784 {
8785 int end = i + 4;
8786 for (; i < end; ++i)
8787 ASET (vector, i, Qnil);
8788 }
8789
8790 xassert (i == ASIZE (vector));
8791 return vector;
8792 }
8793
8794
8795 /* Restore global state from VECTOR which was created by
8796 with_echo_area_buffer_unwind_data. */
8797
8798 static Lisp_Object
8799 unwind_with_echo_area_buffer (vector)
8800 Lisp_Object vector;
8801 {
8802 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8803 Vdeactivate_mark = AREF (vector, 1);
8804 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8805
8806 if (WINDOWP (AREF (vector, 3)))
8807 {
8808 struct window *w;
8809 Lisp_Object buffer, charpos, bytepos;
8810
8811 w = XWINDOW (AREF (vector, 3));
8812 buffer = AREF (vector, 4);
8813 charpos = AREF (vector, 5);
8814 bytepos = AREF (vector, 6);
8815
8816 w->buffer = buffer;
8817 set_marker_both (w->pointm, buffer,
8818 XFASTINT (charpos), XFASTINT (bytepos));
8819 }
8820
8821 Vwith_echo_area_save_vector = vector;
8822 return Qnil;
8823 }
8824
8825
8826 /* Set up the echo area for use by print functions. MULTIBYTE_P
8827 non-zero means we will print multibyte. */
8828
8829 void
8830 setup_echo_area_for_printing (multibyte_p)
8831 int multibyte_p;
8832 {
8833 /* If we can't find an echo area any more, exit. */
8834 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8835 Fkill_emacs (Qnil);
8836
8837 ensure_echo_area_buffers ();
8838
8839 if (!message_buf_print)
8840 {
8841 /* A message has been output since the last time we printed.
8842 Choose a fresh echo area buffer. */
8843 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8844 echo_area_buffer[0] = echo_buffer[1];
8845 else
8846 echo_area_buffer[0] = echo_buffer[0];
8847
8848 /* Switch to that buffer and clear it. */
8849 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8850 current_buffer->truncate_lines = Qnil;
8851
8852 if (Z > BEG)
8853 {
8854 int count = SPECPDL_INDEX ();
8855 specbind (Qinhibit_read_only, Qt);
8856 /* Note that undo recording is always disabled. */
8857 del_range (BEG, Z);
8858 unbind_to (count, Qnil);
8859 }
8860 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8861
8862 /* Set up the buffer for the multibyteness we need. */
8863 if (multibyte_p
8864 != !NILP (current_buffer->enable_multibyte_characters))
8865 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8866
8867 /* Raise the frame containing the echo area. */
8868 if (minibuffer_auto_raise)
8869 {
8870 struct frame *sf = SELECTED_FRAME ();
8871 Lisp_Object mini_window;
8872 mini_window = FRAME_MINIBUF_WINDOW (sf);
8873 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8874 }
8875
8876 message_log_maybe_newline ();
8877 message_buf_print = 1;
8878 }
8879 else
8880 {
8881 if (NILP (echo_area_buffer[0]))
8882 {
8883 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8884 echo_area_buffer[0] = echo_buffer[1];
8885 else
8886 echo_area_buffer[0] = echo_buffer[0];
8887 }
8888
8889 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8890 {
8891 /* Someone switched buffers between print requests. */
8892 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8893 current_buffer->truncate_lines = Qnil;
8894 }
8895 }
8896 }
8897
8898
8899 /* Display an echo area message in window W. Value is non-zero if W's
8900 height is changed. If display_last_displayed_message_p is
8901 non-zero, display the message that was last displayed, otherwise
8902 display the current message. */
8903
8904 static int
8905 display_echo_area (w)
8906 struct window *w;
8907 {
8908 int i, no_message_p, window_height_changed_p, count;
8909
8910 /* Temporarily disable garbage collections while displaying the echo
8911 area. This is done because a GC can print a message itself.
8912 That message would modify the echo area buffer's contents while a
8913 redisplay of the buffer is going on, and seriously confuse
8914 redisplay. */
8915 count = inhibit_garbage_collection ();
8916
8917 /* If there is no message, we must call display_echo_area_1
8918 nevertheless because it resizes the window. But we will have to
8919 reset the echo_area_buffer in question to nil at the end because
8920 with_echo_area_buffer will sets it to an empty buffer. */
8921 i = display_last_displayed_message_p ? 1 : 0;
8922 no_message_p = NILP (echo_area_buffer[i]);
8923
8924 window_height_changed_p
8925 = with_echo_area_buffer (w, display_last_displayed_message_p,
8926 display_echo_area_1,
8927 (EMACS_INT) w, Qnil, 0, 0);
8928
8929 if (no_message_p)
8930 echo_area_buffer[i] = Qnil;
8931
8932 unbind_to (count, Qnil);
8933 return window_height_changed_p;
8934 }
8935
8936
8937 /* Helper for display_echo_area. Display the current buffer which
8938 contains the current echo area message in window W, a mini-window,
8939 a pointer to which is passed in A1. A2..A4 are currently not used.
8940 Change the height of W so that all of the message is displayed.
8941 Value is non-zero if height of W was changed. */
8942
8943 static int
8944 display_echo_area_1 (a1, a2, a3, a4)
8945 EMACS_INT a1;
8946 Lisp_Object a2;
8947 EMACS_INT a3, a4;
8948 {
8949 struct window *w = (struct window *) a1;
8950 Lisp_Object window;
8951 struct text_pos start;
8952 int window_height_changed_p = 0;
8953
8954 /* Do this before displaying, so that we have a large enough glyph
8955 matrix for the display. If we can't get enough space for the
8956 whole text, display the last N lines. That works by setting w->start. */
8957 window_height_changed_p = resize_mini_window (w, 0);
8958
8959 /* Use the starting position chosen by resize_mini_window. */
8960 SET_TEXT_POS_FROM_MARKER (start, w->start);
8961
8962 /* Display. */
8963 clear_glyph_matrix (w->desired_matrix);
8964 XSETWINDOW (window, w);
8965 try_window (window, start, 0);
8966
8967 return window_height_changed_p;
8968 }
8969
8970
8971 /* Resize the echo area window to exactly the size needed for the
8972 currently displayed message, if there is one. If a mini-buffer
8973 is active, don't shrink it. */
8974
8975 void
8976 resize_echo_area_exactly ()
8977 {
8978 if (BUFFERP (echo_area_buffer[0])
8979 && WINDOWP (echo_area_window))
8980 {
8981 struct window *w = XWINDOW (echo_area_window);
8982 int resized_p;
8983 Lisp_Object resize_exactly;
8984
8985 if (minibuf_level == 0)
8986 resize_exactly = Qt;
8987 else
8988 resize_exactly = Qnil;
8989
8990 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8991 (EMACS_INT) w, resize_exactly, 0, 0);
8992 if (resized_p)
8993 {
8994 ++windows_or_buffers_changed;
8995 ++update_mode_lines;
8996 redisplay_internal (0);
8997 }
8998 }
8999 }
9000
9001
9002 /* Callback function for with_echo_area_buffer, when used from
9003 resize_echo_area_exactly. A1 contains a pointer to the window to
9004 resize, EXACTLY non-nil means resize the mini-window exactly to the
9005 size of the text displayed. A3 and A4 are not used. Value is what
9006 resize_mini_window returns. */
9007
9008 static int
9009 resize_mini_window_1 (a1, exactly, a3, a4)
9010 EMACS_INT a1;
9011 Lisp_Object exactly;
9012 EMACS_INT a3, a4;
9013 {
9014 return resize_mini_window ((struct window *) a1, !NILP (exactly));
9015 }
9016
9017
9018 /* Resize mini-window W to fit the size of its contents. EXACT_P
9019 means size the window exactly to the size needed. Otherwise, it's
9020 only enlarged until W's buffer is empty.
9021
9022 Set W->start to the right place to begin display. If the whole
9023 contents fit, start at the beginning. Otherwise, start so as
9024 to make the end of the contents appear. This is particularly
9025 important for y-or-n-p, but seems desirable generally.
9026
9027 Value is non-zero if the window height has been changed. */
9028
9029 int
9030 resize_mini_window (w, exact_p)
9031 struct window *w;
9032 int exact_p;
9033 {
9034 struct frame *f = XFRAME (w->frame);
9035 int window_height_changed_p = 0;
9036
9037 xassert (MINI_WINDOW_P (w));
9038
9039 /* By default, start display at the beginning. */
9040 set_marker_both (w->start, w->buffer,
9041 BUF_BEGV (XBUFFER (w->buffer)),
9042 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
9043
9044 /* Don't resize windows while redisplaying a window; it would
9045 confuse redisplay functions when the size of the window they are
9046 displaying changes from under them. Such a resizing can happen,
9047 for instance, when which-func prints a long message while
9048 we are running fontification-functions. We're running these
9049 functions with safe_call which binds inhibit-redisplay to t. */
9050 if (!NILP (Vinhibit_redisplay))
9051 return 0;
9052
9053 /* Nil means don't try to resize. */
9054 if (NILP (Vresize_mini_windows)
9055 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
9056 return 0;
9057
9058 if (!FRAME_MINIBUF_ONLY_P (f))
9059 {
9060 struct it it;
9061 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9062 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9063 int height, max_height;
9064 int unit = FRAME_LINE_HEIGHT (f);
9065 struct text_pos start;
9066 struct buffer *old_current_buffer = NULL;
9067
9068 if (current_buffer != XBUFFER (w->buffer))
9069 {
9070 old_current_buffer = current_buffer;
9071 set_buffer_internal (XBUFFER (w->buffer));
9072 }
9073
9074 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9075
9076 /* Compute the max. number of lines specified by the user. */
9077 if (FLOATP (Vmax_mini_window_height))
9078 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9079 else if (INTEGERP (Vmax_mini_window_height))
9080 max_height = XINT (Vmax_mini_window_height);
9081 else
9082 max_height = total_height / 4;
9083
9084 /* Correct that max. height if it's bogus. */
9085 max_height = max (1, max_height);
9086 max_height = min (total_height, max_height);
9087
9088 /* Find out the height of the text in the window. */
9089 if (it.line_wrap == TRUNCATE)
9090 height = 1;
9091 else
9092 {
9093 last_height = 0;
9094 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9095 if (it.max_ascent == 0 && it.max_descent == 0)
9096 height = it.current_y + last_height;
9097 else
9098 height = it.current_y + it.max_ascent + it.max_descent;
9099 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9100 height = (height + unit - 1) / unit;
9101 }
9102
9103 /* Compute a suitable window start. */
9104 if (height > max_height)
9105 {
9106 height = max_height;
9107 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9108 move_it_vertically_backward (&it, (height - 1) * unit);
9109 start = it.current.pos;
9110 }
9111 else
9112 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9113 SET_MARKER_FROM_TEXT_POS (w->start, start);
9114
9115 if (EQ (Vresize_mini_windows, Qgrow_only))
9116 {
9117 /* Let it grow only, until we display an empty message, in which
9118 case the window shrinks again. */
9119 if (height > WINDOW_TOTAL_LINES (w))
9120 {
9121 int old_height = WINDOW_TOTAL_LINES (w);
9122 freeze_window_starts (f, 1);
9123 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9124 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9125 }
9126 else if (height < WINDOW_TOTAL_LINES (w)
9127 && (exact_p || BEGV == ZV))
9128 {
9129 int old_height = WINDOW_TOTAL_LINES (w);
9130 freeze_window_starts (f, 0);
9131 shrink_mini_window (w);
9132 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9133 }
9134 }
9135 else
9136 {
9137 /* Always resize to exact size needed. */
9138 if (height > WINDOW_TOTAL_LINES (w))
9139 {
9140 int old_height = WINDOW_TOTAL_LINES (w);
9141 freeze_window_starts (f, 1);
9142 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9143 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9144 }
9145 else if (height < WINDOW_TOTAL_LINES (w))
9146 {
9147 int old_height = WINDOW_TOTAL_LINES (w);
9148 freeze_window_starts (f, 0);
9149 shrink_mini_window (w);
9150
9151 if (height)
9152 {
9153 freeze_window_starts (f, 1);
9154 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9155 }
9156
9157 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9158 }
9159 }
9160
9161 if (old_current_buffer)
9162 set_buffer_internal (old_current_buffer);
9163 }
9164
9165 return window_height_changed_p;
9166 }
9167
9168
9169 /* Value is the current message, a string, or nil if there is no
9170 current message. */
9171
9172 Lisp_Object
9173 current_message ()
9174 {
9175 Lisp_Object msg;
9176
9177 if (!BUFFERP (echo_area_buffer[0]))
9178 msg = Qnil;
9179 else
9180 {
9181 with_echo_area_buffer (0, 0, current_message_1,
9182 (EMACS_INT) &msg, Qnil, 0, 0);
9183 if (NILP (msg))
9184 echo_area_buffer[0] = Qnil;
9185 }
9186
9187 return msg;
9188 }
9189
9190
9191 static int
9192 current_message_1 (a1, a2, a3, a4)
9193 EMACS_INT a1;
9194 Lisp_Object a2;
9195 EMACS_INT a3, a4;
9196 {
9197 Lisp_Object *msg = (Lisp_Object *) a1;
9198
9199 if (Z > BEG)
9200 *msg = make_buffer_string (BEG, Z, 1);
9201 else
9202 *msg = Qnil;
9203 return 0;
9204 }
9205
9206
9207 /* Push the current message on Vmessage_stack for later restauration
9208 by restore_message. Value is non-zero if the current message isn't
9209 empty. This is a relatively infrequent operation, so it's not
9210 worth optimizing. */
9211
9212 int
9213 push_message ()
9214 {
9215 Lisp_Object msg;
9216 msg = current_message ();
9217 Vmessage_stack = Fcons (msg, Vmessage_stack);
9218 return STRINGP (msg);
9219 }
9220
9221
9222 /* Restore message display from the top of Vmessage_stack. */
9223
9224 void
9225 restore_message ()
9226 {
9227 Lisp_Object msg;
9228
9229 xassert (CONSP (Vmessage_stack));
9230 msg = XCAR (Vmessage_stack);
9231 if (STRINGP (msg))
9232 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9233 else
9234 message3_nolog (msg, 0, 0);
9235 }
9236
9237
9238 /* Handler for record_unwind_protect calling pop_message. */
9239
9240 Lisp_Object
9241 pop_message_unwind (dummy)
9242 Lisp_Object dummy;
9243 {
9244 pop_message ();
9245 return Qnil;
9246 }
9247
9248 /* Pop the top-most entry off Vmessage_stack. */
9249
9250 void
9251 pop_message ()
9252 {
9253 xassert (CONSP (Vmessage_stack));
9254 Vmessage_stack = XCDR (Vmessage_stack);
9255 }
9256
9257
9258 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9259 exits. If the stack is not empty, we have a missing pop_message
9260 somewhere. */
9261
9262 void
9263 check_message_stack ()
9264 {
9265 if (!NILP (Vmessage_stack))
9266 abort ();
9267 }
9268
9269
9270 /* Truncate to NCHARS what will be displayed in the echo area the next
9271 time we display it---but don't redisplay it now. */
9272
9273 void
9274 truncate_echo_area (nchars)
9275 int nchars;
9276 {
9277 if (nchars == 0)
9278 echo_area_buffer[0] = Qnil;
9279 /* A null message buffer means that the frame hasn't really been
9280 initialized yet. Error messages get reported properly by
9281 cmd_error, so this must be just an informative message; toss it. */
9282 else if (!noninteractive
9283 && INTERACTIVE
9284 && !NILP (echo_area_buffer[0]))
9285 {
9286 struct frame *sf = SELECTED_FRAME ();
9287 if (FRAME_MESSAGE_BUF (sf))
9288 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9289 }
9290 }
9291
9292
9293 /* Helper function for truncate_echo_area. Truncate the current
9294 message to at most NCHARS characters. */
9295
9296 static int
9297 truncate_message_1 (nchars, a2, a3, a4)
9298 EMACS_INT nchars;
9299 Lisp_Object a2;
9300 EMACS_INT a3, a4;
9301 {
9302 if (BEG + nchars < Z)
9303 del_range (BEG + nchars, Z);
9304 if (Z == BEG)
9305 echo_area_buffer[0] = Qnil;
9306 return 0;
9307 }
9308
9309
9310 /* Set the current message to a substring of S or STRING.
9311
9312 If STRING is a Lisp string, set the message to the first NBYTES
9313 bytes from STRING. NBYTES zero means use the whole string. If
9314 STRING is multibyte, the message will be displayed multibyte.
9315
9316 If S is not null, set the message to the first LEN bytes of S. LEN
9317 zero means use the whole string. MULTIBYTE_P non-zero means S is
9318 multibyte. Display the message multibyte in that case.
9319
9320 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9321 to t before calling set_message_1 (which calls insert).
9322 */
9323
9324 void
9325 set_message (s, string, nbytes, multibyte_p)
9326 const char *s;
9327 Lisp_Object string;
9328 int nbytes, multibyte_p;
9329 {
9330 message_enable_multibyte
9331 = ((s && multibyte_p)
9332 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9333
9334 with_echo_area_buffer (0, -1, set_message_1,
9335 (EMACS_INT) s, string, nbytes, multibyte_p);
9336 message_buf_print = 0;
9337 help_echo_showing_p = 0;
9338 }
9339
9340
9341 /* Helper function for set_message. Arguments have the same meaning
9342 as there, with A1 corresponding to S and A2 corresponding to STRING
9343 This function is called with the echo area buffer being
9344 current. */
9345
9346 static int
9347 set_message_1 (a1, a2, nbytes, multibyte_p)
9348 EMACS_INT a1;
9349 Lisp_Object a2;
9350 EMACS_INT nbytes, multibyte_p;
9351 {
9352 const char *s = (const char *) a1;
9353 Lisp_Object string = a2;
9354
9355 /* Change multibyteness of the echo buffer appropriately. */
9356 if (message_enable_multibyte
9357 != !NILP (current_buffer->enable_multibyte_characters))
9358 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9359
9360 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9361
9362 /* Insert new message at BEG. */
9363 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9364
9365 if (STRINGP (string))
9366 {
9367 int nchars;
9368
9369 if (nbytes == 0)
9370 nbytes = SBYTES (string);
9371 nchars = string_byte_to_char (string, nbytes);
9372
9373 /* This function takes care of single/multibyte conversion. We
9374 just have to ensure that the echo area buffer has the right
9375 setting of enable_multibyte_characters. */
9376 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9377 }
9378 else if (s)
9379 {
9380 if (nbytes == 0)
9381 nbytes = strlen (s);
9382
9383 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
9384 {
9385 /* Convert from multi-byte to single-byte. */
9386 int i, c, n;
9387 unsigned char work[1];
9388
9389 /* Convert a multibyte string to single-byte. */
9390 for (i = 0; i < nbytes; i += n)
9391 {
9392 c = string_char_and_length (s + i, &n);
9393 work[0] = (ASCII_CHAR_P (c)
9394 ? c
9395 : multibyte_char_to_unibyte (c, Qnil));
9396 insert_1_both (work, 1, 1, 1, 0, 0);
9397 }
9398 }
9399 else if (!multibyte_p
9400 && !NILP (current_buffer->enable_multibyte_characters))
9401 {
9402 /* Convert from single-byte to multi-byte. */
9403 int i, c, n;
9404 const unsigned char *msg = (const unsigned char *) s;
9405 unsigned char str[MAX_MULTIBYTE_LENGTH];
9406
9407 /* Convert a single-byte string to multibyte. */
9408 for (i = 0; i < nbytes; i++)
9409 {
9410 c = msg[i];
9411 MAKE_CHAR_MULTIBYTE (c);
9412 n = CHAR_STRING (c, str);
9413 insert_1_both (str, 1, n, 1, 0, 0);
9414 }
9415 }
9416 else
9417 insert_1 (s, nbytes, 1, 0, 0);
9418 }
9419
9420 return 0;
9421 }
9422
9423
9424 /* Clear messages. CURRENT_P non-zero means clear the current
9425 message. LAST_DISPLAYED_P non-zero means clear the message
9426 last displayed. */
9427
9428 void
9429 clear_message (current_p, last_displayed_p)
9430 int current_p, last_displayed_p;
9431 {
9432 if (current_p)
9433 {
9434 echo_area_buffer[0] = Qnil;
9435 message_cleared_p = 1;
9436 }
9437
9438 if (last_displayed_p)
9439 echo_area_buffer[1] = Qnil;
9440
9441 message_buf_print = 0;
9442 }
9443
9444 /* Clear garbaged frames.
9445
9446 This function is used where the old redisplay called
9447 redraw_garbaged_frames which in turn called redraw_frame which in
9448 turn called clear_frame. The call to clear_frame was a source of
9449 flickering. I believe a clear_frame is not necessary. It should
9450 suffice in the new redisplay to invalidate all current matrices,
9451 and ensure a complete redisplay of all windows. */
9452
9453 static void
9454 clear_garbaged_frames ()
9455 {
9456 if (frame_garbaged)
9457 {
9458 Lisp_Object tail, frame;
9459 int changed_count = 0;
9460
9461 FOR_EACH_FRAME (tail, frame)
9462 {
9463 struct frame *f = XFRAME (frame);
9464
9465 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9466 {
9467 if (f->resized_p)
9468 {
9469 Fredraw_frame (frame);
9470 f->force_flush_display_p = 1;
9471 }
9472 clear_current_matrices (f);
9473 changed_count++;
9474 f->garbaged = 0;
9475 f->resized_p = 0;
9476 }
9477 }
9478
9479 frame_garbaged = 0;
9480 if (changed_count)
9481 ++windows_or_buffers_changed;
9482 }
9483 }
9484
9485
9486 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9487 is non-zero update selected_frame. Value is non-zero if the
9488 mini-windows height has been changed. */
9489
9490 static int
9491 echo_area_display (update_frame_p)
9492 int update_frame_p;
9493 {
9494 Lisp_Object mini_window;
9495 struct window *w;
9496 struct frame *f;
9497 int window_height_changed_p = 0;
9498 struct frame *sf = SELECTED_FRAME ();
9499
9500 mini_window = FRAME_MINIBUF_WINDOW (sf);
9501 w = XWINDOW (mini_window);
9502 f = XFRAME (WINDOW_FRAME (w));
9503
9504 /* Don't display if frame is invisible or not yet initialized. */
9505 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9506 return 0;
9507
9508 #ifdef HAVE_WINDOW_SYSTEM
9509 /* When Emacs starts, selected_frame may be the initial terminal
9510 frame. If we let this through, a message would be displayed on
9511 the terminal. */
9512 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9513 return 0;
9514 #endif /* HAVE_WINDOW_SYSTEM */
9515
9516 /* Redraw garbaged frames. */
9517 if (frame_garbaged)
9518 clear_garbaged_frames ();
9519
9520 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9521 {
9522 echo_area_window = mini_window;
9523 window_height_changed_p = display_echo_area (w);
9524 w->must_be_updated_p = 1;
9525
9526 /* Update the display, unless called from redisplay_internal.
9527 Also don't update the screen during redisplay itself. The
9528 update will happen at the end of redisplay, and an update
9529 here could cause confusion. */
9530 if (update_frame_p && !redisplaying_p)
9531 {
9532 int n = 0;
9533
9534 /* If the display update has been interrupted by pending
9535 input, update mode lines in the frame. Due to the
9536 pending input, it might have been that redisplay hasn't
9537 been called, so that mode lines above the echo area are
9538 garbaged. This looks odd, so we prevent it here. */
9539 if (!display_completed)
9540 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9541
9542 if (window_height_changed_p
9543 /* Don't do this if Emacs is shutting down. Redisplay
9544 needs to run hooks. */
9545 && !NILP (Vrun_hooks))
9546 {
9547 /* Must update other windows. Likewise as in other
9548 cases, don't let this update be interrupted by
9549 pending input. */
9550 int count = SPECPDL_INDEX ();
9551 specbind (Qredisplay_dont_pause, Qt);
9552 windows_or_buffers_changed = 1;
9553 redisplay_internal (0);
9554 unbind_to (count, Qnil);
9555 }
9556 else if (FRAME_WINDOW_P (f) && n == 0)
9557 {
9558 /* Window configuration is the same as before.
9559 Can do with a display update of the echo area,
9560 unless we displayed some mode lines. */
9561 update_single_window (w, 1);
9562 FRAME_RIF (f)->flush_display (f);
9563 }
9564 else
9565 update_frame (f, 1, 1);
9566
9567 /* If cursor is in the echo area, make sure that the next
9568 redisplay displays the minibuffer, so that the cursor will
9569 be replaced with what the minibuffer wants. */
9570 if (cursor_in_echo_area)
9571 ++windows_or_buffers_changed;
9572 }
9573 }
9574 else if (!EQ (mini_window, selected_window))
9575 windows_or_buffers_changed++;
9576
9577 /* Last displayed message is now the current message. */
9578 echo_area_buffer[1] = echo_area_buffer[0];
9579 /* Inform read_char that we're not echoing. */
9580 echo_message_buffer = Qnil;
9581
9582 /* Prevent redisplay optimization in redisplay_internal by resetting
9583 this_line_start_pos. This is done because the mini-buffer now
9584 displays the message instead of its buffer text. */
9585 if (EQ (mini_window, selected_window))
9586 CHARPOS (this_line_start_pos) = 0;
9587
9588 return window_height_changed_p;
9589 }
9590
9591
9592 \f
9593 /***********************************************************************
9594 Mode Lines and Frame Titles
9595 ***********************************************************************/
9596
9597 /* A buffer for constructing non-propertized mode-line strings and
9598 frame titles in it; allocated from the heap in init_xdisp and
9599 resized as needed in store_mode_line_noprop_char. */
9600
9601 static char *mode_line_noprop_buf;
9602
9603 /* The buffer's end, and a current output position in it. */
9604
9605 static char *mode_line_noprop_buf_end;
9606 static char *mode_line_noprop_ptr;
9607
9608 #define MODE_LINE_NOPROP_LEN(start) \
9609 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9610
9611 static enum {
9612 MODE_LINE_DISPLAY = 0,
9613 MODE_LINE_TITLE,
9614 MODE_LINE_NOPROP,
9615 MODE_LINE_STRING
9616 } mode_line_target;
9617
9618 /* Alist that caches the results of :propertize.
9619 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9620 static Lisp_Object mode_line_proptrans_alist;
9621
9622 /* List of strings making up the mode-line. */
9623 static Lisp_Object mode_line_string_list;
9624
9625 /* Base face property when building propertized mode line string. */
9626 static Lisp_Object mode_line_string_face;
9627 static Lisp_Object mode_line_string_face_prop;
9628
9629
9630 /* Unwind data for mode line strings */
9631
9632 static Lisp_Object Vmode_line_unwind_vector;
9633
9634 static Lisp_Object
9635 format_mode_line_unwind_data (struct buffer *obuf,
9636 Lisp_Object owin,
9637 int save_proptrans)
9638 {
9639 Lisp_Object vector, tmp;
9640
9641 /* Reduce consing by keeping one vector in
9642 Vwith_echo_area_save_vector. */
9643 vector = Vmode_line_unwind_vector;
9644 Vmode_line_unwind_vector = Qnil;
9645
9646 if (NILP (vector))
9647 vector = Fmake_vector (make_number (8), Qnil);
9648
9649 ASET (vector, 0, make_number (mode_line_target));
9650 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9651 ASET (vector, 2, mode_line_string_list);
9652 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9653 ASET (vector, 4, mode_line_string_face);
9654 ASET (vector, 5, mode_line_string_face_prop);
9655
9656 if (obuf)
9657 XSETBUFFER (tmp, obuf);
9658 else
9659 tmp = Qnil;
9660 ASET (vector, 6, tmp);
9661 ASET (vector, 7, owin);
9662
9663 return vector;
9664 }
9665
9666 static Lisp_Object
9667 unwind_format_mode_line (vector)
9668 Lisp_Object vector;
9669 {
9670 mode_line_target = XINT (AREF (vector, 0));
9671 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9672 mode_line_string_list = AREF (vector, 2);
9673 if (! EQ (AREF (vector, 3), Qt))
9674 mode_line_proptrans_alist = AREF (vector, 3);
9675 mode_line_string_face = AREF (vector, 4);
9676 mode_line_string_face_prop = AREF (vector, 5);
9677
9678 if (!NILP (AREF (vector, 7)))
9679 /* Select window before buffer, since it may change the buffer. */
9680 Fselect_window (AREF (vector, 7), Qt);
9681
9682 if (!NILP (AREF (vector, 6)))
9683 {
9684 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9685 ASET (vector, 6, Qnil);
9686 }
9687
9688 Vmode_line_unwind_vector = vector;
9689 return Qnil;
9690 }
9691
9692
9693 /* Store a single character C for the frame title in mode_line_noprop_buf.
9694 Re-allocate mode_line_noprop_buf if necessary. */
9695
9696 static void
9697 #ifdef PROTOTYPES
9698 store_mode_line_noprop_char (char c)
9699 #else
9700 store_mode_line_noprop_char (c)
9701 char c;
9702 #endif
9703 {
9704 /* If output position has reached the end of the allocated buffer,
9705 double the buffer's size. */
9706 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9707 {
9708 int len = MODE_LINE_NOPROP_LEN (0);
9709 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9710 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9711 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9712 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9713 }
9714
9715 *mode_line_noprop_ptr++ = c;
9716 }
9717
9718
9719 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9720 mode_line_noprop_ptr. STR is the string to store. Do not copy
9721 characters that yield more columns than PRECISION; PRECISION <= 0
9722 means copy the whole string. Pad with spaces until FIELD_WIDTH
9723 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9724 pad. Called from display_mode_element when it is used to build a
9725 frame title. */
9726
9727 static int
9728 store_mode_line_noprop (str, field_width, precision)
9729 const unsigned char *str;
9730 int field_width, precision;
9731 {
9732 int n = 0;
9733 int dummy, nbytes;
9734
9735 /* Copy at most PRECISION chars from STR. */
9736 nbytes = strlen (str);
9737 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9738 while (nbytes--)
9739 store_mode_line_noprop_char (*str++);
9740
9741 /* Fill up with spaces until FIELD_WIDTH reached. */
9742 while (field_width > 0
9743 && n < field_width)
9744 {
9745 store_mode_line_noprop_char (' ');
9746 ++n;
9747 }
9748
9749 return n;
9750 }
9751
9752 /***********************************************************************
9753 Frame Titles
9754 ***********************************************************************/
9755
9756 #ifdef HAVE_WINDOW_SYSTEM
9757
9758 /* Set the title of FRAME, if it has changed. The title format is
9759 Vicon_title_format if FRAME is iconified, otherwise it is
9760 frame_title_format. */
9761
9762 static void
9763 x_consider_frame_title (frame)
9764 Lisp_Object frame;
9765 {
9766 struct frame *f = XFRAME (frame);
9767
9768 if (FRAME_WINDOW_P (f)
9769 || FRAME_MINIBUF_ONLY_P (f)
9770 || f->explicit_name)
9771 {
9772 /* Do we have more than one visible frame on this X display? */
9773 Lisp_Object tail;
9774 Lisp_Object fmt;
9775 int title_start;
9776 char *title;
9777 int len;
9778 struct it it;
9779 int count = SPECPDL_INDEX ();
9780
9781 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9782 {
9783 Lisp_Object other_frame = XCAR (tail);
9784 struct frame *tf = XFRAME (other_frame);
9785
9786 if (tf != f
9787 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9788 && !FRAME_MINIBUF_ONLY_P (tf)
9789 && !EQ (other_frame, tip_frame)
9790 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9791 break;
9792 }
9793
9794 /* Set global variable indicating that multiple frames exist. */
9795 multiple_frames = CONSP (tail);
9796
9797 /* Switch to the buffer of selected window of the frame. Set up
9798 mode_line_target so that display_mode_element will output into
9799 mode_line_noprop_buf; then display the title. */
9800 record_unwind_protect (unwind_format_mode_line,
9801 format_mode_line_unwind_data
9802 (current_buffer, selected_window, 0));
9803
9804 Fselect_window (f->selected_window, Qt);
9805 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9806 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9807
9808 mode_line_target = MODE_LINE_TITLE;
9809 title_start = MODE_LINE_NOPROP_LEN (0);
9810 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9811 NULL, DEFAULT_FACE_ID);
9812 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9813 len = MODE_LINE_NOPROP_LEN (title_start);
9814 title = mode_line_noprop_buf + title_start;
9815 unbind_to (count, Qnil);
9816
9817 /* Set the title only if it's changed. This avoids consing in
9818 the common case where it hasn't. (If it turns out that we've
9819 already wasted too much time by walking through the list with
9820 display_mode_element, then we might need to optimize at a
9821 higher level than this.) */
9822 if (! STRINGP (f->name)
9823 || SBYTES (f->name) != len
9824 || bcmp (title, SDATA (f->name), len) != 0)
9825 x_implicitly_set_name (f, make_string (title, len), Qnil);
9826 }
9827 }
9828
9829 #endif /* not HAVE_WINDOW_SYSTEM */
9830
9831
9832
9833 \f
9834 /***********************************************************************
9835 Menu Bars
9836 ***********************************************************************/
9837
9838
9839 /* Prepare for redisplay by updating menu-bar item lists when
9840 appropriate. This can call eval. */
9841
9842 void
9843 prepare_menu_bars ()
9844 {
9845 int all_windows;
9846 struct gcpro gcpro1, gcpro2;
9847 struct frame *f;
9848 Lisp_Object tooltip_frame;
9849
9850 #ifdef HAVE_WINDOW_SYSTEM
9851 tooltip_frame = tip_frame;
9852 #else
9853 tooltip_frame = Qnil;
9854 #endif
9855
9856 /* Update all frame titles based on their buffer names, etc. We do
9857 this before the menu bars so that the buffer-menu will show the
9858 up-to-date frame titles. */
9859 #ifdef HAVE_WINDOW_SYSTEM
9860 if (windows_or_buffers_changed || update_mode_lines)
9861 {
9862 Lisp_Object tail, frame;
9863
9864 FOR_EACH_FRAME (tail, frame)
9865 {
9866 f = XFRAME (frame);
9867 if (!EQ (frame, tooltip_frame)
9868 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9869 x_consider_frame_title (frame);
9870 }
9871 }
9872 #endif /* HAVE_WINDOW_SYSTEM */
9873
9874 /* Update the menu bar item lists, if appropriate. This has to be
9875 done before any actual redisplay or generation of display lines. */
9876 all_windows = (update_mode_lines
9877 || buffer_shared > 1
9878 || windows_or_buffers_changed);
9879 if (all_windows)
9880 {
9881 Lisp_Object tail, frame;
9882 int count = SPECPDL_INDEX ();
9883 /* 1 means that update_menu_bar has run its hooks
9884 so any further calls to update_menu_bar shouldn't do so again. */
9885 int menu_bar_hooks_run = 0;
9886
9887 record_unwind_save_match_data ();
9888
9889 FOR_EACH_FRAME (tail, frame)
9890 {
9891 f = XFRAME (frame);
9892
9893 /* Ignore tooltip frame. */
9894 if (EQ (frame, tooltip_frame))
9895 continue;
9896
9897 /* If a window on this frame changed size, report that to
9898 the user and clear the size-change flag. */
9899 if (FRAME_WINDOW_SIZES_CHANGED (f))
9900 {
9901 Lisp_Object functions;
9902
9903 /* Clear flag first in case we get an error below. */
9904 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9905 functions = Vwindow_size_change_functions;
9906 GCPRO2 (tail, functions);
9907
9908 while (CONSP (functions))
9909 {
9910 if (!EQ (XCAR (functions), Qt))
9911 call1 (XCAR (functions), frame);
9912 functions = XCDR (functions);
9913 }
9914 UNGCPRO;
9915 }
9916
9917 GCPRO1 (tail);
9918 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9919 #ifdef HAVE_WINDOW_SYSTEM
9920 update_tool_bar (f, 0);
9921 #endif
9922 #ifdef HAVE_NS
9923 if (windows_or_buffers_changed
9924 && FRAME_NS_P (f))
9925 ns_set_doc_edited (f, Fbuffer_modified_p
9926 (XWINDOW (f->selected_window)->buffer));
9927 #endif
9928 UNGCPRO;
9929 }
9930
9931 unbind_to (count, Qnil);
9932 }
9933 else
9934 {
9935 struct frame *sf = SELECTED_FRAME ();
9936 update_menu_bar (sf, 1, 0);
9937 #ifdef HAVE_WINDOW_SYSTEM
9938 update_tool_bar (sf, 1);
9939 #endif
9940 }
9941
9942 /* Motif needs this. See comment in xmenu.c. Turn it off when
9943 pending_menu_activation is not defined. */
9944 #ifdef USE_X_TOOLKIT
9945 pending_menu_activation = 0;
9946 #endif
9947 }
9948
9949
9950 /* Update the menu bar item list for frame F. This has to be done
9951 before we start to fill in any display lines, because it can call
9952 eval.
9953
9954 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9955
9956 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9957 already ran the menu bar hooks for this redisplay, so there
9958 is no need to run them again. The return value is the
9959 updated value of this flag, to pass to the next call. */
9960
9961 static int
9962 update_menu_bar (f, save_match_data, hooks_run)
9963 struct frame *f;
9964 int save_match_data;
9965 int hooks_run;
9966 {
9967 Lisp_Object window;
9968 register struct window *w;
9969
9970 /* If called recursively during a menu update, do nothing. This can
9971 happen when, for instance, an activate-menubar-hook causes a
9972 redisplay. */
9973 if (inhibit_menubar_update)
9974 return hooks_run;
9975
9976 window = FRAME_SELECTED_WINDOW (f);
9977 w = XWINDOW (window);
9978
9979 if (FRAME_WINDOW_P (f)
9980 ?
9981 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9982 || defined (HAVE_NS) || defined (USE_GTK)
9983 FRAME_EXTERNAL_MENU_BAR (f)
9984 #else
9985 FRAME_MENU_BAR_LINES (f) > 0
9986 #endif
9987 : FRAME_MENU_BAR_LINES (f) > 0)
9988 {
9989 /* If the user has switched buffers or windows, we need to
9990 recompute to reflect the new bindings. But we'll
9991 recompute when update_mode_lines is set too; that means
9992 that people can use force-mode-line-update to request
9993 that the menu bar be recomputed. The adverse effect on
9994 the rest of the redisplay algorithm is about the same as
9995 windows_or_buffers_changed anyway. */
9996 if (windows_or_buffers_changed
9997 /* This used to test w->update_mode_line, but we believe
9998 there is no need to recompute the menu in that case. */
9999 || update_mode_lines
10000 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10001 < BUF_MODIFF (XBUFFER (w->buffer)))
10002 != !NILP (w->last_had_star))
10003 || ((!NILP (Vtransient_mark_mode)
10004 && !NILP (XBUFFER (w->buffer)->mark_active))
10005 != !NILP (w->region_showing)))
10006 {
10007 struct buffer *prev = current_buffer;
10008 int count = SPECPDL_INDEX ();
10009
10010 specbind (Qinhibit_menubar_update, Qt);
10011
10012 set_buffer_internal_1 (XBUFFER (w->buffer));
10013 if (save_match_data)
10014 record_unwind_save_match_data ();
10015 if (NILP (Voverriding_local_map_menu_flag))
10016 {
10017 specbind (Qoverriding_terminal_local_map, Qnil);
10018 specbind (Qoverriding_local_map, Qnil);
10019 }
10020
10021 if (!hooks_run)
10022 {
10023 /* Run the Lucid hook. */
10024 safe_run_hooks (Qactivate_menubar_hook);
10025
10026 /* If it has changed current-menubar from previous value,
10027 really recompute the menu-bar from the value. */
10028 if (! NILP (Vlucid_menu_bar_dirty_flag))
10029 call0 (Qrecompute_lucid_menubar);
10030
10031 safe_run_hooks (Qmenu_bar_update_hook);
10032
10033 hooks_run = 1;
10034 }
10035
10036 XSETFRAME (Vmenu_updating_frame, f);
10037 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
10038
10039 /* Redisplay the menu bar in case we changed it. */
10040 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
10041 || defined (HAVE_NS) || defined (USE_GTK)
10042 if (FRAME_WINDOW_P (f))
10043 {
10044 #if defined (HAVE_NS)
10045 /* All frames on Mac OS share the same menubar. So only
10046 the selected frame should be allowed to set it. */
10047 if (f == SELECTED_FRAME ())
10048 #endif
10049 set_frame_menubar (f, 0, 0);
10050 }
10051 else
10052 /* On a terminal screen, the menu bar is an ordinary screen
10053 line, and this makes it get updated. */
10054 w->update_mode_line = Qt;
10055 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10056 /* In the non-toolkit version, the menu bar is an ordinary screen
10057 line, and this makes it get updated. */
10058 w->update_mode_line = Qt;
10059 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10060
10061 unbind_to (count, Qnil);
10062 set_buffer_internal_1 (prev);
10063 }
10064 }
10065
10066 return hooks_run;
10067 }
10068
10069
10070 \f
10071 /***********************************************************************
10072 Output Cursor
10073 ***********************************************************************/
10074
10075 #ifdef HAVE_WINDOW_SYSTEM
10076
10077 /* EXPORT:
10078 Nominal cursor position -- where to draw output.
10079 HPOS and VPOS are window relative glyph matrix coordinates.
10080 X and Y are window relative pixel coordinates. */
10081
10082 struct cursor_pos output_cursor;
10083
10084
10085 /* EXPORT:
10086 Set the global variable output_cursor to CURSOR. All cursor
10087 positions are relative to updated_window. */
10088
10089 void
10090 set_output_cursor (cursor)
10091 struct cursor_pos *cursor;
10092 {
10093 output_cursor.hpos = cursor->hpos;
10094 output_cursor.vpos = cursor->vpos;
10095 output_cursor.x = cursor->x;
10096 output_cursor.y = cursor->y;
10097 }
10098
10099
10100 /* EXPORT for RIF:
10101 Set a nominal cursor position.
10102
10103 HPOS and VPOS are column/row positions in a window glyph matrix. X
10104 and Y are window text area relative pixel positions.
10105
10106 If this is done during an update, updated_window will contain the
10107 window that is being updated and the position is the future output
10108 cursor position for that window. If updated_window is null, use
10109 selected_window and display the cursor at the given position. */
10110
10111 void
10112 x_cursor_to (vpos, hpos, y, x)
10113 int vpos, hpos, y, x;
10114 {
10115 struct window *w;
10116
10117 /* If updated_window is not set, work on selected_window. */
10118 if (updated_window)
10119 w = updated_window;
10120 else
10121 w = XWINDOW (selected_window);
10122
10123 /* Set the output cursor. */
10124 output_cursor.hpos = hpos;
10125 output_cursor.vpos = vpos;
10126 output_cursor.x = x;
10127 output_cursor.y = y;
10128
10129 /* If not called as part of an update, really display the cursor.
10130 This will also set the cursor position of W. */
10131 if (updated_window == NULL)
10132 {
10133 BLOCK_INPUT;
10134 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10135 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10136 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10137 UNBLOCK_INPUT;
10138 }
10139 }
10140
10141 #endif /* HAVE_WINDOW_SYSTEM */
10142
10143 \f
10144 /***********************************************************************
10145 Tool-bars
10146 ***********************************************************************/
10147
10148 #ifdef HAVE_WINDOW_SYSTEM
10149
10150 /* Where the mouse was last time we reported a mouse event. */
10151
10152 FRAME_PTR last_mouse_frame;
10153
10154 /* Tool-bar item index of the item on which a mouse button was pressed
10155 or -1. */
10156
10157 int last_tool_bar_item;
10158
10159
10160 static Lisp_Object
10161 update_tool_bar_unwind (frame)
10162 Lisp_Object frame;
10163 {
10164 selected_frame = frame;
10165 return Qnil;
10166 }
10167
10168 /* Update the tool-bar item list for frame F. This has to be done
10169 before we start to fill in any display lines. Called from
10170 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10171 and restore it here. */
10172
10173 static void
10174 update_tool_bar (f, save_match_data)
10175 struct frame *f;
10176 int save_match_data;
10177 {
10178 #if defined (USE_GTK) || defined (HAVE_NS)
10179 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10180 #else
10181 int do_update = WINDOWP (f->tool_bar_window)
10182 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10183 #endif
10184
10185 if (do_update)
10186 {
10187 Lisp_Object window;
10188 struct window *w;
10189
10190 window = FRAME_SELECTED_WINDOW (f);
10191 w = XWINDOW (window);
10192
10193 /* If the user has switched buffers or windows, we need to
10194 recompute to reflect the new bindings. But we'll
10195 recompute when update_mode_lines is set too; that means
10196 that people can use force-mode-line-update to request
10197 that the menu bar be recomputed. The adverse effect on
10198 the rest of the redisplay algorithm is about the same as
10199 windows_or_buffers_changed anyway. */
10200 if (windows_or_buffers_changed
10201 || !NILP (w->update_mode_line)
10202 || update_mode_lines
10203 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10204 < BUF_MODIFF (XBUFFER (w->buffer)))
10205 != !NILP (w->last_had_star))
10206 || ((!NILP (Vtransient_mark_mode)
10207 && !NILP (XBUFFER (w->buffer)->mark_active))
10208 != !NILP (w->region_showing)))
10209 {
10210 struct buffer *prev = current_buffer;
10211 int count = SPECPDL_INDEX ();
10212 Lisp_Object frame, new_tool_bar;
10213 int new_n_tool_bar;
10214 struct gcpro gcpro1;
10215
10216 /* Set current_buffer to the buffer of the selected
10217 window of the frame, so that we get the right local
10218 keymaps. */
10219 set_buffer_internal_1 (XBUFFER (w->buffer));
10220
10221 /* Save match data, if we must. */
10222 if (save_match_data)
10223 record_unwind_save_match_data ();
10224
10225 /* Make sure that we don't accidentally use bogus keymaps. */
10226 if (NILP (Voverriding_local_map_menu_flag))
10227 {
10228 specbind (Qoverriding_terminal_local_map, Qnil);
10229 specbind (Qoverriding_local_map, Qnil);
10230 }
10231
10232 GCPRO1 (new_tool_bar);
10233
10234 /* We must temporarily set the selected frame to this frame
10235 before calling tool_bar_items, because the calculation of
10236 the tool-bar keymap uses the selected frame (see
10237 `tool-bar-make-keymap' in tool-bar.el). */
10238 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10239 XSETFRAME (frame, f);
10240 selected_frame = frame;
10241
10242 /* Build desired tool-bar items from keymaps. */
10243 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10244 &new_n_tool_bar);
10245
10246 /* Redisplay the tool-bar if we changed it. */
10247 if (new_n_tool_bar != f->n_tool_bar_items
10248 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10249 {
10250 /* Redisplay that happens asynchronously due to an expose event
10251 may access f->tool_bar_items. Make sure we update both
10252 variables within BLOCK_INPUT so no such event interrupts. */
10253 BLOCK_INPUT;
10254 f->tool_bar_items = new_tool_bar;
10255 f->n_tool_bar_items = new_n_tool_bar;
10256 w->update_mode_line = Qt;
10257 UNBLOCK_INPUT;
10258 }
10259
10260 UNGCPRO;
10261
10262 unbind_to (count, Qnil);
10263 set_buffer_internal_1 (prev);
10264 }
10265 }
10266 }
10267
10268
10269 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10270 F's desired tool-bar contents. F->tool_bar_items must have
10271 been set up previously by calling prepare_menu_bars. */
10272
10273 static void
10274 build_desired_tool_bar_string (f)
10275 struct frame *f;
10276 {
10277 int i, size, size_needed;
10278 struct gcpro gcpro1, gcpro2, gcpro3;
10279 Lisp_Object image, plist, props;
10280
10281 image = plist = props = Qnil;
10282 GCPRO3 (image, plist, props);
10283
10284 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10285 Otherwise, make a new string. */
10286
10287 /* The size of the string we might be able to reuse. */
10288 size = (STRINGP (f->desired_tool_bar_string)
10289 ? SCHARS (f->desired_tool_bar_string)
10290 : 0);
10291
10292 /* We need one space in the string for each image. */
10293 size_needed = f->n_tool_bar_items;
10294
10295 /* Reuse f->desired_tool_bar_string, if possible. */
10296 if (size < size_needed || NILP (f->desired_tool_bar_string))
10297 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10298 make_number (' '));
10299 else
10300 {
10301 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10302 Fremove_text_properties (make_number (0), make_number (size),
10303 props, f->desired_tool_bar_string);
10304 }
10305
10306 /* Put a `display' property on the string for the images to display,
10307 put a `menu_item' property on tool-bar items with a value that
10308 is the index of the item in F's tool-bar item vector. */
10309 for (i = 0; i < f->n_tool_bar_items; ++i)
10310 {
10311 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10312
10313 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10314 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10315 int hmargin, vmargin, relief, idx, end;
10316 extern Lisp_Object QCrelief, QCmargin, QCconversion;
10317
10318 /* If image is a vector, choose the image according to the
10319 button state. */
10320 image = PROP (TOOL_BAR_ITEM_IMAGES);
10321 if (VECTORP (image))
10322 {
10323 if (enabled_p)
10324 idx = (selected_p
10325 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10326 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10327 else
10328 idx = (selected_p
10329 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10330 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10331
10332 xassert (ASIZE (image) >= idx);
10333 image = AREF (image, idx);
10334 }
10335 else
10336 idx = -1;
10337
10338 /* Ignore invalid image specifications. */
10339 if (!valid_image_p (image))
10340 continue;
10341
10342 /* Display the tool-bar button pressed, or depressed. */
10343 plist = Fcopy_sequence (XCDR (image));
10344
10345 /* Compute margin and relief to draw. */
10346 relief = (tool_bar_button_relief >= 0
10347 ? tool_bar_button_relief
10348 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10349 hmargin = vmargin = relief;
10350
10351 if (INTEGERP (Vtool_bar_button_margin)
10352 && XINT (Vtool_bar_button_margin) > 0)
10353 {
10354 hmargin += XFASTINT (Vtool_bar_button_margin);
10355 vmargin += XFASTINT (Vtool_bar_button_margin);
10356 }
10357 else if (CONSP (Vtool_bar_button_margin))
10358 {
10359 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10360 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10361 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10362
10363 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10364 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10365 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10366 }
10367
10368 if (auto_raise_tool_bar_buttons_p)
10369 {
10370 /* Add a `:relief' property to the image spec if the item is
10371 selected. */
10372 if (selected_p)
10373 {
10374 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10375 hmargin -= relief;
10376 vmargin -= relief;
10377 }
10378 }
10379 else
10380 {
10381 /* If image is selected, display it pressed, i.e. with a
10382 negative relief. If it's not selected, display it with a
10383 raised relief. */
10384 plist = Fplist_put (plist, QCrelief,
10385 (selected_p
10386 ? make_number (-relief)
10387 : make_number (relief)));
10388 hmargin -= relief;
10389 vmargin -= relief;
10390 }
10391
10392 /* Put a margin around the image. */
10393 if (hmargin || vmargin)
10394 {
10395 if (hmargin == vmargin)
10396 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10397 else
10398 plist = Fplist_put (plist, QCmargin,
10399 Fcons (make_number (hmargin),
10400 make_number (vmargin)));
10401 }
10402
10403 /* If button is not enabled, and we don't have special images
10404 for the disabled state, make the image appear disabled by
10405 applying an appropriate algorithm to it. */
10406 if (!enabled_p && idx < 0)
10407 plist = Fplist_put (plist, QCconversion, Qdisabled);
10408
10409 /* Put a `display' text property on the string for the image to
10410 display. Put a `menu-item' property on the string that gives
10411 the start of this item's properties in the tool-bar items
10412 vector. */
10413 image = Fcons (Qimage, plist);
10414 props = list4 (Qdisplay, image,
10415 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10416
10417 /* Let the last image hide all remaining spaces in the tool bar
10418 string. The string can be longer than needed when we reuse a
10419 previous string. */
10420 if (i + 1 == f->n_tool_bar_items)
10421 end = SCHARS (f->desired_tool_bar_string);
10422 else
10423 end = i + 1;
10424 Fadd_text_properties (make_number (i), make_number (end),
10425 props, f->desired_tool_bar_string);
10426 #undef PROP
10427 }
10428
10429 UNGCPRO;
10430 }
10431
10432
10433 /* Display one line of the tool-bar of frame IT->f.
10434
10435 HEIGHT specifies the desired height of the tool-bar line.
10436 If the actual height of the glyph row is less than HEIGHT, the
10437 row's height is increased to HEIGHT, and the icons are centered
10438 vertically in the new height.
10439
10440 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10441 count a final empty row in case the tool-bar width exactly matches
10442 the window width.
10443 */
10444
10445 static void
10446 display_tool_bar_line (it, height)
10447 struct it *it;
10448 int height;
10449 {
10450 struct glyph_row *row = it->glyph_row;
10451 int max_x = it->last_visible_x;
10452 struct glyph *last;
10453
10454 prepare_desired_row (row);
10455 row->y = it->current_y;
10456
10457 /* Note that this isn't made use of if the face hasn't a box,
10458 so there's no need to check the face here. */
10459 it->start_of_box_run_p = 1;
10460
10461 while (it->current_x < max_x)
10462 {
10463 int x, n_glyphs_before, i, nglyphs;
10464 struct it it_before;
10465
10466 /* Get the next display element. */
10467 if (!get_next_display_element (it))
10468 {
10469 /* Don't count empty row if we are counting needed tool-bar lines. */
10470 if (height < 0 && !it->hpos)
10471 return;
10472 break;
10473 }
10474
10475 /* Produce glyphs. */
10476 n_glyphs_before = row->used[TEXT_AREA];
10477 it_before = *it;
10478
10479 PRODUCE_GLYPHS (it);
10480
10481 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10482 i = 0;
10483 x = it_before.current_x;
10484 while (i < nglyphs)
10485 {
10486 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10487
10488 if (x + glyph->pixel_width > max_x)
10489 {
10490 /* Glyph doesn't fit on line. Backtrack. */
10491 row->used[TEXT_AREA] = n_glyphs_before;
10492 *it = it_before;
10493 /* If this is the only glyph on this line, it will never fit on the
10494 toolbar, so skip it. But ensure there is at least one glyph,
10495 so we don't accidentally disable the tool-bar. */
10496 if (n_glyphs_before == 0
10497 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10498 break;
10499 goto out;
10500 }
10501
10502 ++it->hpos;
10503 x += glyph->pixel_width;
10504 ++i;
10505 }
10506
10507 /* Stop at line ends. */
10508 if (ITERATOR_AT_END_OF_LINE_P (it))
10509 break;
10510
10511 set_iterator_to_next (it, 1);
10512 }
10513
10514 out:;
10515
10516 row->displays_text_p = row->used[TEXT_AREA] != 0;
10517
10518 /* Use default face for the border below the tool bar.
10519
10520 FIXME: When auto-resize-tool-bars is grow-only, there is
10521 no additional border below the possibly empty tool-bar lines.
10522 So to make the extra empty lines look "normal", we have to
10523 use the tool-bar face for the border too. */
10524 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10525 it->face_id = DEFAULT_FACE_ID;
10526
10527 extend_face_to_end_of_line (it);
10528 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10529 last->right_box_line_p = 1;
10530 if (last == row->glyphs[TEXT_AREA])
10531 last->left_box_line_p = 1;
10532
10533 /* Make line the desired height and center it vertically. */
10534 if ((height -= it->max_ascent + it->max_descent) > 0)
10535 {
10536 /* Don't add more than one line height. */
10537 height %= FRAME_LINE_HEIGHT (it->f);
10538 it->max_ascent += height / 2;
10539 it->max_descent += (height + 1) / 2;
10540 }
10541
10542 compute_line_metrics (it);
10543
10544 /* If line is empty, make it occupy the rest of the tool-bar. */
10545 if (!row->displays_text_p)
10546 {
10547 row->height = row->phys_height = it->last_visible_y - row->y;
10548 row->visible_height = row->height;
10549 row->ascent = row->phys_ascent = 0;
10550 row->extra_line_spacing = 0;
10551 }
10552
10553 row->full_width_p = 1;
10554 row->continued_p = 0;
10555 row->truncated_on_left_p = 0;
10556 row->truncated_on_right_p = 0;
10557
10558 it->current_x = it->hpos = 0;
10559 it->current_y += row->height;
10560 ++it->vpos;
10561 ++it->glyph_row;
10562 }
10563
10564
10565 /* Max tool-bar height. */
10566
10567 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10568 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10569
10570 /* Value is the number of screen lines needed to make all tool-bar
10571 items of frame F visible. The number of actual rows needed is
10572 returned in *N_ROWS if non-NULL. */
10573
10574 static int
10575 tool_bar_lines_needed (f, n_rows)
10576 struct frame *f;
10577 int *n_rows;
10578 {
10579 struct window *w = XWINDOW (f->tool_bar_window);
10580 struct it it;
10581 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10582 the desired matrix, so use (unused) mode-line row as temporary row to
10583 avoid destroying the first tool-bar row. */
10584 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10585
10586 /* Initialize an iterator for iteration over
10587 F->desired_tool_bar_string in the tool-bar window of frame F. */
10588 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10589 it.first_visible_x = 0;
10590 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10591 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10592
10593 while (!ITERATOR_AT_END_P (&it))
10594 {
10595 clear_glyph_row (temp_row);
10596 it.glyph_row = temp_row;
10597 display_tool_bar_line (&it, -1);
10598 }
10599 clear_glyph_row (temp_row);
10600
10601 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10602 if (n_rows)
10603 *n_rows = it.vpos > 0 ? it.vpos : -1;
10604
10605 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10606 }
10607
10608
10609 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10610 0, 1, 0,
10611 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10612 (frame)
10613 Lisp_Object frame;
10614 {
10615 struct frame *f;
10616 struct window *w;
10617 int nlines = 0;
10618
10619 if (NILP (frame))
10620 frame = selected_frame;
10621 else
10622 CHECK_FRAME (frame);
10623 f = XFRAME (frame);
10624
10625 if (WINDOWP (f->tool_bar_window)
10626 || (w = XWINDOW (f->tool_bar_window),
10627 WINDOW_TOTAL_LINES (w) > 0))
10628 {
10629 update_tool_bar (f, 1);
10630 if (f->n_tool_bar_items)
10631 {
10632 build_desired_tool_bar_string (f);
10633 nlines = tool_bar_lines_needed (f, NULL);
10634 }
10635 }
10636
10637 return make_number (nlines);
10638 }
10639
10640
10641 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10642 height should be changed. */
10643
10644 static int
10645 redisplay_tool_bar (f)
10646 struct frame *f;
10647 {
10648 struct window *w;
10649 struct it it;
10650 struct glyph_row *row;
10651
10652 #if defined (USE_GTK) || defined (HAVE_NS)
10653 if (FRAME_EXTERNAL_TOOL_BAR (f))
10654 update_frame_tool_bar (f);
10655 return 0;
10656 #endif
10657
10658 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10659 do anything. This means you must start with tool-bar-lines
10660 non-zero to get the auto-sizing effect. Or in other words, you
10661 can turn off tool-bars by specifying tool-bar-lines zero. */
10662 if (!WINDOWP (f->tool_bar_window)
10663 || (w = XWINDOW (f->tool_bar_window),
10664 WINDOW_TOTAL_LINES (w) == 0))
10665 return 0;
10666
10667 /* Set up an iterator for the tool-bar window. */
10668 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10669 it.first_visible_x = 0;
10670 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10671 row = it.glyph_row;
10672
10673 /* Build a string that represents the contents of the tool-bar. */
10674 build_desired_tool_bar_string (f);
10675 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10676
10677 if (f->n_tool_bar_rows == 0)
10678 {
10679 int nlines;
10680
10681 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10682 nlines != WINDOW_TOTAL_LINES (w)))
10683 {
10684 extern Lisp_Object Qtool_bar_lines;
10685 Lisp_Object frame;
10686 int old_height = WINDOW_TOTAL_LINES (w);
10687
10688 XSETFRAME (frame, f);
10689 Fmodify_frame_parameters (frame,
10690 Fcons (Fcons (Qtool_bar_lines,
10691 make_number (nlines)),
10692 Qnil));
10693 if (WINDOW_TOTAL_LINES (w) != old_height)
10694 {
10695 clear_glyph_matrix (w->desired_matrix);
10696 fonts_changed_p = 1;
10697 return 1;
10698 }
10699 }
10700 }
10701
10702 /* Display as many lines as needed to display all tool-bar items. */
10703
10704 if (f->n_tool_bar_rows > 0)
10705 {
10706 int border, rows, height, extra;
10707
10708 if (INTEGERP (Vtool_bar_border))
10709 border = XINT (Vtool_bar_border);
10710 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10711 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10712 else if (EQ (Vtool_bar_border, Qborder_width))
10713 border = f->border_width;
10714 else
10715 border = 0;
10716 if (border < 0)
10717 border = 0;
10718
10719 rows = f->n_tool_bar_rows;
10720 height = max (1, (it.last_visible_y - border) / rows);
10721 extra = it.last_visible_y - border - height * rows;
10722
10723 while (it.current_y < it.last_visible_y)
10724 {
10725 int h = 0;
10726 if (extra > 0 && rows-- > 0)
10727 {
10728 h = (extra + rows - 1) / rows;
10729 extra -= h;
10730 }
10731 display_tool_bar_line (&it, height + h);
10732 }
10733 }
10734 else
10735 {
10736 while (it.current_y < it.last_visible_y)
10737 display_tool_bar_line (&it, 0);
10738 }
10739
10740 /* It doesn't make much sense to try scrolling in the tool-bar
10741 window, so don't do it. */
10742 w->desired_matrix->no_scrolling_p = 1;
10743 w->must_be_updated_p = 1;
10744
10745 if (!NILP (Vauto_resize_tool_bars))
10746 {
10747 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10748 int change_height_p = 0;
10749
10750 /* If we couldn't display everything, change the tool-bar's
10751 height if there is room for more. */
10752 if (IT_STRING_CHARPOS (it) < it.end_charpos
10753 && it.current_y < max_tool_bar_height)
10754 change_height_p = 1;
10755
10756 row = it.glyph_row - 1;
10757
10758 /* If there are blank lines at the end, except for a partially
10759 visible blank line at the end that is smaller than
10760 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10761 if (!row->displays_text_p
10762 && row->height >= FRAME_LINE_HEIGHT (f))
10763 change_height_p = 1;
10764
10765 /* If row displays tool-bar items, but is partially visible,
10766 change the tool-bar's height. */
10767 if (row->displays_text_p
10768 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10769 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10770 change_height_p = 1;
10771
10772 /* Resize windows as needed by changing the `tool-bar-lines'
10773 frame parameter. */
10774 if (change_height_p)
10775 {
10776 extern Lisp_Object Qtool_bar_lines;
10777 Lisp_Object frame;
10778 int old_height = WINDOW_TOTAL_LINES (w);
10779 int nrows;
10780 int nlines = tool_bar_lines_needed (f, &nrows);
10781
10782 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10783 && !f->minimize_tool_bar_window_p)
10784 ? (nlines > old_height)
10785 : (nlines != old_height));
10786 f->minimize_tool_bar_window_p = 0;
10787
10788 if (change_height_p)
10789 {
10790 XSETFRAME (frame, f);
10791 Fmodify_frame_parameters (frame,
10792 Fcons (Fcons (Qtool_bar_lines,
10793 make_number (nlines)),
10794 Qnil));
10795 if (WINDOW_TOTAL_LINES (w) != old_height)
10796 {
10797 clear_glyph_matrix (w->desired_matrix);
10798 f->n_tool_bar_rows = nrows;
10799 fonts_changed_p = 1;
10800 return 1;
10801 }
10802 }
10803 }
10804 }
10805
10806 f->minimize_tool_bar_window_p = 0;
10807 return 0;
10808 }
10809
10810
10811 /* Get information about the tool-bar item which is displayed in GLYPH
10812 on frame F. Return in *PROP_IDX the index where tool-bar item
10813 properties start in F->tool_bar_items. Value is zero if
10814 GLYPH doesn't display a tool-bar item. */
10815
10816 static int
10817 tool_bar_item_info (f, glyph, prop_idx)
10818 struct frame *f;
10819 struct glyph *glyph;
10820 int *prop_idx;
10821 {
10822 Lisp_Object prop;
10823 int success_p;
10824 int charpos;
10825
10826 /* This function can be called asynchronously, which means we must
10827 exclude any possibility that Fget_text_property signals an
10828 error. */
10829 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10830 charpos = max (0, charpos);
10831
10832 /* Get the text property `menu-item' at pos. The value of that
10833 property is the start index of this item's properties in
10834 F->tool_bar_items. */
10835 prop = Fget_text_property (make_number (charpos),
10836 Qmenu_item, f->current_tool_bar_string);
10837 if (INTEGERP (prop))
10838 {
10839 *prop_idx = XINT (prop);
10840 success_p = 1;
10841 }
10842 else
10843 success_p = 0;
10844
10845 return success_p;
10846 }
10847
10848 \f
10849 /* Get information about the tool-bar item at position X/Y on frame F.
10850 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10851 the current matrix of the tool-bar window of F, or NULL if not
10852 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10853 item in F->tool_bar_items. Value is
10854
10855 -1 if X/Y is not on a tool-bar item
10856 0 if X/Y is on the same item that was highlighted before.
10857 1 otherwise. */
10858
10859 static int
10860 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
10861 struct frame *f;
10862 int x, y;
10863 struct glyph **glyph;
10864 int *hpos, *vpos, *prop_idx;
10865 {
10866 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10867 struct window *w = XWINDOW (f->tool_bar_window);
10868 int area;
10869
10870 /* Find the glyph under X/Y. */
10871 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10872 if (*glyph == NULL)
10873 return -1;
10874
10875 /* Get the start of this tool-bar item's properties in
10876 f->tool_bar_items. */
10877 if (!tool_bar_item_info (f, *glyph, prop_idx))
10878 return -1;
10879
10880 /* Is mouse on the highlighted item? */
10881 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10882 && *vpos >= dpyinfo->mouse_face_beg_row
10883 && *vpos <= dpyinfo->mouse_face_end_row
10884 && (*vpos > dpyinfo->mouse_face_beg_row
10885 || *hpos >= dpyinfo->mouse_face_beg_col)
10886 && (*vpos < dpyinfo->mouse_face_end_row
10887 || *hpos < dpyinfo->mouse_face_end_col
10888 || dpyinfo->mouse_face_past_end))
10889 return 0;
10890
10891 return 1;
10892 }
10893
10894
10895 /* EXPORT:
10896 Handle mouse button event on the tool-bar of frame F, at
10897 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10898 0 for button release. MODIFIERS is event modifiers for button
10899 release. */
10900
10901 void
10902 handle_tool_bar_click (f, x, y, down_p, modifiers)
10903 struct frame *f;
10904 int x, y, down_p;
10905 unsigned int modifiers;
10906 {
10907 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10908 struct window *w = XWINDOW (f->tool_bar_window);
10909 int hpos, vpos, prop_idx;
10910 struct glyph *glyph;
10911 Lisp_Object enabled_p;
10912
10913 /* If not on the highlighted tool-bar item, return. */
10914 frame_to_window_pixel_xy (w, &x, &y);
10915 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10916 return;
10917
10918 /* If item is disabled, do nothing. */
10919 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10920 if (NILP (enabled_p))
10921 return;
10922
10923 if (down_p)
10924 {
10925 /* Show item in pressed state. */
10926 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10927 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10928 last_tool_bar_item = prop_idx;
10929 }
10930 else
10931 {
10932 Lisp_Object key, frame;
10933 struct input_event event;
10934 EVENT_INIT (event);
10935
10936 /* Show item in released state. */
10937 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10938 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10939
10940 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10941
10942 XSETFRAME (frame, f);
10943 event.kind = TOOL_BAR_EVENT;
10944 event.frame_or_window = frame;
10945 event.arg = frame;
10946 kbd_buffer_store_event (&event);
10947
10948 event.kind = TOOL_BAR_EVENT;
10949 event.frame_or_window = frame;
10950 event.arg = key;
10951 event.modifiers = modifiers;
10952 kbd_buffer_store_event (&event);
10953 last_tool_bar_item = -1;
10954 }
10955 }
10956
10957
10958 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10959 tool-bar window-relative coordinates X/Y. Called from
10960 note_mouse_highlight. */
10961
10962 static void
10963 note_tool_bar_highlight (f, x, y)
10964 struct frame *f;
10965 int x, y;
10966 {
10967 Lisp_Object window = f->tool_bar_window;
10968 struct window *w = XWINDOW (window);
10969 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10970 int hpos, vpos;
10971 struct glyph *glyph;
10972 struct glyph_row *row;
10973 int i;
10974 Lisp_Object enabled_p;
10975 int prop_idx;
10976 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10977 int mouse_down_p, rc;
10978
10979 /* Function note_mouse_highlight is called with negative x(y
10980 values when mouse moves outside of the frame. */
10981 if (x <= 0 || y <= 0)
10982 {
10983 clear_mouse_face (dpyinfo);
10984 return;
10985 }
10986
10987 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10988 if (rc < 0)
10989 {
10990 /* Not on tool-bar item. */
10991 clear_mouse_face (dpyinfo);
10992 return;
10993 }
10994 else if (rc == 0)
10995 /* On same tool-bar item as before. */
10996 goto set_help_echo;
10997
10998 clear_mouse_face (dpyinfo);
10999
11000 /* Mouse is down, but on different tool-bar item? */
11001 mouse_down_p = (dpyinfo->grabbed
11002 && f == last_mouse_frame
11003 && FRAME_LIVE_P (f));
11004 if (mouse_down_p
11005 && last_tool_bar_item != prop_idx)
11006 return;
11007
11008 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
11009 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
11010
11011 /* If tool-bar item is not enabled, don't highlight it. */
11012 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
11013 if (!NILP (enabled_p))
11014 {
11015 /* Compute the x-position of the glyph. In front and past the
11016 image is a space. We include this in the highlighted area. */
11017 row = MATRIX_ROW (w->current_matrix, vpos);
11018 for (i = x = 0; i < hpos; ++i)
11019 x += row->glyphs[TEXT_AREA][i].pixel_width;
11020
11021 /* Record this as the current active region. */
11022 dpyinfo->mouse_face_beg_col = hpos;
11023 dpyinfo->mouse_face_beg_row = vpos;
11024 dpyinfo->mouse_face_beg_x = x;
11025 dpyinfo->mouse_face_beg_y = row->y;
11026 dpyinfo->mouse_face_past_end = 0;
11027
11028 dpyinfo->mouse_face_end_col = hpos + 1;
11029 dpyinfo->mouse_face_end_row = vpos;
11030 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
11031 dpyinfo->mouse_face_end_y = row->y;
11032 dpyinfo->mouse_face_window = window;
11033 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
11034
11035 /* Display it as active. */
11036 show_mouse_face (dpyinfo, draw);
11037 dpyinfo->mouse_face_image_state = draw;
11038 }
11039
11040 set_help_echo:
11041
11042 /* Set help_echo_string to a help string to display for this tool-bar item.
11043 XTread_socket does the rest. */
11044 help_echo_object = help_echo_window = Qnil;
11045 help_echo_pos = -1;
11046 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
11047 if (NILP (help_echo_string))
11048 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
11049 }
11050
11051 #endif /* HAVE_WINDOW_SYSTEM */
11052
11053
11054 \f
11055 /************************************************************************
11056 Horizontal scrolling
11057 ************************************************************************/
11058
11059 static int hscroll_window_tree P_ ((Lisp_Object));
11060 static int hscroll_windows P_ ((Lisp_Object));
11061
11062 /* For all leaf windows in the window tree rooted at WINDOW, set their
11063 hscroll value so that PT is (i) visible in the window, and (ii) so
11064 that it is not within a certain margin at the window's left and
11065 right border. Value is non-zero if any window's hscroll has been
11066 changed. */
11067
11068 static int
11069 hscroll_window_tree (window)
11070 Lisp_Object window;
11071 {
11072 int hscrolled_p = 0;
11073 int hscroll_relative_p = FLOATP (Vhscroll_step);
11074 int hscroll_step_abs = 0;
11075 double hscroll_step_rel = 0;
11076
11077 if (hscroll_relative_p)
11078 {
11079 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
11080 if (hscroll_step_rel < 0)
11081 {
11082 hscroll_relative_p = 0;
11083 hscroll_step_abs = 0;
11084 }
11085 }
11086 else if (INTEGERP (Vhscroll_step))
11087 {
11088 hscroll_step_abs = XINT (Vhscroll_step);
11089 if (hscroll_step_abs < 0)
11090 hscroll_step_abs = 0;
11091 }
11092 else
11093 hscroll_step_abs = 0;
11094
11095 while (WINDOWP (window))
11096 {
11097 struct window *w = XWINDOW (window);
11098
11099 if (WINDOWP (w->hchild))
11100 hscrolled_p |= hscroll_window_tree (w->hchild);
11101 else if (WINDOWP (w->vchild))
11102 hscrolled_p |= hscroll_window_tree (w->vchild);
11103 else if (w->cursor.vpos >= 0)
11104 {
11105 int h_margin;
11106 int text_area_width;
11107 struct glyph_row *current_cursor_row
11108 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
11109 struct glyph_row *desired_cursor_row
11110 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
11111 struct glyph_row *cursor_row
11112 = (desired_cursor_row->enabled_p
11113 ? desired_cursor_row
11114 : current_cursor_row);
11115
11116 text_area_width = window_box_width (w, TEXT_AREA);
11117
11118 /* Scroll when cursor is inside this scroll margin. */
11119 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11120
11121 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11122 && ((XFASTINT (w->hscroll)
11123 && w->cursor.x <= h_margin)
11124 || (cursor_row->enabled_p
11125 && cursor_row->truncated_on_right_p
11126 && (w->cursor.x >= text_area_width - h_margin))))
11127 {
11128 struct it it;
11129 int hscroll;
11130 struct buffer *saved_current_buffer;
11131 int pt;
11132 int wanted_x;
11133
11134 /* Find point in a display of infinite width. */
11135 saved_current_buffer = current_buffer;
11136 current_buffer = XBUFFER (w->buffer);
11137
11138 if (w == XWINDOW (selected_window))
11139 pt = BUF_PT (current_buffer);
11140 else
11141 {
11142 pt = marker_position (w->pointm);
11143 pt = max (BEGV, pt);
11144 pt = min (ZV, pt);
11145 }
11146
11147 /* Move iterator to pt starting at cursor_row->start in
11148 a line with infinite width. */
11149 init_to_row_start (&it, w, cursor_row);
11150 it.last_visible_x = INFINITY;
11151 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11152 current_buffer = saved_current_buffer;
11153
11154 /* Position cursor in window. */
11155 if (!hscroll_relative_p && hscroll_step_abs == 0)
11156 hscroll = max (0, (it.current_x
11157 - (ITERATOR_AT_END_OF_LINE_P (&it)
11158 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11159 : (text_area_width / 2))))
11160 / FRAME_COLUMN_WIDTH (it.f);
11161 else if (w->cursor.x >= text_area_width - h_margin)
11162 {
11163 if (hscroll_relative_p)
11164 wanted_x = text_area_width * (1 - hscroll_step_rel)
11165 - h_margin;
11166 else
11167 wanted_x = text_area_width
11168 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11169 - h_margin;
11170 hscroll
11171 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11172 }
11173 else
11174 {
11175 if (hscroll_relative_p)
11176 wanted_x = text_area_width * hscroll_step_rel
11177 + h_margin;
11178 else
11179 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11180 + h_margin;
11181 hscroll
11182 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11183 }
11184 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11185
11186 /* Don't call Fset_window_hscroll if value hasn't
11187 changed because it will prevent redisplay
11188 optimizations. */
11189 if (XFASTINT (w->hscroll) != hscroll)
11190 {
11191 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11192 w->hscroll = make_number (hscroll);
11193 hscrolled_p = 1;
11194 }
11195 }
11196 }
11197
11198 window = w->next;
11199 }
11200
11201 /* Value is non-zero if hscroll of any leaf window has been changed. */
11202 return hscrolled_p;
11203 }
11204
11205
11206 /* Set hscroll so that cursor is visible and not inside horizontal
11207 scroll margins for all windows in the tree rooted at WINDOW. See
11208 also hscroll_window_tree above. Value is non-zero if any window's
11209 hscroll has been changed. If it has, desired matrices on the frame
11210 of WINDOW are cleared. */
11211
11212 static int
11213 hscroll_windows (window)
11214 Lisp_Object window;
11215 {
11216 int hscrolled_p = hscroll_window_tree (window);
11217 if (hscrolled_p)
11218 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11219 return hscrolled_p;
11220 }
11221
11222
11223 \f
11224 /************************************************************************
11225 Redisplay
11226 ************************************************************************/
11227
11228 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11229 to a non-zero value. This is sometimes handy to have in a debugger
11230 session. */
11231
11232 #if GLYPH_DEBUG
11233
11234 /* First and last unchanged row for try_window_id. */
11235
11236 int debug_first_unchanged_at_end_vpos;
11237 int debug_last_unchanged_at_beg_vpos;
11238
11239 /* Delta vpos and y. */
11240
11241 int debug_dvpos, debug_dy;
11242
11243 /* Delta in characters and bytes for try_window_id. */
11244
11245 int debug_delta, debug_delta_bytes;
11246
11247 /* Values of window_end_pos and window_end_vpos at the end of
11248 try_window_id. */
11249
11250 EMACS_INT debug_end_pos, debug_end_vpos;
11251
11252 /* Append a string to W->desired_matrix->method. FMT is a printf
11253 format string. A1...A9 are a supplement for a variable-length
11254 argument list. If trace_redisplay_p is non-zero also printf the
11255 resulting string to stderr. */
11256
11257 static void
11258 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11259 struct window *w;
11260 char *fmt;
11261 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11262 {
11263 char buffer[512];
11264 char *method = w->desired_matrix->method;
11265 int len = strlen (method);
11266 int size = sizeof w->desired_matrix->method;
11267 int remaining = size - len - 1;
11268
11269 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11270 if (len && remaining)
11271 {
11272 method[len] = '|';
11273 --remaining, ++len;
11274 }
11275
11276 strncpy (method + len, buffer, remaining);
11277
11278 if (trace_redisplay_p)
11279 fprintf (stderr, "%p (%s): %s\n",
11280 w,
11281 ((BUFFERP (w->buffer)
11282 && STRINGP (XBUFFER (w->buffer)->name))
11283 ? (char *) SDATA (XBUFFER (w->buffer)->name)
11284 : "no buffer"),
11285 buffer);
11286 }
11287
11288 #endif /* GLYPH_DEBUG */
11289
11290
11291 /* Value is non-zero if all changes in window W, which displays
11292 current_buffer, are in the text between START and END. START is a
11293 buffer position, END is given as a distance from Z. Used in
11294 redisplay_internal for display optimization. */
11295
11296 static INLINE int
11297 text_outside_line_unchanged_p (w, start, end)
11298 struct window *w;
11299 int start, end;
11300 {
11301 int unchanged_p = 1;
11302
11303 /* If text or overlays have changed, see where. */
11304 if (XFASTINT (w->last_modified) < MODIFF
11305 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11306 {
11307 /* Gap in the line? */
11308 if (GPT < start || Z - GPT < end)
11309 unchanged_p = 0;
11310
11311 /* Changes start in front of the line, or end after it? */
11312 if (unchanged_p
11313 && (BEG_UNCHANGED < start - 1
11314 || END_UNCHANGED < end))
11315 unchanged_p = 0;
11316
11317 /* If selective display, can't optimize if changes start at the
11318 beginning of the line. */
11319 if (unchanged_p
11320 && INTEGERP (current_buffer->selective_display)
11321 && XINT (current_buffer->selective_display) > 0
11322 && (BEG_UNCHANGED < start || GPT <= start))
11323 unchanged_p = 0;
11324
11325 /* If there are overlays at the start or end of the line, these
11326 may have overlay strings with newlines in them. A change at
11327 START, for instance, may actually concern the display of such
11328 overlay strings as well, and they are displayed on different
11329 lines. So, quickly rule out this case. (For the future, it
11330 might be desirable to implement something more telling than
11331 just BEG/END_UNCHANGED.) */
11332 if (unchanged_p)
11333 {
11334 if (BEG + BEG_UNCHANGED == start
11335 && overlay_touches_p (start))
11336 unchanged_p = 0;
11337 if (END_UNCHANGED == end
11338 && overlay_touches_p (Z - end))
11339 unchanged_p = 0;
11340 }
11341
11342 /* Under bidi reordering, adding or deleting a character in the
11343 beginning of a paragraph, before the first strong directional
11344 character, can change the base direction of the paragraph (unless
11345 the buffer specifies a fixed paragraph direction), which will
11346 require to redisplay the whole paragraph. It might be worthwhile
11347 to find the paragraph limits and widen the range of redisplayed
11348 lines to that, but for now just give up this optimization. */
11349 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
11350 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
11351 unchanged_p = 0;
11352 }
11353
11354 return unchanged_p;
11355 }
11356
11357
11358 /* Do a frame update, taking possible shortcuts into account. This is
11359 the main external entry point for redisplay.
11360
11361 If the last redisplay displayed an echo area message and that message
11362 is no longer requested, we clear the echo area or bring back the
11363 mini-buffer if that is in use. */
11364
11365 void
11366 redisplay ()
11367 {
11368 redisplay_internal (0);
11369 }
11370
11371
11372 static Lisp_Object
11373 overlay_arrow_string_or_property (var)
11374 Lisp_Object var;
11375 {
11376 Lisp_Object val;
11377
11378 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11379 return val;
11380
11381 return Voverlay_arrow_string;
11382 }
11383
11384 /* Return 1 if there are any overlay-arrows in current_buffer. */
11385 static int
11386 overlay_arrow_in_current_buffer_p ()
11387 {
11388 Lisp_Object vlist;
11389
11390 for (vlist = Voverlay_arrow_variable_list;
11391 CONSP (vlist);
11392 vlist = XCDR (vlist))
11393 {
11394 Lisp_Object var = XCAR (vlist);
11395 Lisp_Object val;
11396
11397 if (!SYMBOLP (var))
11398 continue;
11399 val = find_symbol_value (var);
11400 if (MARKERP (val)
11401 && current_buffer == XMARKER (val)->buffer)
11402 return 1;
11403 }
11404 return 0;
11405 }
11406
11407
11408 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11409 has changed. */
11410
11411 static int
11412 overlay_arrows_changed_p ()
11413 {
11414 Lisp_Object vlist;
11415
11416 for (vlist = Voverlay_arrow_variable_list;
11417 CONSP (vlist);
11418 vlist = XCDR (vlist))
11419 {
11420 Lisp_Object var = XCAR (vlist);
11421 Lisp_Object val, pstr;
11422
11423 if (!SYMBOLP (var))
11424 continue;
11425 val = find_symbol_value (var);
11426 if (!MARKERP (val))
11427 continue;
11428 if (! EQ (COERCE_MARKER (val),
11429 Fget (var, Qlast_arrow_position))
11430 || ! (pstr = overlay_arrow_string_or_property (var),
11431 EQ (pstr, Fget (var, Qlast_arrow_string))))
11432 return 1;
11433 }
11434 return 0;
11435 }
11436
11437 /* Mark overlay arrows to be updated on next redisplay. */
11438
11439 static void
11440 update_overlay_arrows (up_to_date)
11441 int up_to_date;
11442 {
11443 Lisp_Object vlist;
11444
11445 for (vlist = Voverlay_arrow_variable_list;
11446 CONSP (vlist);
11447 vlist = XCDR (vlist))
11448 {
11449 Lisp_Object var = XCAR (vlist);
11450
11451 if (!SYMBOLP (var))
11452 continue;
11453
11454 if (up_to_date > 0)
11455 {
11456 Lisp_Object val = find_symbol_value (var);
11457 Fput (var, Qlast_arrow_position,
11458 COERCE_MARKER (val));
11459 Fput (var, Qlast_arrow_string,
11460 overlay_arrow_string_or_property (var));
11461 }
11462 else if (up_to_date < 0
11463 || !NILP (Fget (var, Qlast_arrow_position)))
11464 {
11465 Fput (var, Qlast_arrow_position, Qt);
11466 Fput (var, Qlast_arrow_string, Qt);
11467 }
11468 }
11469 }
11470
11471
11472 /* Return overlay arrow string to display at row.
11473 Return integer (bitmap number) for arrow bitmap in left fringe.
11474 Return nil if no overlay arrow. */
11475
11476 static Lisp_Object
11477 overlay_arrow_at_row (it, row)
11478 struct it *it;
11479 struct glyph_row *row;
11480 {
11481 Lisp_Object vlist;
11482
11483 for (vlist = Voverlay_arrow_variable_list;
11484 CONSP (vlist);
11485 vlist = XCDR (vlist))
11486 {
11487 Lisp_Object var = XCAR (vlist);
11488 Lisp_Object val;
11489
11490 if (!SYMBOLP (var))
11491 continue;
11492
11493 val = find_symbol_value (var);
11494
11495 if (MARKERP (val)
11496 && current_buffer == XMARKER (val)->buffer
11497 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11498 {
11499 if (FRAME_WINDOW_P (it->f)
11500 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11501 {
11502 #ifdef HAVE_WINDOW_SYSTEM
11503 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11504 {
11505 int fringe_bitmap;
11506 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11507 return make_number (fringe_bitmap);
11508 }
11509 #endif
11510 return make_number (-1); /* Use default arrow bitmap */
11511 }
11512 return overlay_arrow_string_or_property (var);
11513 }
11514 }
11515
11516 return Qnil;
11517 }
11518
11519 /* Return 1 if point moved out of or into a composition. Otherwise
11520 return 0. PREV_BUF and PREV_PT are the last point buffer and
11521 position. BUF and PT are the current point buffer and position. */
11522
11523 int
11524 check_point_in_composition (prev_buf, prev_pt, buf, pt)
11525 struct buffer *prev_buf, *buf;
11526 int prev_pt, pt;
11527 {
11528 EMACS_INT start, end;
11529 Lisp_Object prop;
11530 Lisp_Object buffer;
11531
11532 XSETBUFFER (buffer, buf);
11533 /* Check a composition at the last point if point moved within the
11534 same buffer. */
11535 if (prev_buf == buf)
11536 {
11537 if (prev_pt == pt)
11538 /* Point didn't move. */
11539 return 0;
11540
11541 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11542 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11543 && COMPOSITION_VALID_P (start, end, prop)
11544 && start < prev_pt && end > prev_pt)
11545 /* The last point was within the composition. Return 1 iff
11546 point moved out of the composition. */
11547 return (pt <= start || pt >= end);
11548 }
11549
11550 /* Check a composition at the current point. */
11551 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11552 && find_composition (pt, -1, &start, &end, &prop, buffer)
11553 && COMPOSITION_VALID_P (start, end, prop)
11554 && start < pt && end > pt);
11555 }
11556
11557
11558 /* Reconsider the setting of B->clip_changed which is displayed
11559 in window W. */
11560
11561 static INLINE void
11562 reconsider_clip_changes (w, b)
11563 struct window *w;
11564 struct buffer *b;
11565 {
11566 if (b->clip_changed
11567 && !NILP (w->window_end_valid)
11568 && w->current_matrix->buffer == b
11569 && w->current_matrix->zv == BUF_ZV (b)
11570 && w->current_matrix->begv == BUF_BEGV (b))
11571 b->clip_changed = 0;
11572
11573 /* If display wasn't paused, and W is not a tool bar window, see if
11574 point has been moved into or out of a composition. In that case,
11575 we set b->clip_changed to 1 to force updating the screen. If
11576 b->clip_changed has already been set to 1, we can skip this
11577 check. */
11578 if (!b->clip_changed
11579 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11580 {
11581 int pt;
11582
11583 if (w == XWINDOW (selected_window))
11584 pt = BUF_PT (current_buffer);
11585 else
11586 pt = marker_position (w->pointm);
11587
11588 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11589 || pt != XINT (w->last_point))
11590 && check_point_in_composition (w->current_matrix->buffer,
11591 XINT (w->last_point),
11592 XBUFFER (w->buffer), pt))
11593 b->clip_changed = 1;
11594 }
11595 }
11596 \f
11597
11598 /* Select FRAME to forward the values of frame-local variables into C
11599 variables so that the redisplay routines can access those values
11600 directly. */
11601
11602 static void
11603 select_frame_for_redisplay (frame)
11604 Lisp_Object frame;
11605 {
11606 Lisp_Object tail, tem;
11607 Lisp_Object old = selected_frame;
11608 struct Lisp_Symbol *sym;
11609
11610 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11611
11612 selected_frame = frame;
11613
11614 do {
11615 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11616 if (CONSP (XCAR (tail))
11617 && (tem = XCAR (XCAR (tail)),
11618 SYMBOLP (tem))
11619 && (sym = indirect_variable (XSYMBOL (tem)),
11620 sym->redirect == SYMBOL_LOCALIZED)
11621 && sym->val.blv->frame_local)
11622 /* Use find_symbol_value rather than Fsymbol_value
11623 to avoid an error if it is void. */
11624 find_symbol_value (tem);
11625 } while (!EQ (frame, old) && (frame = old, 1));
11626 }
11627
11628
11629 #define STOP_POLLING \
11630 do { if (! polling_stopped_here) stop_polling (); \
11631 polling_stopped_here = 1; } while (0)
11632
11633 #define RESUME_POLLING \
11634 do { if (polling_stopped_here) start_polling (); \
11635 polling_stopped_here = 0; } while (0)
11636
11637
11638 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11639 response to any user action; therefore, we should preserve the echo
11640 area. (Actually, our caller does that job.) Perhaps in the future
11641 avoid recentering windows if it is not necessary; currently that
11642 causes some problems. */
11643
11644 static void
11645 redisplay_internal (preserve_echo_area)
11646 int preserve_echo_area;
11647 {
11648 struct window *w = XWINDOW (selected_window);
11649 struct frame *f;
11650 int pause;
11651 int must_finish = 0;
11652 struct text_pos tlbufpos, tlendpos;
11653 int number_of_visible_frames;
11654 int count, count1;
11655 struct frame *sf;
11656 int polling_stopped_here = 0;
11657 Lisp_Object old_frame = selected_frame;
11658
11659 /* Non-zero means redisplay has to consider all windows on all
11660 frames. Zero means, only selected_window is considered. */
11661 int consider_all_windows_p;
11662
11663 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11664
11665 /* No redisplay if running in batch mode or frame is not yet fully
11666 initialized, or redisplay is explicitly turned off by setting
11667 Vinhibit_redisplay. */
11668 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11669 || !NILP (Vinhibit_redisplay))
11670 return;
11671
11672 /* Don't examine these until after testing Vinhibit_redisplay.
11673 When Emacs is shutting down, perhaps because its connection to
11674 X has dropped, we should not look at them at all. */
11675 f = XFRAME (w->frame);
11676 sf = SELECTED_FRAME ();
11677
11678 if (!f->glyphs_initialized_p)
11679 return;
11680
11681 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11682 if (popup_activated ())
11683 return;
11684 #endif
11685
11686 /* I don't think this happens but let's be paranoid. */
11687 if (redisplaying_p)
11688 return;
11689
11690 /* Record a function that resets redisplaying_p to its old value
11691 when we leave this function. */
11692 count = SPECPDL_INDEX ();
11693 record_unwind_protect (unwind_redisplay,
11694 Fcons (make_number (redisplaying_p), selected_frame));
11695 ++redisplaying_p;
11696 specbind (Qinhibit_free_realized_faces, Qnil);
11697
11698 {
11699 Lisp_Object tail, frame;
11700
11701 FOR_EACH_FRAME (tail, frame)
11702 {
11703 struct frame *f = XFRAME (frame);
11704 f->already_hscrolled_p = 0;
11705 }
11706 }
11707
11708 retry:
11709 if (!EQ (old_frame, selected_frame)
11710 && FRAME_LIVE_P (XFRAME (old_frame)))
11711 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11712 selected_frame and selected_window to be temporarily out-of-sync so
11713 when we come back here via `goto retry', we need to resync because we
11714 may need to run Elisp code (via prepare_menu_bars). */
11715 select_frame_for_redisplay (old_frame);
11716
11717 pause = 0;
11718 reconsider_clip_changes (w, current_buffer);
11719 last_escape_glyph_frame = NULL;
11720 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11721
11722 /* If new fonts have been loaded that make a glyph matrix adjustment
11723 necessary, do it. */
11724 if (fonts_changed_p)
11725 {
11726 adjust_glyphs (NULL);
11727 ++windows_or_buffers_changed;
11728 fonts_changed_p = 0;
11729 }
11730
11731 /* If face_change_count is non-zero, init_iterator will free all
11732 realized faces, which includes the faces referenced from current
11733 matrices. So, we can't reuse current matrices in this case. */
11734 if (face_change_count)
11735 ++windows_or_buffers_changed;
11736
11737 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11738 && FRAME_TTY (sf)->previous_frame != sf)
11739 {
11740 /* Since frames on a single ASCII terminal share the same
11741 display area, displaying a different frame means redisplay
11742 the whole thing. */
11743 windows_or_buffers_changed++;
11744 SET_FRAME_GARBAGED (sf);
11745 #ifndef DOS_NT
11746 set_tty_color_mode (FRAME_TTY (sf), sf);
11747 #endif
11748 FRAME_TTY (sf)->previous_frame = sf;
11749 }
11750
11751 /* Set the visible flags for all frames. Do this before checking
11752 for resized or garbaged frames; they want to know if their frames
11753 are visible. See the comment in frame.h for
11754 FRAME_SAMPLE_VISIBILITY. */
11755 {
11756 Lisp_Object tail, frame;
11757
11758 number_of_visible_frames = 0;
11759
11760 FOR_EACH_FRAME (tail, frame)
11761 {
11762 struct frame *f = XFRAME (frame);
11763
11764 FRAME_SAMPLE_VISIBILITY (f);
11765 if (FRAME_VISIBLE_P (f))
11766 ++number_of_visible_frames;
11767 clear_desired_matrices (f);
11768 }
11769 }
11770
11771 /* Notice any pending interrupt request to change frame size. */
11772 do_pending_window_change (1);
11773
11774 /* Clear frames marked as garbaged. */
11775 if (frame_garbaged)
11776 clear_garbaged_frames ();
11777
11778 /* Build menubar and tool-bar items. */
11779 if (NILP (Vmemory_full))
11780 prepare_menu_bars ();
11781
11782 if (windows_or_buffers_changed)
11783 update_mode_lines++;
11784
11785 /* Detect case that we need to write or remove a star in the mode line. */
11786 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11787 {
11788 w->update_mode_line = Qt;
11789 if (buffer_shared > 1)
11790 update_mode_lines++;
11791 }
11792
11793 /* Avoid invocation of point motion hooks by `current_column' below. */
11794 count1 = SPECPDL_INDEX ();
11795 specbind (Qinhibit_point_motion_hooks, Qt);
11796
11797 /* If %c is in the mode line, update it if needed. */
11798 if (!NILP (w->column_number_displayed)
11799 /* This alternative quickly identifies a common case
11800 where no change is needed. */
11801 && !(PT == XFASTINT (w->last_point)
11802 && XFASTINT (w->last_modified) >= MODIFF
11803 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11804 && (XFASTINT (w->column_number_displayed)
11805 != (int) current_column ())) /* iftc */
11806 w->update_mode_line = Qt;
11807
11808 unbind_to (count1, Qnil);
11809
11810 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11811
11812 /* The variable buffer_shared is set in redisplay_window and
11813 indicates that we redisplay a buffer in different windows. See
11814 there. */
11815 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11816 || cursor_type_changed);
11817
11818 /* If specs for an arrow have changed, do thorough redisplay
11819 to ensure we remove any arrow that should no longer exist. */
11820 if (overlay_arrows_changed_p ())
11821 consider_all_windows_p = windows_or_buffers_changed = 1;
11822
11823 /* Normally the message* functions will have already displayed and
11824 updated the echo area, but the frame may have been trashed, or
11825 the update may have been preempted, so display the echo area
11826 again here. Checking message_cleared_p captures the case that
11827 the echo area should be cleared. */
11828 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11829 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11830 || (message_cleared_p
11831 && minibuf_level == 0
11832 /* If the mini-window is currently selected, this means the
11833 echo-area doesn't show through. */
11834 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11835 {
11836 int window_height_changed_p = echo_area_display (0);
11837 must_finish = 1;
11838
11839 /* If we don't display the current message, don't clear the
11840 message_cleared_p flag, because, if we did, we wouldn't clear
11841 the echo area in the next redisplay which doesn't preserve
11842 the echo area. */
11843 if (!display_last_displayed_message_p)
11844 message_cleared_p = 0;
11845
11846 if (fonts_changed_p)
11847 goto retry;
11848 else if (window_height_changed_p)
11849 {
11850 consider_all_windows_p = 1;
11851 ++update_mode_lines;
11852 ++windows_or_buffers_changed;
11853
11854 /* If window configuration was changed, frames may have been
11855 marked garbaged. Clear them or we will experience
11856 surprises wrt scrolling. */
11857 if (frame_garbaged)
11858 clear_garbaged_frames ();
11859 }
11860 }
11861 else if (EQ (selected_window, minibuf_window)
11862 && (current_buffer->clip_changed
11863 || XFASTINT (w->last_modified) < MODIFF
11864 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11865 && resize_mini_window (w, 0))
11866 {
11867 /* Resized active mini-window to fit the size of what it is
11868 showing if its contents might have changed. */
11869 must_finish = 1;
11870 /* FIXME: this causes all frames to be updated, which seems unnecessary
11871 since only the current frame needs to be considered. This function needs
11872 to be rewritten with two variables, consider_all_windows and
11873 consider_all_frames. */
11874 consider_all_windows_p = 1;
11875 ++windows_or_buffers_changed;
11876 ++update_mode_lines;
11877
11878 /* If window configuration was changed, frames may have been
11879 marked garbaged. Clear them or we will experience
11880 surprises wrt scrolling. */
11881 if (frame_garbaged)
11882 clear_garbaged_frames ();
11883 }
11884
11885
11886 /* If showing the region, and mark has changed, we must redisplay
11887 the whole window. The assignment to this_line_start_pos prevents
11888 the optimization directly below this if-statement. */
11889 if (((!NILP (Vtransient_mark_mode)
11890 && !NILP (XBUFFER (w->buffer)->mark_active))
11891 != !NILP (w->region_showing))
11892 || (!NILP (w->region_showing)
11893 && !EQ (w->region_showing,
11894 Fmarker_position (XBUFFER (w->buffer)->mark))))
11895 CHARPOS (this_line_start_pos) = 0;
11896
11897 /* Optimize the case that only the line containing the cursor in the
11898 selected window has changed. Variables starting with this_ are
11899 set in display_line and record information about the line
11900 containing the cursor. */
11901 tlbufpos = this_line_start_pos;
11902 tlendpos = this_line_end_pos;
11903 if (!consider_all_windows_p
11904 && CHARPOS (tlbufpos) > 0
11905 && NILP (w->update_mode_line)
11906 && !current_buffer->clip_changed
11907 && !current_buffer->prevent_redisplay_optimizations_p
11908 && FRAME_VISIBLE_P (XFRAME (w->frame))
11909 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11910 /* Make sure recorded data applies to current buffer, etc. */
11911 && this_line_buffer == current_buffer
11912 && current_buffer == XBUFFER (w->buffer)
11913 && NILP (w->force_start)
11914 && NILP (w->optional_new_start)
11915 /* Point must be on the line that we have info recorded about. */
11916 && PT >= CHARPOS (tlbufpos)
11917 && PT <= Z - CHARPOS (tlendpos)
11918 /* All text outside that line, including its final newline,
11919 must be unchanged. */
11920 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11921 CHARPOS (tlendpos)))
11922 {
11923 if (CHARPOS (tlbufpos) > BEGV
11924 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11925 && (CHARPOS (tlbufpos) == ZV
11926 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11927 /* Former continuation line has disappeared by becoming empty. */
11928 goto cancel;
11929 else if (XFASTINT (w->last_modified) < MODIFF
11930 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11931 || MINI_WINDOW_P (w))
11932 {
11933 /* We have to handle the case of continuation around a
11934 wide-column character (see the comment in indent.c around
11935 line 1340).
11936
11937 For instance, in the following case:
11938
11939 -------- Insert --------
11940 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11941 J_I_ ==> J_I_ `^^' are cursors.
11942 ^^ ^^
11943 -------- --------
11944
11945 As we have to redraw the line above, we cannot use this
11946 optimization. */
11947
11948 struct it it;
11949 int line_height_before = this_line_pixel_height;
11950
11951 /* Note that start_display will handle the case that the
11952 line starting at tlbufpos is a continuation line. */
11953 start_display (&it, w, tlbufpos);
11954
11955 /* Implementation note: It this still necessary? */
11956 if (it.current_x != this_line_start_x)
11957 goto cancel;
11958
11959 TRACE ((stderr, "trying display optimization 1\n"));
11960 w->cursor.vpos = -1;
11961 overlay_arrow_seen = 0;
11962 it.vpos = this_line_vpos;
11963 it.current_y = this_line_y;
11964 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11965 display_line (&it);
11966
11967 /* If line contains point, is not continued,
11968 and ends at same distance from eob as before, we win. */
11969 if (w->cursor.vpos >= 0
11970 /* Line is not continued, otherwise this_line_start_pos
11971 would have been set to 0 in display_line. */
11972 && CHARPOS (this_line_start_pos)
11973 /* Line ends as before. */
11974 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11975 /* Line has same height as before. Otherwise other lines
11976 would have to be shifted up or down. */
11977 && this_line_pixel_height == line_height_before)
11978 {
11979 /* If this is not the window's last line, we must adjust
11980 the charstarts of the lines below. */
11981 if (it.current_y < it.last_visible_y)
11982 {
11983 struct glyph_row *row
11984 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11985 int delta, delta_bytes;
11986
11987 /* We used to distinguish between two cases here,
11988 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11989 when the line ends in a newline or the end of the
11990 buffer's accessible portion. But both cases did
11991 the same, so they were collapsed. */
11992 delta = (Z
11993 - CHARPOS (tlendpos)
11994 - MATRIX_ROW_START_CHARPOS (row));
11995 delta_bytes = (Z_BYTE
11996 - BYTEPOS (tlendpos)
11997 - MATRIX_ROW_START_BYTEPOS (row));
11998
11999 increment_matrix_positions (w->current_matrix,
12000 this_line_vpos + 1,
12001 w->current_matrix->nrows,
12002 delta, delta_bytes);
12003 }
12004
12005 /* If this row displays text now but previously didn't,
12006 or vice versa, w->window_end_vpos may have to be
12007 adjusted. */
12008 if ((it.glyph_row - 1)->displays_text_p)
12009 {
12010 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
12011 XSETINT (w->window_end_vpos, this_line_vpos);
12012 }
12013 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
12014 && this_line_vpos > 0)
12015 XSETINT (w->window_end_vpos, this_line_vpos - 1);
12016 w->window_end_valid = Qnil;
12017
12018 /* Update hint: No need to try to scroll in update_window. */
12019 w->desired_matrix->no_scrolling_p = 1;
12020
12021 #if GLYPH_DEBUG
12022 *w->desired_matrix->method = 0;
12023 debug_method_add (w, "optimization 1");
12024 #endif
12025 #ifdef HAVE_WINDOW_SYSTEM
12026 update_window_fringes (w, 0);
12027 #endif
12028 goto update;
12029 }
12030 else
12031 goto cancel;
12032 }
12033 else if (/* Cursor position hasn't changed. */
12034 PT == XFASTINT (w->last_point)
12035 /* Make sure the cursor was last displayed
12036 in this window. Otherwise we have to reposition it. */
12037 && 0 <= w->cursor.vpos
12038 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
12039 {
12040 if (!must_finish)
12041 {
12042 do_pending_window_change (1);
12043
12044 /* We used to always goto end_of_redisplay here, but this
12045 isn't enough if we have a blinking cursor. */
12046 if (w->cursor_off_p == w->last_cursor_off_p)
12047 goto end_of_redisplay;
12048 }
12049 goto update;
12050 }
12051 /* If highlighting the region, or if the cursor is in the echo area,
12052 then we can't just move the cursor. */
12053 else if (! (!NILP (Vtransient_mark_mode)
12054 && !NILP (current_buffer->mark_active))
12055 && (EQ (selected_window, current_buffer->last_selected_window)
12056 || highlight_nonselected_windows)
12057 && NILP (w->region_showing)
12058 && NILP (Vshow_trailing_whitespace)
12059 && !cursor_in_echo_area)
12060 {
12061 struct it it;
12062 struct glyph_row *row;
12063
12064 /* Skip from tlbufpos to PT and see where it is. Note that
12065 PT may be in invisible text. If so, we will end at the
12066 next visible position. */
12067 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
12068 NULL, DEFAULT_FACE_ID);
12069 it.current_x = this_line_start_x;
12070 it.current_y = this_line_y;
12071 it.vpos = this_line_vpos;
12072
12073 /* The call to move_it_to stops in front of PT, but
12074 moves over before-strings. */
12075 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
12076
12077 if (it.vpos == this_line_vpos
12078 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
12079 row->enabled_p))
12080 {
12081 xassert (this_line_vpos == it.vpos);
12082 xassert (this_line_y == it.current_y);
12083 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12084 #if GLYPH_DEBUG
12085 *w->desired_matrix->method = 0;
12086 debug_method_add (w, "optimization 3");
12087 #endif
12088 goto update;
12089 }
12090 else
12091 goto cancel;
12092 }
12093
12094 cancel:
12095 /* Text changed drastically or point moved off of line. */
12096 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
12097 }
12098
12099 CHARPOS (this_line_start_pos) = 0;
12100 consider_all_windows_p |= buffer_shared > 1;
12101 ++clear_face_cache_count;
12102 #ifdef HAVE_WINDOW_SYSTEM
12103 ++clear_image_cache_count;
12104 #endif
12105
12106 /* Build desired matrices, and update the display. If
12107 consider_all_windows_p is non-zero, do it for all windows on all
12108 frames. Otherwise do it for selected_window, only. */
12109
12110 if (consider_all_windows_p)
12111 {
12112 Lisp_Object tail, frame;
12113
12114 FOR_EACH_FRAME (tail, frame)
12115 XFRAME (frame)->updated_p = 0;
12116
12117 /* Recompute # windows showing selected buffer. This will be
12118 incremented each time such a window is displayed. */
12119 buffer_shared = 0;
12120
12121 FOR_EACH_FRAME (tail, frame)
12122 {
12123 struct frame *f = XFRAME (frame);
12124
12125 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
12126 {
12127 if (! EQ (frame, selected_frame))
12128 /* Select the frame, for the sake of frame-local
12129 variables. */
12130 select_frame_for_redisplay (frame);
12131
12132 /* Mark all the scroll bars to be removed; we'll redeem
12133 the ones we want when we redisplay their windows. */
12134 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12135 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12136
12137 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12138 redisplay_windows (FRAME_ROOT_WINDOW (f));
12139
12140 /* The X error handler may have deleted that frame. */
12141 if (!FRAME_LIVE_P (f))
12142 continue;
12143
12144 /* Any scroll bars which redisplay_windows should have
12145 nuked should now go away. */
12146 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12147 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12148
12149 /* If fonts changed, display again. */
12150 /* ??? rms: I suspect it is a mistake to jump all the way
12151 back to retry here. It should just retry this frame. */
12152 if (fonts_changed_p)
12153 goto retry;
12154
12155 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12156 {
12157 /* See if we have to hscroll. */
12158 if (!f->already_hscrolled_p)
12159 {
12160 f->already_hscrolled_p = 1;
12161 if (hscroll_windows (f->root_window))
12162 goto retry;
12163 }
12164
12165 /* Prevent various kinds of signals during display
12166 update. stdio is not robust about handling
12167 signals, which can cause an apparent I/O
12168 error. */
12169 if (interrupt_input)
12170 unrequest_sigio ();
12171 STOP_POLLING;
12172
12173 /* Update the display. */
12174 set_window_update_flags (XWINDOW (f->root_window), 1);
12175 pause |= update_frame (f, 0, 0);
12176 f->updated_p = 1;
12177 }
12178 }
12179 }
12180
12181 if (!EQ (old_frame, selected_frame)
12182 && FRAME_LIVE_P (XFRAME (old_frame)))
12183 /* We played a bit fast-and-loose above and allowed selected_frame
12184 and selected_window to be temporarily out-of-sync but let's make
12185 sure this stays contained. */
12186 select_frame_for_redisplay (old_frame);
12187 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12188
12189 if (!pause)
12190 {
12191 /* Do the mark_window_display_accurate after all windows have
12192 been redisplayed because this call resets flags in buffers
12193 which are needed for proper redisplay. */
12194 FOR_EACH_FRAME (tail, frame)
12195 {
12196 struct frame *f = XFRAME (frame);
12197 if (f->updated_p)
12198 {
12199 mark_window_display_accurate (f->root_window, 1);
12200 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12201 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12202 }
12203 }
12204 }
12205 }
12206 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12207 {
12208 Lisp_Object mini_window;
12209 struct frame *mini_frame;
12210
12211 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12212 /* Use list_of_error, not Qerror, so that
12213 we catch only errors and don't run the debugger. */
12214 internal_condition_case_1 (redisplay_window_1, selected_window,
12215 list_of_error,
12216 redisplay_window_error);
12217
12218 /* Compare desired and current matrices, perform output. */
12219
12220 update:
12221 /* If fonts changed, display again. */
12222 if (fonts_changed_p)
12223 goto retry;
12224
12225 /* Prevent various kinds of signals during display update.
12226 stdio is not robust about handling signals,
12227 which can cause an apparent I/O error. */
12228 if (interrupt_input)
12229 unrequest_sigio ();
12230 STOP_POLLING;
12231
12232 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12233 {
12234 if (hscroll_windows (selected_window))
12235 goto retry;
12236
12237 XWINDOW (selected_window)->must_be_updated_p = 1;
12238 pause = update_frame (sf, 0, 0);
12239 }
12240
12241 /* We may have called echo_area_display at the top of this
12242 function. If the echo area is on another frame, that may
12243 have put text on a frame other than the selected one, so the
12244 above call to update_frame would not have caught it. Catch
12245 it here. */
12246 mini_window = FRAME_MINIBUF_WINDOW (sf);
12247 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12248
12249 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12250 {
12251 XWINDOW (mini_window)->must_be_updated_p = 1;
12252 pause |= update_frame (mini_frame, 0, 0);
12253 if (!pause && hscroll_windows (mini_window))
12254 goto retry;
12255 }
12256 }
12257
12258 /* If display was paused because of pending input, make sure we do a
12259 thorough update the next time. */
12260 if (pause)
12261 {
12262 /* Prevent the optimization at the beginning of
12263 redisplay_internal that tries a single-line update of the
12264 line containing the cursor in the selected window. */
12265 CHARPOS (this_line_start_pos) = 0;
12266
12267 /* Let the overlay arrow be updated the next time. */
12268 update_overlay_arrows (0);
12269
12270 /* If we pause after scrolling, some rows in the current
12271 matrices of some windows are not valid. */
12272 if (!WINDOW_FULL_WIDTH_P (w)
12273 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12274 update_mode_lines = 1;
12275 }
12276 else
12277 {
12278 if (!consider_all_windows_p)
12279 {
12280 /* This has already been done above if
12281 consider_all_windows_p is set. */
12282 mark_window_display_accurate_1 (w, 1);
12283
12284 /* Say overlay arrows are up to date. */
12285 update_overlay_arrows (1);
12286
12287 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12288 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12289 }
12290
12291 update_mode_lines = 0;
12292 windows_or_buffers_changed = 0;
12293 cursor_type_changed = 0;
12294 }
12295
12296 /* Start SIGIO interrupts coming again. Having them off during the
12297 code above makes it less likely one will discard output, but not
12298 impossible, since there might be stuff in the system buffer here.
12299 But it is much hairier to try to do anything about that. */
12300 if (interrupt_input)
12301 request_sigio ();
12302 RESUME_POLLING;
12303
12304 /* If a frame has become visible which was not before, redisplay
12305 again, so that we display it. Expose events for such a frame
12306 (which it gets when becoming visible) don't call the parts of
12307 redisplay constructing glyphs, so simply exposing a frame won't
12308 display anything in this case. So, we have to display these
12309 frames here explicitly. */
12310 if (!pause)
12311 {
12312 Lisp_Object tail, frame;
12313 int new_count = 0;
12314
12315 FOR_EACH_FRAME (tail, frame)
12316 {
12317 int this_is_visible = 0;
12318
12319 if (XFRAME (frame)->visible)
12320 this_is_visible = 1;
12321 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12322 if (XFRAME (frame)->visible)
12323 this_is_visible = 1;
12324
12325 if (this_is_visible)
12326 new_count++;
12327 }
12328
12329 if (new_count != number_of_visible_frames)
12330 windows_or_buffers_changed++;
12331 }
12332
12333 /* Change frame size now if a change is pending. */
12334 do_pending_window_change (1);
12335
12336 /* If we just did a pending size change, or have additional
12337 visible frames, redisplay again. */
12338 if (windows_or_buffers_changed && !pause)
12339 goto retry;
12340
12341 /* Clear the face cache eventually. */
12342 if (consider_all_windows_p)
12343 {
12344 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12345 {
12346 clear_face_cache (0);
12347 clear_face_cache_count = 0;
12348 }
12349 #ifdef HAVE_WINDOW_SYSTEM
12350 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12351 {
12352 clear_image_caches (Qnil);
12353 clear_image_cache_count = 0;
12354 }
12355 #endif /* HAVE_WINDOW_SYSTEM */
12356 }
12357
12358 end_of_redisplay:
12359 unbind_to (count, Qnil);
12360 RESUME_POLLING;
12361 }
12362
12363
12364 /* Redisplay, but leave alone any recent echo area message unless
12365 another message has been requested in its place.
12366
12367 This is useful in situations where you need to redisplay but no
12368 user action has occurred, making it inappropriate for the message
12369 area to be cleared. See tracking_off and
12370 wait_reading_process_output for examples of these situations.
12371
12372 FROM_WHERE is an integer saying from where this function was
12373 called. This is useful for debugging. */
12374
12375 void
12376 redisplay_preserve_echo_area (from_where)
12377 int from_where;
12378 {
12379 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12380
12381 if (!NILP (echo_area_buffer[1]))
12382 {
12383 /* We have a previously displayed message, but no current
12384 message. Redisplay the previous message. */
12385 display_last_displayed_message_p = 1;
12386 redisplay_internal (1);
12387 display_last_displayed_message_p = 0;
12388 }
12389 else
12390 redisplay_internal (1);
12391
12392 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12393 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12394 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12395 }
12396
12397
12398 /* Function registered with record_unwind_protect in
12399 redisplay_internal. Reset redisplaying_p to the value it had
12400 before redisplay_internal was called, and clear
12401 prevent_freeing_realized_faces_p. It also selects the previously
12402 selected frame, unless it has been deleted (by an X connection
12403 failure during redisplay, for example). */
12404
12405 static Lisp_Object
12406 unwind_redisplay (val)
12407 Lisp_Object val;
12408 {
12409 Lisp_Object old_redisplaying_p, old_frame;
12410
12411 old_redisplaying_p = XCAR (val);
12412 redisplaying_p = XFASTINT (old_redisplaying_p);
12413 old_frame = XCDR (val);
12414 if (! EQ (old_frame, selected_frame)
12415 && FRAME_LIVE_P (XFRAME (old_frame)))
12416 select_frame_for_redisplay (old_frame);
12417 return Qnil;
12418 }
12419
12420
12421 /* Mark the display of window W as accurate or inaccurate. If
12422 ACCURATE_P is non-zero mark display of W as accurate. If
12423 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12424 redisplay_internal is called. */
12425
12426 static void
12427 mark_window_display_accurate_1 (w, accurate_p)
12428 struct window *w;
12429 int accurate_p;
12430 {
12431 if (BUFFERP (w->buffer))
12432 {
12433 struct buffer *b = XBUFFER (w->buffer);
12434
12435 w->last_modified
12436 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12437 w->last_overlay_modified
12438 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12439 w->last_had_star
12440 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12441
12442 if (accurate_p)
12443 {
12444 b->clip_changed = 0;
12445 b->prevent_redisplay_optimizations_p = 0;
12446
12447 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12448 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12449 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12450 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12451
12452 w->current_matrix->buffer = b;
12453 w->current_matrix->begv = BUF_BEGV (b);
12454 w->current_matrix->zv = BUF_ZV (b);
12455
12456 w->last_cursor = w->cursor;
12457 w->last_cursor_off_p = w->cursor_off_p;
12458
12459 if (w == XWINDOW (selected_window))
12460 w->last_point = make_number (BUF_PT (b));
12461 else
12462 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12463 }
12464 }
12465
12466 if (accurate_p)
12467 {
12468 w->window_end_valid = w->buffer;
12469 w->update_mode_line = Qnil;
12470 }
12471 }
12472
12473
12474 /* Mark the display of windows in the window tree rooted at WINDOW as
12475 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12476 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12477 be redisplayed the next time redisplay_internal is called. */
12478
12479 void
12480 mark_window_display_accurate (window, accurate_p)
12481 Lisp_Object window;
12482 int accurate_p;
12483 {
12484 struct window *w;
12485
12486 for (; !NILP (window); window = w->next)
12487 {
12488 w = XWINDOW (window);
12489 mark_window_display_accurate_1 (w, accurate_p);
12490
12491 if (!NILP (w->vchild))
12492 mark_window_display_accurate (w->vchild, accurate_p);
12493 if (!NILP (w->hchild))
12494 mark_window_display_accurate (w->hchild, accurate_p);
12495 }
12496
12497 if (accurate_p)
12498 {
12499 update_overlay_arrows (1);
12500 }
12501 else
12502 {
12503 /* Force a thorough redisplay the next time by setting
12504 last_arrow_position and last_arrow_string to t, which is
12505 unequal to any useful value of Voverlay_arrow_... */
12506 update_overlay_arrows (-1);
12507 }
12508 }
12509
12510
12511 /* Return value in display table DP (Lisp_Char_Table *) for character
12512 C. Since a display table doesn't have any parent, we don't have to
12513 follow parent. Do not call this function directly but use the
12514 macro DISP_CHAR_VECTOR. */
12515
12516 Lisp_Object
12517 disp_char_vector (dp, c)
12518 struct Lisp_Char_Table *dp;
12519 int c;
12520 {
12521 Lisp_Object val;
12522
12523 if (ASCII_CHAR_P (c))
12524 {
12525 val = dp->ascii;
12526 if (SUB_CHAR_TABLE_P (val))
12527 val = XSUB_CHAR_TABLE (val)->contents[c];
12528 }
12529 else
12530 {
12531 Lisp_Object table;
12532
12533 XSETCHAR_TABLE (table, dp);
12534 val = char_table_ref (table, c);
12535 }
12536 if (NILP (val))
12537 val = dp->defalt;
12538 return val;
12539 }
12540
12541
12542 \f
12543 /***********************************************************************
12544 Window Redisplay
12545 ***********************************************************************/
12546
12547 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12548
12549 static void
12550 redisplay_windows (window)
12551 Lisp_Object window;
12552 {
12553 while (!NILP (window))
12554 {
12555 struct window *w = XWINDOW (window);
12556
12557 if (!NILP (w->hchild))
12558 redisplay_windows (w->hchild);
12559 else if (!NILP (w->vchild))
12560 redisplay_windows (w->vchild);
12561 else if (!NILP (w->buffer))
12562 {
12563 displayed_buffer = XBUFFER (w->buffer);
12564 /* Use list_of_error, not Qerror, so that
12565 we catch only errors and don't run the debugger. */
12566 internal_condition_case_1 (redisplay_window_0, window,
12567 list_of_error,
12568 redisplay_window_error);
12569 }
12570
12571 window = w->next;
12572 }
12573 }
12574
12575 static Lisp_Object
12576 redisplay_window_error ()
12577 {
12578 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12579 return Qnil;
12580 }
12581
12582 static Lisp_Object
12583 redisplay_window_0 (window)
12584 Lisp_Object window;
12585 {
12586 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12587 redisplay_window (window, 0);
12588 return Qnil;
12589 }
12590
12591 static Lisp_Object
12592 redisplay_window_1 (window)
12593 Lisp_Object window;
12594 {
12595 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12596 redisplay_window (window, 1);
12597 return Qnil;
12598 }
12599 \f
12600
12601 /* Increment GLYPH until it reaches END or CONDITION fails while
12602 adding (GLYPH)->pixel_width to X. */
12603
12604 #define SKIP_GLYPHS(glyph, end, x, condition) \
12605 do \
12606 { \
12607 (x) += (glyph)->pixel_width; \
12608 ++(glyph); \
12609 } \
12610 while ((glyph) < (end) && (condition))
12611
12612
12613 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12614 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12615 which positions recorded in ROW differ from current buffer
12616 positions.
12617
12618 Return 0 if cursor is not on this row, 1 otherwise. */
12619
12620 int
12621 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
12622 struct window *w;
12623 struct glyph_row *row;
12624 struct glyph_matrix *matrix;
12625 int delta, delta_bytes, dy, dvpos;
12626 {
12627 struct glyph *glyph = row->glyphs[TEXT_AREA];
12628 struct glyph *end = glyph + row->used[TEXT_AREA];
12629 struct glyph *cursor = NULL;
12630 /* The last known character position in row. */
12631 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12632 int x = row->x;
12633 EMACS_INT pt_old = PT - delta;
12634 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12635 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12636 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12637 /* A glyph beyond the edge of TEXT_AREA which we should never
12638 touch. */
12639 struct glyph *glyphs_end = end;
12640 /* Non-zero means we've found a match for cursor position, but that
12641 glyph has the avoid_cursor_p flag set. */
12642 int match_with_avoid_cursor = 0;
12643 /* Non-zero means we've seen at least one glyph that came from a
12644 display string. */
12645 int string_seen = 0;
12646 /* Largest buffer position seen so far during scan of glyph row. */
12647 EMACS_INT bpos_max = last_pos;
12648 /* Last buffer position covered by an overlay string with an integer
12649 `cursor' property. */
12650 EMACS_INT bpos_covered = 0;
12651
12652 /* Skip over glyphs not having an object at the start and the end of
12653 the row. These are special glyphs like truncation marks on
12654 terminal frames. */
12655 if (row->displays_text_p)
12656 {
12657 if (!row->reversed_p)
12658 {
12659 while (glyph < end
12660 && INTEGERP (glyph->object)
12661 && glyph->charpos < 0)
12662 {
12663 x += glyph->pixel_width;
12664 ++glyph;
12665 }
12666 while (end > glyph
12667 && INTEGERP ((end - 1)->object)
12668 /* CHARPOS is zero for blanks and stretch glyphs
12669 inserted by extend_face_to_end_of_line. */
12670 && (end - 1)->charpos <= 0)
12671 --end;
12672 glyph_before = glyph - 1;
12673 glyph_after = end;
12674 }
12675 else
12676 {
12677 struct glyph *g;
12678
12679 /* If the glyph row is reversed, we need to process it from back
12680 to front, so swap the edge pointers. */
12681 glyphs_end = end = glyph - 1;
12682 glyph += row->used[TEXT_AREA] - 1;
12683
12684 while (glyph > end + 1
12685 && INTEGERP (glyph->object)
12686 && glyph->charpos < 0)
12687 {
12688 --glyph;
12689 x -= glyph->pixel_width;
12690 }
12691 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12692 --glyph;
12693 /* By default, in reversed rows we put the cursor on the
12694 rightmost (first in the reading order) glyph. */
12695 for (g = end + 1; g < glyph; g++)
12696 x += g->pixel_width;
12697 while (end < glyph
12698 && INTEGERP ((end + 1)->object)
12699 && (end + 1)->charpos <= 0)
12700 ++end;
12701 glyph_before = glyph + 1;
12702 glyph_after = end;
12703 }
12704 }
12705 else if (row->reversed_p)
12706 {
12707 /* In R2L rows that don't display text, put the cursor on the
12708 rightmost glyph. Case in point: an empty last line that is
12709 part of an R2L paragraph. */
12710 cursor = end - 1;
12711 x = -1; /* will be computed below, at label compute_x */
12712 }
12713
12714 /* Step 1: Try to find the glyph whose character position
12715 corresponds to point. If that's not possible, find 2 glyphs
12716 whose character positions are the closest to point, one before
12717 point, the other after it. */
12718 if (!row->reversed_p)
12719 while (/* not marched to end of glyph row */
12720 glyph < end
12721 /* glyph was not inserted by redisplay for internal purposes */
12722 && !INTEGERP (glyph->object))
12723 {
12724 if (BUFFERP (glyph->object))
12725 {
12726 EMACS_INT dpos = glyph->charpos - pt_old;
12727
12728 if (glyph->charpos > bpos_max)
12729 bpos_max = glyph->charpos;
12730 if (!glyph->avoid_cursor_p)
12731 {
12732 /* If we hit point, we've found the glyph on which to
12733 display the cursor. */
12734 if (dpos == 0)
12735 {
12736 match_with_avoid_cursor = 0;
12737 break;
12738 }
12739 /* See if we've found a better approximation to
12740 POS_BEFORE or to POS_AFTER. Note that we want the
12741 first (leftmost) glyph of all those that are the
12742 closest from below, and the last (rightmost) of all
12743 those from above. */
12744 if (0 > dpos && dpos > pos_before - pt_old)
12745 {
12746 pos_before = glyph->charpos;
12747 glyph_before = glyph;
12748 }
12749 else if (0 < dpos && dpos <= pos_after - pt_old)
12750 {
12751 pos_after = glyph->charpos;
12752 glyph_after = glyph;
12753 }
12754 }
12755 else if (dpos == 0)
12756 match_with_avoid_cursor = 1;
12757 }
12758 else if (STRINGP (glyph->object))
12759 {
12760 Lisp_Object chprop;
12761 int glyph_pos = glyph->charpos;
12762
12763 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12764 glyph->object);
12765 if (INTEGERP (chprop))
12766 {
12767 bpos_covered = bpos_max + XINT (chprop);
12768 /* If the `cursor' property covers buffer positions up
12769 to and including point, we should display cursor on
12770 this glyph. Note that overlays and text properties
12771 with string values stop bidi reordering, so every
12772 buffer position to the left of the string is always
12773 smaller than any position to the right of the
12774 string. Therefore, if a `cursor' property on one
12775 of the string's characters has an integer value, we
12776 will break out of the loop below _before_ we get to
12777 the position match above. IOW, integer values of
12778 the `cursor' property override the "exact match for
12779 point" strategy of positioning the cursor. */
12780 /* Implementation note: bpos_max == pt_old when, e.g.,
12781 we are in an empty line, where bpos_max is set to
12782 MATRIX_ROW_START_CHARPOS, see above. */
12783 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12784 {
12785 cursor = glyph;
12786 break;
12787 }
12788 }
12789
12790 string_seen = 1;
12791 }
12792 x += glyph->pixel_width;
12793 ++glyph;
12794 }
12795 else if (glyph > end) /* row is reversed */
12796 while (!INTEGERP (glyph->object))
12797 {
12798 if (BUFFERP (glyph->object))
12799 {
12800 EMACS_INT dpos = glyph->charpos - pt_old;
12801
12802 if (glyph->charpos > bpos_max)
12803 bpos_max = glyph->charpos;
12804 if (!glyph->avoid_cursor_p)
12805 {
12806 if (dpos == 0)
12807 {
12808 match_with_avoid_cursor = 0;
12809 break;
12810 }
12811 if (0 > dpos && dpos > pos_before - pt_old)
12812 {
12813 pos_before = glyph->charpos;
12814 glyph_before = glyph;
12815 }
12816 else if (0 < dpos && dpos <= pos_after - pt_old)
12817 {
12818 pos_after = glyph->charpos;
12819 glyph_after = glyph;
12820 }
12821 }
12822 else if (dpos == 0)
12823 match_with_avoid_cursor = 1;
12824 }
12825 else if (STRINGP (glyph->object))
12826 {
12827 Lisp_Object chprop;
12828 int glyph_pos = glyph->charpos;
12829
12830 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12831 glyph->object);
12832 if (INTEGERP (chprop))
12833 {
12834 bpos_covered = bpos_max + XINT (chprop);
12835 /* If the `cursor' property covers buffer positions up
12836 to and including point, we should display cursor on
12837 this glyph. */
12838 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12839 {
12840 cursor = glyph;
12841 break;
12842 }
12843 }
12844 string_seen = 1;
12845 }
12846 --glyph;
12847 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12848 {
12849 x--; /* can't use any pixel_width */
12850 break;
12851 }
12852 x -= glyph->pixel_width;
12853 }
12854
12855 /* Step 2: If we didn't find an exact match for point, we need to
12856 look for a proper place to put the cursor among glyphs between
12857 GLYPH_BEFORE and GLYPH_AFTER. */
12858 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12859 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12860 && bpos_covered < pt_old)
12861 {
12862 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12863 {
12864 EMACS_INT ellipsis_pos;
12865
12866 /* Scan back over the ellipsis glyphs. */
12867 if (!row->reversed_p)
12868 {
12869 ellipsis_pos = (glyph - 1)->charpos;
12870 while (glyph > row->glyphs[TEXT_AREA]
12871 && (glyph - 1)->charpos == ellipsis_pos)
12872 glyph--, x -= glyph->pixel_width;
12873 /* That loop always goes one position too far, including
12874 the glyph before the ellipsis. So scan forward over
12875 that one. */
12876 x += glyph->pixel_width;
12877 glyph++;
12878 }
12879 else /* row is reversed */
12880 {
12881 ellipsis_pos = (glyph + 1)->charpos;
12882 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12883 && (glyph + 1)->charpos == ellipsis_pos)
12884 glyph++, x += glyph->pixel_width;
12885 x -= glyph->pixel_width;
12886 glyph--;
12887 }
12888 }
12889 else if (match_with_avoid_cursor
12890 /* zero-width characters produce no glyphs */
12891 || ((row->reversed_p
12892 ? glyph_after > glyphs_end
12893 : glyph_after < glyphs_end)
12894 && eabs (glyph_after - glyph_before) == 1))
12895 {
12896 cursor = glyph_after;
12897 x = -1;
12898 }
12899 else if (string_seen)
12900 {
12901 int incr = row->reversed_p ? -1 : +1;
12902
12903 /* Need to find the glyph that came out of a string which is
12904 present at point. That glyph is somewhere between
12905 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12906 positioned between POS_BEFORE and POS_AFTER in the
12907 buffer. */
12908 struct glyph *stop = glyph_after;
12909 EMACS_INT pos = pos_before;
12910
12911 x = -1;
12912 for (glyph = glyph_before + incr;
12913 row->reversed_p ? glyph > stop : glyph < stop; )
12914 {
12915
12916 /* Any glyphs that come from the buffer are here because
12917 of bidi reordering. Skip them, and only pay
12918 attention to glyphs that came from some string. */
12919 if (STRINGP (glyph->object))
12920 {
12921 Lisp_Object str;
12922 EMACS_INT tem;
12923
12924 str = glyph->object;
12925 tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
12926 if (tem == 0 /* from overlay */
12927 || pos <= tem)
12928 {
12929 /* If the string from which this glyph came is
12930 found in the buffer at point, then we've
12931 found the glyph we've been looking for. If
12932 it comes from an overlay (tem == 0), and it
12933 has the `cursor' property on one of its
12934 glyphs, record that glyph as a candidate for
12935 displaying the cursor. (As in the
12936 unidirectional version, we will display the
12937 cursor on the last candidate we find.) */
12938 if (tem == 0 || tem == pt_old)
12939 {
12940 /* The glyphs from this string could have
12941 been reordered. Find the one with the
12942 smallest string position. Or there could
12943 be a character in the string with the
12944 `cursor' property, which means display
12945 cursor on that character's glyph. */
12946 int strpos = glyph->charpos;
12947
12948 cursor = glyph;
12949 for (glyph += incr;
12950 EQ (glyph->object, str);
12951 glyph += incr)
12952 {
12953 Lisp_Object cprop;
12954 int gpos = glyph->charpos;
12955
12956 cprop = Fget_char_property (make_number (gpos),
12957 Qcursor,
12958 glyph->object);
12959 if (!NILP (cprop))
12960 {
12961 cursor = glyph;
12962 break;
12963 }
12964 if (glyph->charpos < strpos)
12965 {
12966 strpos = glyph->charpos;
12967 cursor = glyph;
12968 }
12969 }
12970
12971 if (tem == pt_old)
12972 goto compute_x;
12973 }
12974 if (tem)
12975 pos = tem + 1; /* don't find previous instances */
12976 }
12977 /* This string is not what we want; skip all of the
12978 glyphs that came from it. */
12979 do
12980 glyph += incr;
12981 while ((row->reversed_p ? glyph > stop : glyph < stop)
12982 && EQ (glyph->object, str));
12983 }
12984 else
12985 glyph += incr;
12986 }
12987
12988 /* If we reached the end of the line, and END was from a string,
12989 the cursor is not on this line. */
12990 if (glyph == end
12991 && STRINGP ((glyph - incr)->object)
12992 && row->continued_p)
12993 return 0;
12994 }
12995 }
12996
12997 compute_x:
12998 if (cursor != NULL)
12999 glyph = cursor;
13000 if (x < 0)
13001 {
13002 struct glyph *g;
13003
13004 /* Need to compute x that corresponds to GLYPH. */
13005 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
13006 {
13007 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
13008 abort ();
13009 x += g->pixel_width;
13010 }
13011 }
13012
13013 /* ROW could be part of a continued line, which, under bidi
13014 reordering, might have other rows whose start and end charpos
13015 occlude point. Only set w->cursor if we found a better
13016 approximation to the cursor position than we have from previously
13017 examined candidate rows belonging to the same continued line. */
13018 if (/* we already have a candidate row */
13019 w->cursor.vpos >= 0
13020 /* that candidate is not the row we are processing */
13021 && MATRIX_ROW (matrix, w->cursor.vpos) != row
13022 /* the row we are processing is part of a continued line */
13023 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
13024 /* Make sure cursor.vpos specifies a row whose start and end
13025 charpos occlude point. This is because some callers of this
13026 function leave cursor.vpos at the row where the cursor was
13027 displayed during the last redisplay cycle. */
13028 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
13029 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
13030 {
13031 struct glyph *g1 =
13032 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
13033
13034 /* Don't consider glyphs that are outside TEXT_AREA. */
13035 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
13036 return 0;
13037 /* Keep the candidate whose buffer position is the closest to
13038 point. */
13039 if (/* previous candidate is a glyph in TEXT_AREA of that row */
13040 w->cursor.hpos >= 0
13041 && w->cursor.hpos < MATRIX_ROW_USED(matrix, w->cursor.vpos)
13042 && BUFFERP (g1->object)
13043 && (g1->charpos == pt_old /* an exact match always wins */
13044 || (BUFFERP (glyph->object)
13045 && eabs (g1->charpos - pt_old)
13046 < eabs (glyph->charpos - pt_old))))
13047 return 0;
13048 /* If this candidate gives an exact match, use that. */
13049 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
13050 /* Otherwise, keep the candidate that comes from a row
13051 spanning less buffer positions. This may win when one or
13052 both candidate positions are on glyphs that came from
13053 display strings, for which we cannot compare buffer
13054 positions. */
13055 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13056 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13057 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
13058 return 0;
13059 }
13060 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
13061 w->cursor.x = x;
13062 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
13063 w->cursor.y = row->y + dy;
13064
13065 if (w == XWINDOW (selected_window))
13066 {
13067 if (!row->continued_p
13068 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
13069 && row->x == 0)
13070 {
13071 this_line_buffer = XBUFFER (w->buffer);
13072
13073 CHARPOS (this_line_start_pos)
13074 = MATRIX_ROW_START_CHARPOS (row) + delta;
13075 BYTEPOS (this_line_start_pos)
13076 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
13077
13078 CHARPOS (this_line_end_pos)
13079 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
13080 BYTEPOS (this_line_end_pos)
13081 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
13082
13083 this_line_y = w->cursor.y;
13084 this_line_pixel_height = row->height;
13085 this_line_vpos = w->cursor.vpos;
13086 this_line_start_x = row->x;
13087 }
13088 else
13089 CHARPOS (this_line_start_pos) = 0;
13090 }
13091
13092 return 1;
13093 }
13094
13095
13096 /* Run window scroll functions, if any, for WINDOW with new window
13097 start STARTP. Sets the window start of WINDOW to that position.
13098
13099 We assume that the window's buffer is really current. */
13100
13101 static INLINE struct text_pos
13102 run_window_scroll_functions (window, startp)
13103 Lisp_Object window;
13104 struct text_pos startp;
13105 {
13106 struct window *w = XWINDOW (window);
13107 SET_MARKER_FROM_TEXT_POS (w->start, startp);
13108
13109 if (current_buffer != XBUFFER (w->buffer))
13110 abort ();
13111
13112 if (!NILP (Vwindow_scroll_functions))
13113 {
13114 run_hook_with_args_2 (Qwindow_scroll_functions, window,
13115 make_number (CHARPOS (startp)));
13116 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13117 /* In case the hook functions switch buffers. */
13118 if (current_buffer != XBUFFER (w->buffer))
13119 set_buffer_internal_1 (XBUFFER (w->buffer));
13120 }
13121
13122 return startp;
13123 }
13124
13125
13126 /* Make sure the line containing the cursor is fully visible.
13127 A value of 1 means there is nothing to be done.
13128 (Either the line is fully visible, or it cannot be made so,
13129 or we cannot tell.)
13130
13131 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13132 is higher than window.
13133
13134 A value of 0 means the caller should do scrolling
13135 as if point had gone off the screen. */
13136
13137 static int
13138 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
13139 struct window *w;
13140 int force_p;
13141 int current_matrix_p;
13142 {
13143 struct glyph_matrix *matrix;
13144 struct glyph_row *row;
13145 int window_height;
13146
13147 if (!make_cursor_line_fully_visible_p)
13148 return 1;
13149
13150 /* It's not always possible to find the cursor, e.g, when a window
13151 is full of overlay strings. Don't do anything in that case. */
13152 if (w->cursor.vpos < 0)
13153 return 1;
13154
13155 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13156 row = MATRIX_ROW (matrix, w->cursor.vpos);
13157
13158 /* If the cursor row is not partially visible, there's nothing to do. */
13159 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13160 return 1;
13161
13162 /* If the row the cursor is in is taller than the window's height,
13163 it's not clear what to do, so do nothing. */
13164 window_height = window_box_height (w);
13165 if (row->height >= window_height)
13166 {
13167 if (!force_p || MINI_WINDOW_P (w)
13168 || w->vscroll || w->cursor.vpos == 0)
13169 return 1;
13170 }
13171 return 0;
13172 }
13173
13174
13175 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13176 non-zero means only WINDOW is redisplayed in redisplay_internal.
13177 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
13178 in redisplay_window to bring a partially visible line into view in
13179 the case that only the cursor has moved.
13180
13181 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13182 last screen line's vertical height extends past the end of the screen.
13183
13184 Value is
13185
13186 1 if scrolling succeeded
13187
13188 0 if scrolling didn't find point.
13189
13190 -1 if new fonts have been loaded so that we must interrupt
13191 redisplay, adjust glyph matrices, and try again. */
13192
13193 enum
13194 {
13195 SCROLLING_SUCCESS,
13196 SCROLLING_FAILED,
13197 SCROLLING_NEED_LARGER_MATRICES
13198 };
13199
13200 static int
13201 try_scrolling (window, just_this_one_p, scroll_conservatively,
13202 scroll_step, temp_scroll_step, last_line_misfit)
13203 Lisp_Object window;
13204 int just_this_one_p;
13205 EMACS_INT scroll_conservatively, scroll_step;
13206 int temp_scroll_step;
13207 int last_line_misfit;
13208 {
13209 struct window *w = XWINDOW (window);
13210 struct frame *f = XFRAME (w->frame);
13211 struct text_pos pos, startp;
13212 struct it it;
13213 int this_scroll_margin, scroll_max, rc, height;
13214 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13215 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13216 Lisp_Object aggressive;
13217 int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
13218
13219 #if GLYPH_DEBUG
13220 debug_method_add (w, "try_scrolling");
13221 #endif
13222
13223 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13224
13225 /* Compute scroll margin height in pixels. We scroll when point is
13226 within this distance from the top or bottom of the window. */
13227 if (scroll_margin > 0)
13228 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13229 * FRAME_LINE_HEIGHT (f);
13230 else
13231 this_scroll_margin = 0;
13232
13233 /* Force scroll_conservatively to have a reasonable value, to avoid
13234 overflow while computing how much to scroll. Note that the user
13235 can supply scroll-conservatively equal to `most-positive-fixnum',
13236 which can be larger than INT_MAX. */
13237 if (scroll_conservatively > scroll_limit)
13238 {
13239 scroll_conservatively = scroll_limit;
13240 scroll_max = INT_MAX;
13241 }
13242 else if (scroll_step || scroll_conservatively || temp_scroll_step)
13243 /* Compute how much we should try to scroll maximally to bring
13244 point into view. */
13245 scroll_max = (max (scroll_step,
13246 max (scroll_conservatively, temp_scroll_step))
13247 * FRAME_LINE_HEIGHT (f));
13248 else if (NUMBERP (current_buffer->scroll_down_aggressively)
13249 || NUMBERP (current_buffer->scroll_up_aggressively))
13250 /* We're trying to scroll because of aggressive scrolling but no
13251 scroll_step is set. Choose an arbitrary one. */
13252 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13253 else
13254 scroll_max = 0;
13255
13256 too_near_end:
13257
13258 /* Decide whether to scroll down. */
13259 if (PT > CHARPOS (startp))
13260 {
13261 int scroll_margin_y;
13262
13263 /* Compute the pixel ypos of the scroll margin, then move it to
13264 either that ypos or PT, whichever comes first. */
13265 start_display (&it, w, startp);
13266 scroll_margin_y = it.last_visible_y - this_scroll_margin
13267 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13268 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13269 (MOVE_TO_POS | MOVE_TO_Y));
13270
13271 if (PT > CHARPOS (it.current.pos))
13272 {
13273 int y0 = line_bottom_y (&it);
13274
13275 /* Compute the distance from the scroll margin to PT
13276 (including the height of the cursor line). Moving the
13277 iterator unconditionally to PT can be slow if PT is far
13278 away, so stop 10 lines past the window bottom (is there a
13279 way to do the right thing quickly?). */
13280 move_it_to (&it, PT, -1,
13281 it.last_visible_y + 10 * FRAME_LINE_HEIGHT (f),
13282 -1, MOVE_TO_POS | MOVE_TO_Y);
13283 dy = line_bottom_y (&it) - y0;
13284
13285 if (dy > scroll_max)
13286 return SCROLLING_FAILED;
13287
13288 scroll_down_p = 1;
13289 }
13290 }
13291
13292 if (scroll_down_p)
13293 {
13294 /* Point is in or below the bottom scroll margin, so move the
13295 window start down. If scrolling conservatively, move it just
13296 enough down to make point visible. If scroll_step is set,
13297 move it down by scroll_step. */
13298 if (scroll_conservatively)
13299 amount_to_scroll
13300 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13301 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
13302 else if (scroll_step || temp_scroll_step)
13303 amount_to_scroll = scroll_max;
13304 else
13305 {
13306 aggressive = current_buffer->scroll_up_aggressively;
13307 height = WINDOW_BOX_TEXT_HEIGHT (w);
13308 if (NUMBERP (aggressive))
13309 {
13310 double float_amount = XFLOATINT (aggressive) * height;
13311 amount_to_scroll = float_amount;
13312 if (amount_to_scroll == 0 && float_amount > 0)
13313 amount_to_scroll = 1;
13314 }
13315 }
13316
13317 if (amount_to_scroll <= 0)
13318 return SCROLLING_FAILED;
13319
13320 start_display (&it, w, startp);
13321 move_it_vertically (&it, amount_to_scroll);
13322
13323 /* If STARTP is unchanged, move it down another screen line. */
13324 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13325 move_it_by_lines (&it, 1, 1);
13326 startp = it.current.pos;
13327 }
13328 else
13329 {
13330 struct text_pos scroll_margin_pos = startp;
13331
13332 /* See if point is inside the scroll margin at the top of the
13333 window. */
13334 if (this_scroll_margin)
13335 {
13336 start_display (&it, w, startp);
13337 move_it_vertically (&it, this_scroll_margin);
13338 scroll_margin_pos = it.current.pos;
13339 }
13340
13341 if (PT < CHARPOS (scroll_margin_pos))
13342 {
13343 /* Point is in the scroll margin at the top of the window or
13344 above what is displayed in the window. */
13345 int y0;
13346
13347 /* Compute the vertical distance from PT to the scroll
13348 margin position. Give up if distance is greater than
13349 scroll_max. */
13350 SET_TEXT_POS (pos, PT, PT_BYTE);
13351 start_display (&it, w, pos);
13352 y0 = it.current_y;
13353 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13354 it.last_visible_y, -1,
13355 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13356 dy = it.current_y - y0;
13357 if (dy > scroll_max)
13358 return SCROLLING_FAILED;
13359
13360 /* Compute new window start. */
13361 start_display (&it, w, startp);
13362
13363 if (scroll_conservatively)
13364 amount_to_scroll
13365 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
13366 else if (scroll_step || temp_scroll_step)
13367 amount_to_scroll = scroll_max;
13368 else
13369 {
13370 aggressive = current_buffer->scroll_down_aggressively;
13371 height = WINDOW_BOX_TEXT_HEIGHT (w);
13372 if (NUMBERP (aggressive))
13373 {
13374 double float_amount = XFLOATINT (aggressive) * height;
13375 amount_to_scroll = float_amount;
13376 if (amount_to_scroll == 0 && float_amount > 0)
13377 amount_to_scroll = 1;
13378 }
13379 }
13380
13381 if (amount_to_scroll <= 0)
13382 return SCROLLING_FAILED;
13383
13384 move_it_vertically_backward (&it, amount_to_scroll);
13385 startp = it.current.pos;
13386 }
13387 }
13388
13389 /* Run window scroll functions. */
13390 startp = run_window_scroll_functions (window, startp);
13391
13392 /* Display the window. Give up if new fonts are loaded, or if point
13393 doesn't appear. */
13394 if (!try_window (window, startp, 0))
13395 rc = SCROLLING_NEED_LARGER_MATRICES;
13396 else if (w->cursor.vpos < 0)
13397 {
13398 clear_glyph_matrix (w->desired_matrix);
13399 rc = SCROLLING_FAILED;
13400 }
13401 else
13402 {
13403 /* Maybe forget recorded base line for line number display. */
13404 if (!just_this_one_p
13405 || current_buffer->clip_changed
13406 || BEG_UNCHANGED < CHARPOS (startp))
13407 w->base_line_number = Qnil;
13408
13409 /* If cursor ends up on a partially visible line,
13410 treat that as being off the bottom of the screen. */
13411 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
13412 {
13413 clear_glyph_matrix (w->desired_matrix);
13414 ++extra_scroll_margin_lines;
13415 goto too_near_end;
13416 }
13417 rc = SCROLLING_SUCCESS;
13418 }
13419
13420 return rc;
13421 }
13422
13423
13424 /* Compute a suitable window start for window W if display of W starts
13425 on a continuation line. Value is non-zero if a new window start
13426 was computed.
13427
13428 The new window start will be computed, based on W's width, starting
13429 from the start of the continued line. It is the start of the
13430 screen line with the minimum distance from the old start W->start. */
13431
13432 static int
13433 compute_window_start_on_continuation_line (w)
13434 struct window *w;
13435 {
13436 struct text_pos pos, start_pos;
13437 int window_start_changed_p = 0;
13438
13439 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13440
13441 /* If window start is on a continuation line... Window start may be
13442 < BEGV in case there's invisible text at the start of the
13443 buffer (M-x rmail, for example). */
13444 if (CHARPOS (start_pos) > BEGV
13445 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13446 {
13447 struct it it;
13448 struct glyph_row *row;
13449
13450 /* Handle the case that the window start is out of range. */
13451 if (CHARPOS (start_pos) < BEGV)
13452 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13453 else if (CHARPOS (start_pos) > ZV)
13454 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13455
13456 /* Find the start of the continued line. This should be fast
13457 because scan_buffer is fast (newline cache). */
13458 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13459 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13460 row, DEFAULT_FACE_ID);
13461 reseat_at_previous_visible_line_start (&it);
13462
13463 /* If the line start is "too far" away from the window start,
13464 say it takes too much time to compute a new window start. */
13465 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13466 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13467 {
13468 int min_distance, distance;
13469
13470 /* Move forward by display lines to find the new window
13471 start. If window width was enlarged, the new start can
13472 be expected to be > the old start. If window width was
13473 decreased, the new window start will be < the old start.
13474 So, we're looking for the display line start with the
13475 minimum distance from the old window start. */
13476 pos = it.current.pos;
13477 min_distance = INFINITY;
13478 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13479 distance < min_distance)
13480 {
13481 min_distance = distance;
13482 pos = it.current.pos;
13483 move_it_by_lines (&it, 1, 0);
13484 }
13485
13486 /* Set the window start there. */
13487 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13488 window_start_changed_p = 1;
13489 }
13490 }
13491
13492 return window_start_changed_p;
13493 }
13494
13495
13496 /* Try cursor movement in case text has not changed in window WINDOW,
13497 with window start STARTP. Value is
13498
13499 CURSOR_MOVEMENT_SUCCESS if successful
13500
13501 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13502
13503 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13504 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13505 we want to scroll as if scroll-step were set to 1. See the code.
13506
13507 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13508 which case we have to abort this redisplay, and adjust matrices
13509 first. */
13510
13511 enum
13512 {
13513 CURSOR_MOVEMENT_SUCCESS,
13514 CURSOR_MOVEMENT_CANNOT_BE_USED,
13515 CURSOR_MOVEMENT_MUST_SCROLL,
13516 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13517 };
13518
13519 static int
13520 try_cursor_movement (window, startp, scroll_step)
13521 Lisp_Object window;
13522 struct text_pos startp;
13523 int *scroll_step;
13524 {
13525 struct window *w = XWINDOW (window);
13526 struct frame *f = XFRAME (w->frame);
13527 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13528
13529 #if GLYPH_DEBUG
13530 if (inhibit_try_cursor_movement)
13531 return rc;
13532 #endif
13533
13534 /* Handle case where text has not changed, only point, and it has
13535 not moved off the frame. */
13536 if (/* Point may be in this window. */
13537 PT >= CHARPOS (startp)
13538 /* Selective display hasn't changed. */
13539 && !current_buffer->clip_changed
13540 /* Function force-mode-line-update is used to force a thorough
13541 redisplay. It sets either windows_or_buffers_changed or
13542 update_mode_lines. So don't take a shortcut here for these
13543 cases. */
13544 && !update_mode_lines
13545 && !windows_or_buffers_changed
13546 && !cursor_type_changed
13547 /* Can't use this case if highlighting a region. When a
13548 region exists, cursor movement has to do more than just
13549 set the cursor. */
13550 && !(!NILP (Vtransient_mark_mode)
13551 && !NILP (current_buffer->mark_active))
13552 && NILP (w->region_showing)
13553 && NILP (Vshow_trailing_whitespace)
13554 /* Right after splitting windows, last_point may be nil. */
13555 && INTEGERP (w->last_point)
13556 /* This code is not used for mini-buffer for the sake of the case
13557 of redisplaying to replace an echo area message; since in
13558 that case the mini-buffer contents per se are usually
13559 unchanged. This code is of no real use in the mini-buffer
13560 since the handling of this_line_start_pos, etc., in redisplay
13561 handles the same cases. */
13562 && !EQ (window, minibuf_window)
13563 /* When splitting windows or for new windows, it happens that
13564 redisplay is called with a nil window_end_vpos or one being
13565 larger than the window. This should really be fixed in
13566 window.c. I don't have this on my list, now, so we do
13567 approximately the same as the old redisplay code. --gerd. */
13568 && INTEGERP (w->window_end_vpos)
13569 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13570 && (FRAME_WINDOW_P (f)
13571 || !overlay_arrow_in_current_buffer_p ()))
13572 {
13573 int this_scroll_margin, top_scroll_margin;
13574 struct glyph_row *row = NULL;
13575
13576 #if GLYPH_DEBUG
13577 debug_method_add (w, "cursor movement");
13578 #endif
13579
13580 /* Scroll if point within this distance from the top or bottom
13581 of the window. This is a pixel value. */
13582 if (scroll_margin > 0)
13583 {
13584 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13585 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13586 }
13587 else
13588 this_scroll_margin = 0;
13589
13590 top_scroll_margin = this_scroll_margin;
13591 if (WINDOW_WANTS_HEADER_LINE_P (w))
13592 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13593
13594 /* Start with the row the cursor was displayed during the last
13595 not paused redisplay. Give up if that row is not valid. */
13596 if (w->last_cursor.vpos < 0
13597 || w->last_cursor.vpos >= w->current_matrix->nrows)
13598 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13599 else
13600 {
13601 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13602 if (row->mode_line_p)
13603 ++row;
13604 if (!row->enabled_p)
13605 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13606 /* If rows are bidi-reordered, back up until we find a row
13607 that does not belong to a continuation line. This is
13608 because we must consider all rows of a continued line as
13609 candidates for cursor positioning, since row start and
13610 end positions change non-linearly with vertical position
13611 in such rows. */
13612 /* FIXME: Revisit this when glyph ``spilling'' in
13613 continuation lines' rows is implemented for
13614 bidi-reordered rows. */
13615 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13616 {
13617 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13618 {
13619 xassert (row->enabled_p);
13620 --row;
13621 /* If we hit the beginning of the displayed portion
13622 without finding the first row of a continued
13623 line, give up. */
13624 if (row <= w->current_matrix->rows)
13625 {
13626 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13627 break;
13628 }
13629
13630 }
13631 }
13632 }
13633
13634 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13635 {
13636 int scroll_p = 0;
13637 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13638
13639 if (PT > XFASTINT (w->last_point))
13640 {
13641 /* Point has moved forward. */
13642 while (MATRIX_ROW_END_CHARPOS (row) < PT
13643 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13644 {
13645 xassert (row->enabled_p);
13646 ++row;
13647 }
13648
13649 /* The end position of a row equals the start position
13650 of the next row. If PT is there, we would rather
13651 display it in the next line. */
13652 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13653 && MATRIX_ROW_END_CHARPOS (row) == PT
13654 && !cursor_row_p (w, row))
13655 ++row;
13656
13657 /* If within the scroll margin, scroll. Note that
13658 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13659 the next line would be drawn, and that
13660 this_scroll_margin can be zero. */
13661 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13662 || PT > MATRIX_ROW_END_CHARPOS (row)
13663 /* Line is completely visible last line in window
13664 and PT is to be set in the next line. */
13665 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13666 && PT == MATRIX_ROW_END_CHARPOS (row)
13667 && !row->ends_at_zv_p
13668 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13669 scroll_p = 1;
13670 }
13671 else if (PT < XFASTINT (w->last_point))
13672 {
13673 /* Cursor has to be moved backward. Note that PT >=
13674 CHARPOS (startp) because of the outer if-statement. */
13675 while (!row->mode_line_p
13676 && (MATRIX_ROW_START_CHARPOS (row) > PT
13677 || (MATRIX_ROW_START_CHARPOS (row) == PT
13678 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13679 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13680 row > w->current_matrix->rows
13681 && (row-1)->ends_in_newline_from_string_p))))
13682 && (row->y > top_scroll_margin
13683 || CHARPOS (startp) == BEGV))
13684 {
13685 xassert (row->enabled_p);
13686 --row;
13687 }
13688
13689 /* Consider the following case: Window starts at BEGV,
13690 there is invisible, intangible text at BEGV, so that
13691 display starts at some point START > BEGV. It can
13692 happen that we are called with PT somewhere between
13693 BEGV and START. Try to handle that case. */
13694 if (row < w->current_matrix->rows
13695 || row->mode_line_p)
13696 {
13697 row = w->current_matrix->rows;
13698 if (row->mode_line_p)
13699 ++row;
13700 }
13701
13702 /* Due to newlines in overlay strings, we may have to
13703 skip forward over overlay strings. */
13704 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13705 && MATRIX_ROW_END_CHARPOS (row) == PT
13706 && !cursor_row_p (w, row))
13707 ++row;
13708
13709 /* If within the scroll margin, scroll. */
13710 if (row->y < top_scroll_margin
13711 && CHARPOS (startp) != BEGV)
13712 scroll_p = 1;
13713 }
13714 else
13715 {
13716 /* Cursor did not move. So don't scroll even if cursor line
13717 is partially visible, as it was so before. */
13718 rc = CURSOR_MOVEMENT_SUCCESS;
13719 }
13720
13721 if (PT < MATRIX_ROW_START_CHARPOS (row)
13722 || PT > MATRIX_ROW_END_CHARPOS (row))
13723 {
13724 /* if PT is not in the glyph row, give up. */
13725 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13726 }
13727 else if (rc != CURSOR_MOVEMENT_SUCCESS
13728 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13729 && make_cursor_line_fully_visible_p)
13730 {
13731 if (PT == MATRIX_ROW_END_CHARPOS (row)
13732 && !row->ends_at_zv_p
13733 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13734 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13735 else if (row->height > window_box_height (w))
13736 {
13737 /* If we end up in a partially visible line, let's
13738 make it fully visible, except when it's taller
13739 than the window, in which case we can't do much
13740 about it. */
13741 *scroll_step = 1;
13742 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13743 }
13744 else
13745 {
13746 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13747 if (!cursor_row_fully_visible_p (w, 0, 1))
13748 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13749 else
13750 rc = CURSOR_MOVEMENT_SUCCESS;
13751 }
13752 }
13753 else if (scroll_p)
13754 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13755 else if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13756 {
13757 /* With bidi-reordered rows, there could be more than
13758 one candidate row whose start and end positions
13759 occlude point. We need to let set_cursor_from_row
13760 find the best candidate. */
13761 /* FIXME: Revisit this when glyph ``spilling'' in
13762 continuation lines' rows is implemented for
13763 bidi-reordered rows. */
13764 int rv = 0;
13765
13766 do
13767 {
13768 rv |= set_cursor_from_row (w, row, w->current_matrix,
13769 0, 0, 0, 0);
13770 /* As soon as we've found the first suitable row
13771 whose ends_at_zv_p flag is set, we are done. */
13772 if (rv
13773 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13774 {
13775 rc = CURSOR_MOVEMENT_SUCCESS;
13776 break;
13777 }
13778 ++row;
13779 }
13780 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13781 && MATRIX_ROW_START_CHARPOS (row) <= PT
13782 && PT <= MATRIX_ROW_END_CHARPOS (row)
13783 && cursor_row_p (w, row));
13784 /* If we didn't find any candidate rows, or exited the
13785 loop before all the candidates were examined, signal
13786 to the caller that this method failed. */
13787 if (rc != CURSOR_MOVEMENT_SUCCESS
13788 && (!rv
13789 || (MATRIX_ROW_START_CHARPOS (row) <= PT
13790 && PT <= MATRIX_ROW_END_CHARPOS (row))))
13791 rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13792 else
13793 rc = CURSOR_MOVEMENT_SUCCESS;
13794 }
13795 else
13796 {
13797 do
13798 {
13799 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13800 {
13801 rc = CURSOR_MOVEMENT_SUCCESS;
13802 break;
13803 }
13804 ++row;
13805 }
13806 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13807 && MATRIX_ROW_START_CHARPOS (row) == PT
13808 && cursor_row_p (w, row));
13809 }
13810 }
13811 }
13812
13813 return rc;
13814 }
13815
13816 void
13817 set_vertical_scroll_bar (w)
13818 struct window *w;
13819 {
13820 int start, end, whole;
13821
13822 /* Calculate the start and end positions for the current window.
13823 At some point, it would be nice to choose between scrollbars
13824 which reflect the whole buffer size, with special markers
13825 indicating narrowing, and scrollbars which reflect only the
13826 visible region.
13827
13828 Note that mini-buffers sometimes aren't displaying any text. */
13829 if (!MINI_WINDOW_P (w)
13830 || (w == XWINDOW (minibuf_window)
13831 && NILP (echo_area_buffer[0])))
13832 {
13833 struct buffer *buf = XBUFFER (w->buffer);
13834 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13835 start = marker_position (w->start) - BUF_BEGV (buf);
13836 /* I don't think this is guaranteed to be right. For the
13837 moment, we'll pretend it is. */
13838 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13839
13840 if (end < start)
13841 end = start;
13842 if (whole < (end - start))
13843 whole = end - start;
13844 }
13845 else
13846 start = end = whole = 0;
13847
13848 /* Indicate what this scroll bar ought to be displaying now. */
13849 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13850 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13851 (w, end - start, whole, start);
13852 }
13853
13854
13855 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13856 selected_window is redisplayed.
13857
13858 We can return without actually redisplaying the window if
13859 fonts_changed_p is nonzero. In that case, redisplay_internal will
13860 retry. */
13861
13862 static void
13863 redisplay_window (window, just_this_one_p)
13864 Lisp_Object window;
13865 int just_this_one_p;
13866 {
13867 struct window *w = XWINDOW (window);
13868 struct frame *f = XFRAME (w->frame);
13869 struct buffer *buffer = XBUFFER (w->buffer);
13870 struct buffer *old = current_buffer;
13871 struct text_pos lpoint, opoint, startp;
13872 int update_mode_line;
13873 int tem;
13874 struct it it;
13875 /* Record it now because it's overwritten. */
13876 int current_matrix_up_to_date_p = 0;
13877 int used_current_matrix_p = 0;
13878 /* This is less strict than current_matrix_up_to_date_p.
13879 It indictes that the buffer contents and narrowing are unchanged. */
13880 int buffer_unchanged_p = 0;
13881 int temp_scroll_step = 0;
13882 int count = SPECPDL_INDEX ();
13883 int rc;
13884 int centering_position = -1;
13885 int last_line_misfit = 0;
13886 int beg_unchanged, end_unchanged;
13887
13888 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13889 opoint = lpoint;
13890
13891 /* W must be a leaf window here. */
13892 xassert (!NILP (w->buffer));
13893 #if GLYPH_DEBUG
13894 *w->desired_matrix->method = 0;
13895 #endif
13896
13897 restart:
13898 reconsider_clip_changes (w, buffer);
13899
13900 /* Has the mode line to be updated? */
13901 update_mode_line = (!NILP (w->update_mode_line)
13902 || update_mode_lines
13903 || buffer->clip_changed
13904 || buffer->prevent_redisplay_optimizations_p);
13905
13906 if (MINI_WINDOW_P (w))
13907 {
13908 if (w == XWINDOW (echo_area_window)
13909 && !NILP (echo_area_buffer[0]))
13910 {
13911 if (update_mode_line)
13912 /* We may have to update a tty frame's menu bar or a
13913 tool-bar. Example `M-x C-h C-h C-g'. */
13914 goto finish_menu_bars;
13915 else
13916 /* We've already displayed the echo area glyphs in this window. */
13917 goto finish_scroll_bars;
13918 }
13919 else if ((w != XWINDOW (minibuf_window)
13920 || minibuf_level == 0)
13921 /* When buffer is nonempty, redisplay window normally. */
13922 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13923 /* Quail displays non-mini buffers in minibuffer window.
13924 In that case, redisplay the window normally. */
13925 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13926 {
13927 /* W is a mini-buffer window, but it's not active, so clear
13928 it. */
13929 int yb = window_text_bottom_y (w);
13930 struct glyph_row *row;
13931 int y;
13932
13933 for (y = 0, row = w->desired_matrix->rows;
13934 y < yb;
13935 y += row->height, ++row)
13936 blank_row (w, row, y);
13937 goto finish_scroll_bars;
13938 }
13939
13940 clear_glyph_matrix (w->desired_matrix);
13941 }
13942
13943 /* Otherwise set up data on this window; select its buffer and point
13944 value. */
13945 /* Really select the buffer, for the sake of buffer-local
13946 variables. */
13947 set_buffer_internal_1 (XBUFFER (w->buffer));
13948
13949 current_matrix_up_to_date_p
13950 = (!NILP (w->window_end_valid)
13951 && !current_buffer->clip_changed
13952 && !current_buffer->prevent_redisplay_optimizations_p
13953 && XFASTINT (w->last_modified) >= MODIFF
13954 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13955
13956 /* Run the window-bottom-change-functions
13957 if it is possible that the text on the screen has changed
13958 (either due to modification of the text, or any other reason). */
13959 if (!current_matrix_up_to_date_p
13960 && !NILP (Vwindow_text_change_functions))
13961 {
13962 safe_run_hooks (Qwindow_text_change_functions);
13963 goto restart;
13964 }
13965
13966 beg_unchanged = BEG_UNCHANGED;
13967 end_unchanged = END_UNCHANGED;
13968
13969 SET_TEXT_POS (opoint, PT, PT_BYTE);
13970
13971 specbind (Qinhibit_point_motion_hooks, Qt);
13972
13973 buffer_unchanged_p
13974 = (!NILP (w->window_end_valid)
13975 && !current_buffer->clip_changed
13976 && XFASTINT (w->last_modified) >= MODIFF
13977 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13978
13979 /* When windows_or_buffers_changed is non-zero, we can't rely on
13980 the window end being valid, so set it to nil there. */
13981 if (windows_or_buffers_changed)
13982 {
13983 /* If window starts on a continuation line, maybe adjust the
13984 window start in case the window's width changed. */
13985 if (XMARKER (w->start)->buffer == current_buffer)
13986 compute_window_start_on_continuation_line (w);
13987
13988 w->window_end_valid = Qnil;
13989 }
13990
13991 /* Some sanity checks. */
13992 CHECK_WINDOW_END (w);
13993 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13994 abort ();
13995 if (BYTEPOS (opoint) < CHARPOS (opoint))
13996 abort ();
13997
13998 /* If %c is in mode line, update it if needed. */
13999 if (!NILP (w->column_number_displayed)
14000 /* This alternative quickly identifies a common case
14001 where no change is needed. */
14002 && !(PT == XFASTINT (w->last_point)
14003 && XFASTINT (w->last_modified) >= MODIFF
14004 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
14005 && (XFASTINT (w->column_number_displayed)
14006 != (int) current_column ())) /* iftc */
14007 update_mode_line = 1;
14008
14009 /* Count number of windows showing the selected buffer. An indirect
14010 buffer counts as its base buffer. */
14011 if (!just_this_one_p)
14012 {
14013 struct buffer *current_base, *window_base;
14014 current_base = current_buffer;
14015 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
14016 if (current_base->base_buffer)
14017 current_base = current_base->base_buffer;
14018 if (window_base->base_buffer)
14019 window_base = window_base->base_buffer;
14020 if (current_base == window_base)
14021 buffer_shared++;
14022 }
14023
14024 /* Point refers normally to the selected window. For any other
14025 window, set up appropriate value. */
14026 if (!EQ (window, selected_window))
14027 {
14028 int new_pt = XMARKER (w->pointm)->charpos;
14029 int new_pt_byte = marker_byte_position (w->pointm);
14030 if (new_pt < BEGV)
14031 {
14032 new_pt = BEGV;
14033 new_pt_byte = BEGV_BYTE;
14034 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
14035 }
14036 else if (new_pt > (ZV - 1))
14037 {
14038 new_pt = ZV;
14039 new_pt_byte = ZV_BYTE;
14040 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
14041 }
14042
14043 /* We don't use SET_PT so that the point-motion hooks don't run. */
14044 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
14045 }
14046
14047 /* If any of the character widths specified in the display table
14048 have changed, invalidate the width run cache. It's true that
14049 this may be a bit late to catch such changes, but the rest of
14050 redisplay goes (non-fatally) haywire when the display table is
14051 changed, so why should we worry about doing any better? */
14052 if (current_buffer->width_run_cache)
14053 {
14054 struct Lisp_Char_Table *disptab = buffer_display_table ();
14055
14056 if (! disptab_matches_widthtab (disptab,
14057 XVECTOR (current_buffer->width_table)))
14058 {
14059 invalidate_region_cache (current_buffer,
14060 current_buffer->width_run_cache,
14061 BEG, Z);
14062 recompute_width_table (current_buffer, disptab);
14063 }
14064 }
14065
14066 /* If window-start is screwed up, choose a new one. */
14067 if (XMARKER (w->start)->buffer != current_buffer)
14068 goto recenter;
14069
14070 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14071
14072 /* If someone specified a new starting point but did not insist,
14073 check whether it can be used. */
14074 if (!NILP (w->optional_new_start)
14075 && CHARPOS (startp) >= BEGV
14076 && CHARPOS (startp) <= ZV)
14077 {
14078 w->optional_new_start = Qnil;
14079 start_display (&it, w, startp);
14080 move_it_to (&it, PT, 0, it.last_visible_y, -1,
14081 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14082 if (IT_CHARPOS (it) == PT)
14083 w->force_start = Qt;
14084 /* IT may overshoot PT if text at PT is invisible. */
14085 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
14086 w->force_start = Qt;
14087 }
14088
14089 force_start:
14090
14091 /* Handle case where place to start displaying has been specified,
14092 unless the specified location is outside the accessible range. */
14093 if (!NILP (w->force_start)
14094 || w->frozen_window_start_p)
14095 {
14096 /* We set this later on if we have to adjust point. */
14097 int new_vpos = -1;
14098
14099 w->force_start = Qnil;
14100 w->vscroll = 0;
14101 w->window_end_valid = Qnil;
14102
14103 /* Forget any recorded base line for line number display. */
14104 if (!buffer_unchanged_p)
14105 w->base_line_number = Qnil;
14106
14107 /* Redisplay the mode line. Select the buffer properly for that.
14108 Also, run the hook window-scroll-functions
14109 because we have scrolled. */
14110 /* Note, we do this after clearing force_start because
14111 if there's an error, it is better to forget about force_start
14112 than to get into an infinite loop calling the hook functions
14113 and having them get more errors. */
14114 if (!update_mode_line
14115 || ! NILP (Vwindow_scroll_functions))
14116 {
14117 update_mode_line = 1;
14118 w->update_mode_line = Qt;
14119 startp = run_window_scroll_functions (window, startp);
14120 }
14121
14122 w->last_modified = make_number (0);
14123 w->last_overlay_modified = make_number (0);
14124 if (CHARPOS (startp) < BEGV)
14125 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14126 else if (CHARPOS (startp) > ZV)
14127 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14128
14129 /* Redisplay, then check if cursor has been set during the
14130 redisplay. Give up if new fonts were loaded. */
14131 /* We used to issue a CHECK_MARGINS argument to try_window here,
14132 but this causes scrolling to fail when point begins inside
14133 the scroll margin (bug#148) -- cyd */
14134 if (!try_window (window, startp, 0))
14135 {
14136 w->force_start = Qt;
14137 clear_glyph_matrix (w->desired_matrix);
14138 goto need_larger_matrices;
14139 }
14140
14141 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14142 {
14143 /* If point does not appear, try to move point so it does
14144 appear. The desired matrix has been built above, so we
14145 can use it here. */
14146 new_vpos = window_box_height (w) / 2;
14147 }
14148
14149 if (!cursor_row_fully_visible_p (w, 0, 0))
14150 {
14151 /* Point does appear, but on a line partly visible at end of window.
14152 Move it back to a fully-visible line. */
14153 new_vpos = window_box_height (w);
14154 }
14155
14156 /* If we need to move point for either of the above reasons,
14157 now actually do it. */
14158 if (new_vpos >= 0)
14159 {
14160 struct glyph_row *row;
14161
14162 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14163 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14164 ++row;
14165
14166 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14167 MATRIX_ROW_START_BYTEPOS (row));
14168
14169 if (w != XWINDOW (selected_window))
14170 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14171 else if (current_buffer == old)
14172 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14173
14174 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14175
14176 /* If we are highlighting the region, then we just changed
14177 the region, so redisplay to show it. */
14178 if (!NILP (Vtransient_mark_mode)
14179 && !NILP (current_buffer->mark_active))
14180 {
14181 clear_glyph_matrix (w->desired_matrix);
14182 if (!try_window (window, startp, 0))
14183 goto need_larger_matrices;
14184 }
14185 }
14186
14187 #if GLYPH_DEBUG
14188 debug_method_add (w, "forced window start");
14189 #endif
14190 goto done;
14191 }
14192
14193 /* Handle case where text has not changed, only point, and it has
14194 not moved off the frame, and we are not retrying after hscroll.
14195 (current_matrix_up_to_date_p is nonzero when retrying.) */
14196 if (current_matrix_up_to_date_p
14197 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14198 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14199 {
14200 switch (rc)
14201 {
14202 case CURSOR_MOVEMENT_SUCCESS:
14203 used_current_matrix_p = 1;
14204 goto done;
14205
14206 case CURSOR_MOVEMENT_MUST_SCROLL:
14207 goto try_to_scroll;
14208
14209 default:
14210 abort ();
14211 }
14212 }
14213 /* If current starting point was originally the beginning of a line
14214 but no longer is, find a new starting point. */
14215 else if (!NILP (w->start_at_line_beg)
14216 && !(CHARPOS (startp) <= BEGV
14217 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14218 {
14219 #if GLYPH_DEBUG
14220 debug_method_add (w, "recenter 1");
14221 #endif
14222 goto recenter;
14223 }
14224
14225 /* Try scrolling with try_window_id. Value is > 0 if update has
14226 been done, it is -1 if we know that the same window start will
14227 not work. It is 0 if unsuccessful for some other reason. */
14228 else if ((tem = try_window_id (w)) != 0)
14229 {
14230 #if GLYPH_DEBUG
14231 debug_method_add (w, "try_window_id %d", tem);
14232 #endif
14233
14234 if (fonts_changed_p)
14235 goto need_larger_matrices;
14236 if (tem > 0)
14237 goto done;
14238
14239 /* Otherwise try_window_id has returned -1 which means that we
14240 don't want the alternative below this comment to execute. */
14241 }
14242 else if (CHARPOS (startp) >= BEGV
14243 && CHARPOS (startp) <= ZV
14244 && PT >= CHARPOS (startp)
14245 && (CHARPOS (startp) < ZV
14246 /* Avoid starting at end of buffer. */
14247 || CHARPOS (startp) == BEGV
14248 || (XFASTINT (w->last_modified) >= MODIFF
14249 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14250 {
14251
14252 /* If first window line is a continuation line, and window start
14253 is inside the modified region, but the first change is before
14254 current window start, we must select a new window start.
14255
14256 However, if this is the result of a down-mouse event (e.g. by
14257 extending the mouse-drag-overlay), we don't want to select a
14258 new window start, since that would change the position under
14259 the mouse, resulting in an unwanted mouse-movement rather
14260 than a simple mouse-click. */
14261 if (NILP (w->start_at_line_beg)
14262 && NILP (do_mouse_tracking)
14263 && CHARPOS (startp) > BEGV
14264 && CHARPOS (startp) > BEG + beg_unchanged
14265 && CHARPOS (startp) <= Z - end_unchanged
14266 /* Even if w->start_at_line_beg is nil, a new window may
14267 start at a line_beg, since that's how set_buffer_window
14268 sets it. So, we need to check the return value of
14269 compute_window_start_on_continuation_line. (See also
14270 bug#197). */
14271 && XMARKER (w->start)->buffer == current_buffer
14272 && compute_window_start_on_continuation_line (w))
14273 {
14274 w->force_start = Qt;
14275 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14276 goto force_start;
14277 }
14278
14279 #if GLYPH_DEBUG
14280 debug_method_add (w, "same window start");
14281 #endif
14282
14283 /* Try to redisplay starting at same place as before.
14284 If point has not moved off frame, accept the results. */
14285 if (!current_matrix_up_to_date_p
14286 /* Don't use try_window_reusing_current_matrix in this case
14287 because a window scroll function can have changed the
14288 buffer. */
14289 || !NILP (Vwindow_scroll_functions)
14290 || MINI_WINDOW_P (w)
14291 || !(used_current_matrix_p
14292 = try_window_reusing_current_matrix (w)))
14293 {
14294 IF_DEBUG (debug_method_add (w, "1"));
14295 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14296 /* -1 means we need to scroll.
14297 0 means we need new matrices, but fonts_changed_p
14298 is set in that case, so we will detect it below. */
14299 goto try_to_scroll;
14300 }
14301
14302 if (fonts_changed_p)
14303 goto need_larger_matrices;
14304
14305 if (w->cursor.vpos >= 0)
14306 {
14307 if (!just_this_one_p
14308 || current_buffer->clip_changed
14309 || BEG_UNCHANGED < CHARPOS (startp))
14310 /* Forget any recorded base line for line number display. */
14311 w->base_line_number = Qnil;
14312
14313 if (!cursor_row_fully_visible_p (w, 1, 0))
14314 {
14315 clear_glyph_matrix (w->desired_matrix);
14316 last_line_misfit = 1;
14317 }
14318 /* Drop through and scroll. */
14319 else
14320 goto done;
14321 }
14322 else
14323 clear_glyph_matrix (w->desired_matrix);
14324 }
14325
14326 try_to_scroll:
14327
14328 w->last_modified = make_number (0);
14329 w->last_overlay_modified = make_number (0);
14330
14331 /* Redisplay the mode line. Select the buffer properly for that. */
14332 if (!update_mode_line)
14333 {
14334 update_mode_line = 1;
14335 w->update_mode_line = Qt;
14336 }
14337
14338 /* Try to scroll by specified few lines. */
14339 if ((scroll_conservatively
14340 || scroll_step
14341 || temp_scroll_step
14342 || NUMBERP (current_buffer->scroll_up_aggressively)
14343 || NUMBERP (current_buffer->scroll_down_aggressively))
14344 && !current_buffer->clip_changed
14345 && CHARPOS (startp) >= BEGV
14346 && CHARPOS (startp) <= ZV)
14347 {
14348 /* The function returns -1 if new fonts were loaded, 1 if
14349 successful, 0 if not successful. */
14350 int rc = try_scrolling (window, just_this_one_p,
14351 scroll_conservatively,
14352 scroll_step,
14353 temp_scroll_step, last_line_misfit);
14354 switch (rc)
14355 {
14356 case SCROLLING_SUCCESS:
14357 goto done;
14358
14359 case SCROLLING_NEED_LARGER_MATRICES:
14360 goto need_larger_matrices;
14361
14362 case SCROLLING_FAILED:
14363 break;
14364
14365 default:
14366 abort ();
14367 }
14368 }
14369
14370 /* Finally, just choose place to start which centers point */
14371
14372 recenter:
14373 if (centering_position < 0)
14374 centering_position = window_box_height (w) / 2;
14375
14376 #if GLYPH_DEBUG
14377 debug_method_add (w, "recenter");
14378 #endif
14379
14380 /* w->vscroll = 0; */
14381
14382 /* Forget any previously recorded base line for line number display. */
14383 if (!buffer_unchanged_p)
14384 w->base_line_number = Qnil;
14385
14386 /* Move backward half the height of the window. */
14387 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14388 it.current_y = it.last_visible_y;
14389 move_it_vertically_backward (&it, centering_position);
14390 xassert (IT_CHARPOS (it) >= BEGV);
14391
14392 /* The function move_it_vertically_backward may move over more
14393 than the specified y-distance. If it->w is small, e.g. a
14394 mini-buffer window, we may end up in front of the window's
14395 display area. Start displaying at the start of the line
14396 containing PT in this case. */
14397 if (it.current_y <= 0)
14398 {
14399 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14400 move_it_vertically_backward (&it, 0);
14401 it.current_y = 0;
14402 }
14403
14404 it.current_x = it.hpos = 0;
14405
14406 /* Set startp here explicitly in case that helps avoid an infinite loop
14407 in case the window-scroll-functions functions get errors. */
14408 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14409
14410 /* Run scroll hooks. */
14411 startp = run_window_scroll_functions (window, it.current.pos);
14412
14413 /* Redisplay the window. */
14414 if (!current_matrix_up_to_date_p
14415 || windows_or_buffers_changed
14416 || cursor_type_changed
14417 /* Don't use try_window_reusing_current_matrix in this case
14418 because it can have changed the buffer. */
14419 || !NILP (Vwindow_scroll_functions)
14420 || !just_this_one_p
14421 || MINI_WINDOW_P (w)
14422 || !(used_current_matrix_p
14423 = try_window_reusing_current_matrix (w)))
14424 try_window (window, startp, 0);
14425
14426 /* If new fonts have been loaded (due to fontsets), give up. We
14427 have to start a new redisplay since we need to re-adjust glyph
14428 matrices. */
14429 if (fonts_changed_p)
14430 goto need_larger_matrices;
14431
14432 /* If cursor did not appear assume that the middle of the window is
14433 in the first line of the window. Do it again with the next line.
14434 (Imagine a window of height 100, displaying two lines of height
14435 60. Moving back 50 from it->last_visible_y will end in the first
14436 line.) */
14437 if (w->cursor.vpos < 0)
14438 {
14439 if (!NILP (w->window_end_valid)
14440 && PT >= Z - XFASTINT (w->window_end_pos))
14441 {
14442 clear_glyph_matrix (w->desired_matrix);
14443 move_it_by_lines (&it, 1, 0);
14444 try_window (window, it.current.pos, 0);
14445 }
14446 else if (PT < IT_CHARPOS (it))
14447 {
14448 clear_glyph_matrix (w->desired_matrix);
14449 move_it_by_lines (&it, -1, 0);
14450 try_window (window, it.current.pos, 0);
14451 }
14452 else
14453 {
14454 /* Not much we can do about it. */
14455 }
14456 }
14457
14458 /* Consider the following case: Window starts at BEGV, there is
14459 invisible, intangible text at BEGV, so that display starts at
14460 some point START > BEGV. It can happen that we are called with
14461 PT somewhere between BEGV and START. Try to handle that case. */
14462 if (w->cursor.vpos < 0)
14463 {
14464 struct glyph_row *row = w->current_matrix->rows;
14465 if (row->mode_line_p)
14466 ++row;
14467 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14468 }
14469
14470 if (!cursor_row_fully_visible_p (w, 0, 0))
14471 {
14472 /* If vscroll is enabled, disable it and try again. */
14473 if (w->vscroll)
14474 {
14475 w->vscroll = 0;
14476 clear_glyph_matrix (w->desired_matrix);
14477 goto recenter;
14478 }
14479
14480 /* If centering point failed to make the whole line visible,
14481 put point at the top instead. That has to make the whole line
14482 visible, if it can be done. */
14483 if (centering_position == 0)
14484 goto done;
14485
14486 clear_glyph_matrix (w->desired_matrix);
14487 centering_position = 0;
14488 goto recenter;
14489 }
14490
14491 done:
14492
14493 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14494 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14495 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14496 ? Qt : Qnil);
14497
14498 /* Display the mode line, if we must. */
14499 if ((update_mode_line
14500 /* If window not full width, must redo its mode line
14501 if (a) the window to its side is being redone and
14502 (b) we do a frame-based redisplay. This is a consequence
14503 of how inverted lines are drawn in frame-based redisplay. */
14504 || (!just_this_one_p
14505 && !FRAME_WINDOW_P (f)
14506 && !WINDOW_FULL_WIDTH_P (w))
14507 /* Line number to display. */
14508 || INTEGERP (w->base_line_pos)
14509 /* Column number is displayed and different from the one displayed. */
14510 || (!NILP (w->column_number_displayed)
14511 && (XFASTINT (w->column_number_displayed)
14512 != (int) current_column ()))) /* iftc */
14513 /* This means that the window has a mode line. */
14514 && (WINDOW_WANTS_MODELINE_P (w)
14515 || WINDOW_WANTS_HEADER_LINE_P (w)))
14516 {
14517 display_mode_lines (w);
14518
14519 /* If mode line height has changed, arrange for a thorough
14520 immediate redisplay using the correct mode line height. */
14521 if (WINDOW_WANTS_MODELINE_P (w)
14522 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14523 {
14524 fonts_changed_p = 1;
14525 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14526 = DESIRED_MODE_LINE_HEIGHT (w);
14527 }
14528
14529 /* If header line height has changed, arrange for a thorough
14530 immediate redisplay using the correct header line height. */
14531 if (WINDOW_WANTS_HEADER_LINE_P (w)
14532 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14533 {
14534 fonts_changed_p = 1;
14535 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14536 = DESIRED_HEADER_LINE_HEIGHT (w);
14537 }
14538
14539 if (fonts_changed_p)
14540 goto need_larger_matrices;
14541 }
14542
14543 if (!line_number_displayed
14544 && !BUFFERP (w->base_line_pos))
14545 {
14546 w->base_line_pos = Qnil;
14547 w->base_line_number = Qnil;
14548 }
14549
14550 finish_menu_bars:
14551
14552 /* When we reach a frame's selected window, redo the frame's menu bar. */
14553 if (update_mode_line
14554 && EQ (FRAME_SELECTED_WINDOW (f), window))
14555 {
14556 int redisplay_menu_p = 0;
14557 int redisplay_tool_bar_p = 0;
14558
14559 if (FRAME_WINDOW_P (f))
14560 {
14561 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14562 || defined (HAVE_NS) || defined (USE_GTK)
14563 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14564 #else
14565 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14566 #endif
14567 }
14568 else
14569 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14570
14571 if (redisplay_menu_p)
14572 display_menu_bar (w);
14573
14574 #ifdef HAVE_WINDOW_SYSTEM
14575 if (FRAME_WINDOW_P (f))
14576 {
14577 #if defined (USE_GTK) || defined (HAVE_NS)
14578 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
14579 #else
14580 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
14581 && (FRAME_TOOL_BAR_LINES (f) > 0
14582 || !NILP (Vauto_resize_tool_bars));
14583 #endif
14584
14585 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
14586 {
14587 extern int ignore_mouse_drag_p;
14588 ignore_mouse_drag_p = 1;
14589 }
14590 }
14591 #endif
14592 }
14593
14594 #ifdef HAVE_WINDOW_SYSTEM
14595 if (FRAME_WINDOW_P (f)
14596 && update_window_fringes (w, (just_this_one_p
14597 || (!used_current_matrix_p && !overlay_arrow_seen)
14598 || w->pseudo_window_p)))
14599 {
14600 update_begin (f);
14601 BLOCK_INPUT;
14602 if (draw_window_fringes (w, 1))
14603 x_draw_vertical_border (w);
14604 UNBLOCK_INPUT;
14605 update_end (f);
14606 }
14607 #endif /* HAVE_WINDOW_SYSTEM */
14608
14609 /* We go to this label, with fonts_changed_p nonzero,
14610 if it is necessary to try again using larger glyph matrices.
14611 We have to redeem the scroll bar even in this case,
14612 because the loop in redisplay_internal expects that. */
14613 need_larger_matrices:
14614 ;
14615 finish_scroll_bars:
14616
14617 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14618 {
14619 /* Set the thumb's position and size. */
14620 set_vertical_scroll_bar (w);
14621
14622 /* Note that we actually used the scroll bar attached to this
14623 window, so it shouldn't be deleted at the end of redisplay. */
14624 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14625 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14626 }
14627
14628 /* Restore current_buffer and value of point in it. */
14629 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14630 set_buffer_internal_1 (old);
14631 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14632 shorter. This can be caused by log truncation in *Messages*. */
14633 if (CHARPOS (lpoint) <= ZV)
14634 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14635
14636 unbind_to (count, Qnil);
14637 }
14638
14639
14640 /* Build the complete desired matrix of WINDOW with a window start
14641 buffer position POS.
14642
14643 Value is 1 if successful. It is zero if fonts were loaded during
14644 redisplay which makes re-adjusting glyph matrices necessary, and -1
14645 if point would appear in the scroll margins.
14646 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14647 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14648 set in FLAGS.) */
14649
14650 int
14651 try_window (window, pos, flags)
14652 Lisp_Object window;
14653 struct text_pos pos;
14654 int flags;
14655 {
14656 struct window *w = XWINDOW (window);
14657 struct it it;
14658 struct glyph_row *last_text_row = NULL;
14659 struct frame *f = XFRAME (w->frame);
14660
14661 /* Make POS the new window start. */
14662 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14663
14664 /* Mark cursor position as unknown. No overlay arrow seen. */
14665 w->cursor.vpos = -1;
14666 overlay_arrow_seen = 0;
14667
14668 /* Initialize iterator and info to start at POS. */
14669 start_display (&it, w, pos);
14670
14671 /* Display all lines of W. */
14672 while (it.current_y < it.last_visible_y)
14673 {
14674 if (display_line (&it))
14675 last_text_row = it.glyph_row - 1;
14676 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14677 return 0;
14678 }
14679
14680 /* Don't let the cursor end in the scroll margins. */
14681 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14682 && !MINI_WINDOW_P (w))
14683 {
14684 int this_scroll_margin;
14685
14686 if (scroll_margin > 0)
14687 {
14688 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14689 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14690 }
14691 else
14692 this_scroll_margin = 0;
14693
14694 if ((w->cursor.y >= 0 /* not vscrolled */
14695 && w->cursor.y < this_scroll_margin
14696 && CHARPOS (pos) > BEGV
14697 && IT_CHARPOS (it) < ZV)
14698 /* rms: considering make_cursor_line_fully_visible_p here
14699 seems to give wrong results. We don't want to recenter
14700 when the last line is partly visible, we want to allow
14701 that case to be handled in the usual way. */
14702 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14703 {
14704 w->cursor.vpos = -1;
14705 clear_glyph_matrix (w->desired_matrix);
14706 return -1;
14707 }
14708 }
14709
14710 /* If bottom moved off end of frame, change mode line percentage. */
14711 if (XFASTINT (w->window_end_pos) <= 0
14712 && Z != IT_CHARPOS (it))
14713 w->update_mode_line = Qt;
14714
14715 /* Set window_end_pos to the offset of the last character displayed
14716 on the window from the end of current_buffer. Set
14717 window_end_vpos to its row number. */
14718 if (last_text_row)
14719 {
14720 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14721 w->window_end_bytepos
14722 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14723 w->window_end_pos
14724 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14725 w->window_end_vpos
14726 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14727 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14728 ->displays_text_p);
14729 }
14730 else
14731 {
14732 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14733 w->window_end_pos = make_number (Z - ZV);
14734 w->window_end_vpos = make_number (0);
14735 }
14736
14737 /* But that is not valid info until redisplay finishes. */
14738 w->window_end_valid = Qnil;
14739 return 1;
14740 }
14741
14742
14743 \f
14744 /************************************************************************
14745 Window redisplay reusing current matrix when buffer has not changed
14746 ************************************************************************/
14747
14748 /* Try redisplay of window W showing an unchanged buffer with a
14749 different window start than the last time it was displayed by
14750 reusing its current matrix. Value is non-zero if successful.
14751 W->start is the new window start. */
14752
14753 static int
14754 try_window_reusing_current_matrix (w)
14755 struct window *w;
14756 {
14757 struct frame *f = XFRAME (w->frame);
14758 struct glyph_row *row, *bottom_row;
14759 struct it it;
14760 struct run run;
14761 struct text_pos start, new_start;
14762 int nrows_scrolled, i;
14763 struct glyph_row *last_text_row;
14764 struct glyph_row *last_reused_text_row;
14765 struct glyph_row *start_row;
14766 int start_vpos, min_y, max_y;
14767
14768 #if GLYPH_DEBUG
14769 if (inhibit_try_window_reusing)
14770 return 0;
14771 #endif
14772
14773 if (/* This function doesn't handle terminal frames. */
14774 !FRAME_WINDOW_P (f)
14775 /* Don't try to reuse the display if windows have been split
14776 or such. */
14777 || windows_or_buffers_changed
14778 || cursor_type_changed)
14779 return 0;
14780
14781 /* Can't do this if region may have changed. */
14782 if ((!NILP (Vtransient_mark_mode)
14783 && !NILP (current_buffer->mark_active))
14784 || !NILP (w->region_showing)
14785 || !NILP (Vshow_trailing_whitespace))
14786 return 0;
14787
14788 /* If top-line visibility has changed, give up. */
14789 if (WINDOW_WANTS_HEADER_LINE_P (w)
14790 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14791 return 0;
14792
14793 /* Give up if old or new display is scrolled vertically. We could
14794 make this function handle this, but right now it doesn't. */
14795 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14796 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14797 return 0;
14798
14799 /* The variable new_start now holds the new window start. The old
14800 start `start' can be determined from the current matrix. */
14801 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14802 start = start_row->start.pos;
14803 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14804
14805 /* Clear the desired matrix for the display below. */
14806 clear_glyph_matrix (w->desired_matrix);
14807
14808 if (CHARPOS (new_start) <= CHARPOS (start))
14809 {
14810 int first_row_y;
14811
14812 /* Don't use this method if the display starts with an ellipsis
14813 displayed for invisible text. It's not easy to handle that case
14814 below, and it's certainly not worth the effort since this is
14815 not a frequent case. */
14816 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14817 return 0;
14818
14819 IF_DEBUG (debug_method_add (w, "twu1"));
14820
14821 /* Display up to a row that can be reused. The variable
14822 last_text_row is set to the last row displayed that displays
14823 text. Note that it.vpos == 0 if or if not there is a
14824 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14825 start_display (&it, w, new_start);
14826 first_row_y = it.current_y;
14827 w->cursor.vpos = -1;
14828 last_text_row = last_reused_text_row = NULL;
14829
14830 while (it.current_y < it.last_visible_y
14831 && !fonts_changed_p)
14832 {
14833 /* If we have reached into the characters in the START row,
14834 that means the line boundaries have changed. So we
14835 can't start copying with the row START. Maybe it will
14836 work to start copying with the following row. */
14837 while (IT_CHARPOS (it) > CHARPOS (start))
14838 {
14839 /* Advance to the next row as the "start". */
14840 start_row++;
14841 start = start_row->start.pos;
14842 /* If there are no more rows to try, or just one, give up. */
14843 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14844 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14845 || CHARPOS (start) == ZV)
14846 {
14847 clear_glyph_matrix (w->desired_matrix);
14848 return 0;
14849 }
14850
14851 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14852 }
14853 /* If we have reached alignment,
14854 we can copy the rest of the rows. */
14855 if (IT_CHARPOS (it) == CHARPOS (start))
14856 break;
14857
14858 if (display_line (&it))
14859 last_text_row = it.glyph_row - 1;
14860 }
14861
14862 /* A value of current_y < last_visible_y means that we stopped
14863 at the previous window start, which in turn means that we
14864 have at least one reusable row. */
14865 if (it.current_y < it.last_visible_y)
14866 {
14867 /* IT.vpos always starts from 0; it counts text lines. */
14868 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14869
14870 /* Find PT if not already found in the lines displayed. */
14871 if (w->cursor.vpos < 0)
14872 {
14873 int dy = it.current_y - start_row->y;
14874
14875 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14876 row = row_containing_pos (w, PT, row, NULL, dy);
14877 if (row)
14878 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14879 dy, nrows_scrolled);
14880 else
14881 {
14882 clear_glyph_matrix (w->desired_matrix);
14883 return 0;
14884 }
14885 }
14886
14887 /* Scroll the display. Do it before the current matrix is
14888 changed. The problem here is that update has not yet
14889 run, i.e. part of the current matrix is not up to date.
14890 scroll_run_hook will clear the cursor, and use the
14891 current matrix to get the height of the row the cursor is
14892 in. */
14893 run.current_y = start_row->y;
14894 run.desired_y = it.current_y;
14895 run.height = it.last_visible_y - it.current_y;
14896
14897 if (run.height > 0 && run.current_y != run.desired_y)
14898 {
14899 update_begin (f);
14900 FRAME_RIF (f)->update_window_begin_hook (w);
14901 FRAME_RIF (f)->clear_window_mouse_face (w);
14902 FRAME_RIF (f)->scroll_run_hook (w, &run);
14903 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14904 update_end (f);
14905 }
14906
14907 /* Shift current matrix down by nrows_scrolled lines. */
14908 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14909 rotate_matrix (w->current_matrix,
14910 start_vpos,
14911 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14912 nrows_scrolled);
14913
14914 /* Disable lines that must be updated. */
14915 for (i = 0; i < nrows_scrolled; ++i)
14916 (start_row + i)->enabled_p = 0;
14917
14918 /* Re-compute Y positions. */
14919 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14920 max_y = it.last_visible_y;
14921 for (row = start_row + nrows_scrolled;
14922 row < bottom_row;
14923 ++row)
14924 {
14925 row->y = it.current_y;
14926 row->visible_height = row->height;
14927
14928 if (row->y < min_y)
14929 row->visible_height -= min_y - row->y;
14930 if (row->y + row->height > max_y)
14931 row->visible_height -= row->y + row->height - max_y;
14932 row->redraw_fringe_bitmaps_p = 1;
14933
14934 it.current_y += row->height;
14935
14936 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14937 last_reused_text_row = row;
14938 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14939 break;
14940 }
14941
14942 /* Disable lines in the current matrix which are now
14943 below the window. */
14944 for (++row; row < bottom_row; ++row)
14945 row->enabled_p = row->mode_line_p = 0;
14946 }
14947
14948 /* Update window_end_pos etc.; last_reused_text_row is the last
14949 reused row from the current matrix containing text, if any.
14950 The value of last_text_row is the last displayed line
14951 containing text. */
14952 if (last_reused_text_row)
14953 {
14954 w->window_end_bytepos
14955 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14956 w->window_end_pos
14957 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14958 w->window_end_vpos
14959 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14960 w->current_matrix));
14961 }
14962 else if (last_text_row)
14963 {
14964 w->window_end_bytepos
14965 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14966 w->window_end_pos
14967 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14968 w->window_end_vpos
14969 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14970 }
14971 else
14972 {
14973 /* This window must be completely empty. */
14974 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14975 w->window_end_pos = make_number (Z - ZV);
14976 w->window_end_vpos = make_number (0);
14977 }
14978 w->window_end_valid = Qnil;
14979
14980 /* Update hint: don't try scrolling again in update_window. */
14981 w->desired_matrix->no_scrolling_p = 1;
14982
14983 #if GLYPH_DEBUG
14984 debug_method_add (w, "try_window_reusing_current_matrix 1");
14985 #endif
14986 return 1;
14987 }
14988 else if (CHARPOS (new_start) > CHARPOS (start))
14989 {
14990 struct glyph_row *pt_row, *row;
14991 struct glyph_row *first_reusable_row;
14992 struct glyph_row *first_row_to_display;
14993 int dy;
14994 int yb = window_text_bottom_y (w);
14995
14996 /* Find the row starting at new_start, if there is one. Don't
14997 reuse a partially visible line at the end. */
14998 first_reusable_row = start_row;
14999 while (first_reusable_row->enabled_p
15000 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
15001 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15002 < CHARPOS (new_start)))
15003 ++first_reusable_row;
15004
15005 /* Give up if there is no row to reuse. */
15006 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
15007 || !first_reusable_row->enabled_p
15008 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15009 != CHARPOS (new_start)))
15010 return 0;
15011
15012 /* We can reuse fully visible rows beginning with
15013 first_reusable_row to the end of the window. Set
15014 first_row_to_display to the first row that cannot be reused.
15015 Set pt_row to the row containing point, if there is any. */
15016 pt_row = NULL;
15017 for (first_row_to_display = first_reusable_row;
15018 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
15019 ++first_row_to_display)
15020 {
15021 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
15022 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
15023 pt_row = first_row_to_display;
15024 }
15025
15026 /* Start displaying at the start of first_row_to_display. */
15027 xassert (first_row_to_display->y < yb);
15028 init_to_row_start (&it, w, first_row_to_display);
15029
15030 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
15031 - start_vpos);
15032 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
15033 - nrows_scrolled);
15034 it.current_y = (first_row_to_display->y - first_reusable_row->y
15035 + WINDOW_HEADER_LINE_HEIGHT (w));
15036
15037 /* Display lines beginning with first_row_to_display in the
15038 desired matrix. Set last_text_row to the last row displayed
15039 that displays text. */
15040 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
15041 if (pt_row == NULL)
15042 w->cursor.vpos = -1;
15043 last_text_row = NULL;
15044 while (it.current_y < it.last_visible_y && !fonts_changed_p)
15045 if (display_line (&it))
15046 last_text_row = it.glyph_row - 1;
15047
15048 /* If point is in a reused row, adjust y and vpos of the cursor
15049 position. */
15050 if (pt_row)
15051 {
15052 w->cursor.vpos -= nrows_scrolled;
15053 w->cursor.y -= first_reusable_row->y - start_row->y;
15054 }
15055
15056 /* Give up if point isn't in a row displayed or reused. (This
15057 also handles the case where w->cursor.vpos < nrows_scrolled
15058 after the calls to display_line, which can happen with scroll
15059 margins. See bug#1295.) */
15060 if (w->cursor.vpos < 0)
15061 {
15062 clear_glyph_matrix (w->desired_matrix);
15063 return 0;
15064 }
15065
15066 /* Scroll the display. */
15067 run.current_y = first_reusable_row->y;
15068 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
15069 run.height = it.last_visible_y - run.current_y;
15070 dy = run.current_y - run.desired_y;
15071
15072 if (run.height)
15073 {
15074 update_begin (f);
15075 FRAME_RIF (f)->update_window_begin_hook (w);
15076 FRAME_RIF (f)->clear_window_mouse_face (w);
15077 FRAME_RIF (f)->scroll_run_hook (w, &run);
15078 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15079 update_end (f);
15080 }
15081
15082 /* Adjust Y positions of reused rows. */
15083 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
15084 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
15085 max_y = it.last_visible_y;
15086 for (row = first_reusable_row; row < first_row_to_display; ++row)
15087 {
15088 row->y -= dy;
15089 row->visible_height = row->height;
15090 if (row->y < min_y)
15091 row->visible_height -= min_y - row->y;
15092 if (row->y + row->height > max_y)
15093 row->visible_height -= row->y + row->height - max_y;
15094 row->redraw_fringe_bitmaps_p = 1;
15095 }
15096
15097 /* Scroll the current matrix. */
15098 xassert (nrows_scrolled > 0);
15099 rotate_matrix (w->current_matrix,
15100 start_vpos,
15101 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15102 -nrows_scrolled);
15103
15104 /* Disable rows not reused. */
15105 for (row -= nrows_scrolled; row < bottom_row; ++row)
15106 row->enabled_p = 0;
15107
15108 /* Point may have moved to a different line, so we cannot assume that
15109 the previous cursor position is valid; locate the correct row. */
15110 if (pt_row)
15111 {
15112 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15113 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15114 row++)
15115 {
15116 w->cursor.vpos++;
15117 w->cursor.y = row->y;
15118 }
15119 if (row < bottom_row)
15120 {
15121 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15122 struct glyph *end = glyph + row->used[TEXT_AREA];
15123 struct glyph *orig_glyph = glyph;
15124 struct cursor_pos orig_cursor = w->cursor;
15125
15126 for (; glyph < end
15127 && (!BUFFERP (glyph->object)
15128 || glyph->charpos != PT);
15129 glyph++)
15130 {
15131 w->cursor.hpos++;
15132 w->cursor.x += glyph->pixel_width;
15133 }
15134 /* With bidi reordering, charpos changes non-linearly
15135 with hpos, so the right glyph could be to the
15136 left. */
15137 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15138 && (!BUFFERP (glyph->object) || glyph->charpos != PT))
15139 {
15140 struct glyph *start_glyph = row->glyphs[TEXT_AREA];
15141
15142 glyph = orig_glyph - 1;
15143 orig_cursor.hpos--;
15144 orig_cursor.x -= glyph->pixel_width;
15145 for (; glyph >= start_glyph
15146 && (!BUFFERP (glyph->object)
15147 || glyph->charpos != PT);
15148 glyph--)
15149 {
15150 w->cursor.hpos--;
15151 w->cursor.x -= glyph->pixel_width;
15152 }
15153 if (BUFFERP (glyph->object) && glyph->charpos == PT)
15154 w->cursor = orig_cursor;
15155 }
15156 }
15157 }
15158
15159 /* Adjust window end. A null value of last_text_row means that
15160 the window end is in reused rows which in turn means that
15161 only its vpos can have changed. */
15162 if (last_text_row)
15163 {
15164 w->window_end_bytepos
15165 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15166 w->window_end_pos
15167 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15168 w->window_end_vpos
15169 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15170 }
15171 else
15172 {
15173 w->window_end_vpos
15174 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15175 }
15176
15177 w->window_end_valid = Qnil;
15178 w->desired_matrix->no_scrolling_p = 1;
15179
15180 #if GLYPH_DEBUG
15181 debug_method_add (w, "try_window_reusing_current_matrix 2");
15182 #endif
15183 return 1;
15184 }
15185
15186 return 0;
15187 }
15188
15189
15190 \f
15191 /************************************************************************
15192 Window redisplay reusing current matrix when buffer has changed
15193 ************************************************************************/
15194
15195 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
15196 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
15197 int *, int *));
15198 static struct glyph_row *
15199 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
15200 struct glyph_row *));
15201
15202
15203 /* Return the last row in MATRIX displaying text. If row START is
15204 non-null, start searching with that row. IT gives the dimensions
15205 of the display. Value is null if matrix is empty; otherwise it is
15206 a pointer to the row found. */
15207
15208 static struct glyph_row *
15209 find_last_row_displaying_text (matrix, it, start)
15210 struct glyph_matrix *matrix;
15211 struct it *it;
15212 struct glyph_row *start;
15213 {
15214 struct glyph_row *row, *row_found;
15215
15216 /* Set row_found to the last row in IT->w's current matrix
15217 displaying text. The loop looks funny but think of partially
15218 visible lines. */
15219 row_found = NULL;
15220 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15221 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15222 {
15223 xassert (row->enabled_p);
15224 row_found = row;
15225 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15226 break;
15227 ++row;
15228 }
15229
15230 return row_found;
15231 }
15232
15233
15234 /* Return the last row in the current matrix of W that is not affected
15235 by changes at the start of current_buffer that occurred since W's
15236 current matrix was built. Value is null if no such row exists.
15237
15238 BEG_UNCHANGED us the number of characters unchanged at the start of
15239 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15240 first changed character in current_buffer. Characters at positions <
15241 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15242 when the current matrix was built. */
15243
15244 static struct glyph_row *
15245 find_last_unchanged_at_beg_row (w)
15246 struct window *w;
15247 {
15248 int first_changed_pos = BEG + BEG_UNCHANGED;
15249 struct glyph_row *row;
15250 struct glyph_row *row_found = NULL;
15251 int yb = window_text_bottom_y (w);
15252
15253 /* Find the last row displaying unchanged text. */
15254 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15255 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15256 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15257 ++row)
15258 {
15259 if (/* If row ends before first_changed_pos, it is unchanged,
15260 except in some case. */
15261 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15262 /* When row ends in ZV and we write at ZV it is not
15263 unchanged. */
15264 && !row->ends_at_zv_p
15265 /* When first_changed_pos is the end of a continued line,
15266 row is not unchanged because it may be no longer
15267 continued. */
15268 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15269 && (row->continued_p
15270 || row->exact_window_width_line_p)))
15271 row_found = row;
15272
15273 /* Stop if last visible row. */
15274 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15275 break;
15276 }
15277
15278 return row_found;
15279 }
15280
15281
15282 /* Find the first glyph row in the current matrix of W that is not
15283 affected by changes at the end of current_buffer since the
15284 time W's current matrix was built.
15285
15286 Return in *DELTA the number of chars by which buffer positions in
15287 unchanged text at the end of current_buffer must be adjusted.
15288
15289 Return in *DELTA_BYTES the corresponding number of bytes.
15290
15291 Value is null if no such row exists, i.e. all rows are affected by
15292 changes. */
15293
15294 static struct glyph_row *
15295 find_first_unchanged_at_end_row (w, delta, delta_bytes)
15296 struct window *w;
15297 int *delta, *delta_bytes;
15298 {
15299 struct glyph_row *row;
15300 struct glyph_row *row_found = NULL;
15301
15302 *delta = *delta_bytes = 0;
15303
15304 /* Display must not have been paused, otherwise the current matrix
15305 is not up to date. */
15306 eassert (!NILP (w->window_end_valid));
15307
15308 /* A value of window_end_pos >= END_UNCHANGED means that the window
15309 end is in the range of changed text. If so, there is no
15310 unchanged row at the end of W's current matrix. */
15311 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15312 return NULL;
15313
15314 /* Set row to the last row in W's current matrix displaying text. */
15315 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15316
15317 /* If matrix is entirely empty, no unchanged row exists. */
15318 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15319 {
15320 /* The value of row is the last glyph row in the matrix having a
15321 meaningful buffer position in it. The end position of row
15322 corresponds to window_end_pos. This allows us to translate
15323 buffer positions in the current matrix to current buffer
15324 positions for characters not in changed text. */
15325 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15326 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15327 int last_unchanged_pos, last_unchanged_pos_old;
15328 struct glyph_row *first_text_row
15329 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15330
15331 *delta = Z - Z_old;
15332 *delta_bytes = Z_BYTE - Z_BYTE_old;
15333
15334 /* Set last_unchanged_pos to the buffer position of the last
15335 character in the buffer that has not been changed. Z is the
15336 index + 1 of the last character in current_buffer, i.e. by
15337 subtracting END_UNCHANGED we get the index of the last
15338 unchanged character, and we have to add BEG to get its buffer
15339 position. */
15340 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15341 last_unchanged_pos_old = last_unchanged_pos - *delta;
15342
15343 /* Search backward from ROW for a row displaying a line that
15344 starts at a minimum position >= last_unchanged_pos_old. */
15345 for (; row > first_text_row; --row)
15346 {
15347 /* This used to abort, but it can happen.
15348 It is ok to just stop the search instead here. KFS. */
15349 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15350 break;
15351
15352 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15353 row_found = row;
15354 }
15355 }
15356
15357 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15358
15359 return row_found;
15360 }
15361
15362
15363 /* Make sure that glyph rows in the current matrix of window W
15364 reference the same glyph memory as corresponding rows in the
15365 frame's frame matrix. This function is called after scrolling W's
15366 current matrix on a terminal frame in try_window_id and
15367 try_window_reusing_current_matrix. */
15368
15369 static void
15370 sync_frame_with_window_matrix_rows (w)
15371 struct window *w;
15372 {
15373 struct frame *f = XFRAME (w->frame);
15374 struct glyph_row *window_row, *window_row_end, *frame_row;
15375
15376 /* Preconditions: W must be a leaf window and full-width. Its frame
15377 must have a frame matrix. */
15378 xassert (NILP (w->hchild) && NILP (w->vchild));
15379 xassert (WINDOW_FULL_WIDTH_P (w));
15380 xassert (!FRAME_WINDOW_P (f));
15381
15382 /* If W is a full-width window, glyph pointers in W's current matrix
15383 have, by definition, to be the same as glyph pointers in the
15384 corresponding frame matrix. Note that frame matrices have no
15385 marginal areas (see build_frame_matrix). */
15386 window_row = w->current_matrix->rows;
15387 window_row_end = window_row + w->current_matrix->nrows;
15388 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15389 while (window_row < window_row_end)
15390 {
15391 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15392 struct glyph *end = window_row->glyphs[LAST_AREA];
15393
15394 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15395 frame_row->glyphs[TEXT_AREA] = start;
15396 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15397 frame_row->glyphs[LAST_AREA] = end;
15398
15399 /* Disable frame rows whose corresponding window rows have
15400 been disabled in try_window_id. */
15401 if (!window_row->enabled_p)
15402 frame_row->enabled_p = 0;
15403
15404 ++window_row, ++frame_row;
15405 }
15406 }
15407
15408
15409 /* Find the glyph row in window W containing CHARPOS. Consider all
15410 rows between START and END (not inclusive). END null means search
15411 all rows to the end of the display area of W. Value is the row
15412 containing CHARPOS or null. */
15413
15414 struct glyph_row *
15415 row_containing_pos (w, charpos, start, end, dy)
15416 struct window *w;
15417 int charpos;
15418 struct glyph_row *start, *end;
15419 int dy;
15420 {
15421 struct glyph_row *row = start;
15422 struct glyph_row *best_row = NULL;
15423 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15424 int last_y;
15425
15426 /* If we happen to start on a header-line, skip that. */
15427 if (row->mode_line_p)
15428 ++row;
15429
15430 if ((end && row >= end) || !row->enabled_p)
15431 return NULL;
15432
15433 last_y = window_text_bottom_y (w) - dy;
15434
15435 while (1)
15436 {
15437 /* Give up if we have gone too far. */
15438 if (end && row >= end)
15439 return NULL;
15440 /* This formerly returned if they were equal.
15441 I think that both quantities are of a "last plus one" type;
15442 if so, when they are equal, the row is within the screen. -- rms. */
15443 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15444 return NULL;
15445
15446 /* If it is in this row, return this row. */
15447 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15448 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15449 /* The end position of a row equals the start
15450 position of the next row. If CHARPOS is there, we
15451 would rather display it in the next line, except
15452 when this line ends in ZV. */
15453 && !row->ends_at_zv_p
15454 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15455 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15456 {
15457 struct glyph *g;
15458
15459 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering))
15460 return row;
15461 /* In bidi-reordered rows, there could be several rows
15462 occluding point. We need to find the one which fits
15463 CHARPOS the best. */
15464 for (g = row->glyphs[TEXT_AREA];
15465 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15466 g++)
15467 {
15468 if (!STRINGP (g->object))
15469 {
15470 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15471 {
15472 mindif = eabs (g->charpos - charpos);
15473 best_row = row;
15474 }
15475 }
15476 }
15477 }
15478 else if (best_row)
15479 return best_row;
15480 ++row;
15481 }
15482 }
15483
15484
15485 /* Try to redisplay window W by reusing its existing display. W's
15486 current matrix must be up to date when this function is called,
15487 i.e. window_end_valid must not be nil.
15488
15489 Value is
15490
15491 1 if display has been updated
15492 0 if otherwise unsuccessful
15493 -1 if redisplay with same window start is known not to succeed
15494
15495 The following steps are performed:
15496
15497 1. Find the last row in the current matrix of W that is not
15498 affected by changes at the start of current_buffer. If no such row
15499 is found, give up.
15500
15501 2. Find the first row in W's current matrix that is not affected by
15502 changes at the end of current_buffer. Maybe there is no such row.
15503
15504 3. Display lines beginning with the row + 1 found in step 1 to the
15505 row found in step 2 or, if step 2 didn't find a row, to the end of
15506 the window.
15507
15508 4. If cursor is not known to appear on the window, give up.
15509
15510 5. If display stopped at the row found in step 2, scroll the
15511 display and current matrix as needed.
15512
15513 6. Maybe display some lines at the end of W, if we must. This can
15514 happen under various circumstances, like a partially visible line
15515 becoming fully visible, or because newly displayed lines are displayed
15516 in smaller font sizes.
15517
15518 7. Update W's window end information. */
15519
15520 static int
15521 try_window_id (w)
15522 struct window *w;
15523 {
15524 struct frame *f = XFRAME (w->frame);
15525 struct glyph_matrix *current_matrix = w->current_matrix;
15526 struct glyph_matrix *desired_matrix = w->desired_matrix;
15527 struct glyph_row *last_unchanged_at_beg_row;
15528 struct glyph_row *first_unchanged_at_end_row;
15529 struct glyph_row *row;
15530 struct glyph_row *bottom_row;
15531 int bottom_vpos;
15532 struct it it;
15533 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
15534 struct text_pos start_pos;
15535 struct run run;
15536 int first_unchanged_at_end_vpos = 0;
15537 struct glyph_row *last_text_row, *last_text_row_at_end;
15538 struct text_pos start;
15539 int first_changed_charpos, last_changed_charpos;
15540
15541 #if GLYPH_DEBUG
15542 if (inhibit_try_window_id)
15543 return 0;
15544 #endif
15545
15546 /* This is handy for debugging. */
15547 #if 0
15548 #define GIVE_UP(X) \
15549 do { \
15550 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15551 return 0; \
15552 } while (0)
15553 #else
15554 #define GIVE_UP(X) return 0
15555 #endif
15556
15557 SET_TEXT_POS_FROM_MARKER (start, w->start);
15558
15559 /* Don't use this for mini-windows because these can show
15560 messages and mini-buffers, and we don't handle that here. */
15561 if (MINI_WINDOW_P (w))
15562 GIVE_UP (1);
15563
15564 /* This flag is used to prevent redisplay optimizations. */
15565 if (windows_or_buffers_changed || cursor_type_changed)
15566 GIVE_UP (2);
15567
15568 /* Verify that narrowing has not changed.
15569 Also verify that we were not told to prevent redisplay optimizations.
15570 It would be nice to further
15571 reduce the number of cases where this prevents try_window_id. */
15572 if (current_buffer->clip_changed
15573 || current_buffer->prevent_redisplay_optimizations_p)
15574 GIVE_UP (3);
15575
15576 /* Window must either use window-based redisplay or be full width. */
15577 if (!FRAME_WINDOW_P (f)
15578 && (!FRAME_LINE_INS_DEL_OK (f)
15579 || !WINDOW_FULL_WIDTH_P (w)))
15580 GIVE_UP (4);
15581
15582 /* Give up if point is known NOT to appear in W. */
15583 if (PT < CHARPOS (start))
15584 GIVE_UP (5);
15585
15586 /* Another way to prevent redisplay optimizations. */
15587 if (XFASTINT (w->last_modified) == 0)
15588 GIVE_UP (6);
15589
15590 /* Verify that window is not hscrolled. */
15591 if (XFASTINT (w->hscroll) != 0)
15592 GIVE_UP (7);
15593
15594 /* Verify that display wasn't paused. */
15595 if (NILP (w->window_end_valid))
15596 GIVE_UP (8);
15597
15598 /* Can't use this if highlighting a region because a cursor movement
15599 will do more than just set the cursor. */
15600 if (!NILP (Vtransient_mark_mode)
15601 && !NILP (current_buffer->mark_active))
15602 GIVE_UP (9);
15603
15604 /* Likewise if highlighting trailing whitespace. */
15605 if (!NILP (Vshow_trailing_whitespace))
15606 GIVE_UP (11);
15607
15608 /* Likewise if showing a region. */
15609 if (!NILP (w->region_showing))
15610 GIVE_UP (10);
15611
15612 /* Can't use this if overlay arrow position and/or string have
15613 changed. */
15614 if (overlay_arrows_changed_p ())
15615 GIVE_UP (12);
15616
15617 /* When word-wrap is on, adding a space to the first word of a
15618 wrapped line can change the wrap position, altering the line
15619 above it. It might be worthwhile to handle this more
15620 intelligently, but for now just redisplay from scratch. */
15621 if (!NILP (XBUFFER (w->buffer)->word_wrap))
15622 GIVE_UP (21);
15623
15624 /* Under bidi reordering, adding or deleting a character in the
15625 beginning of a paragraph, before the first strong directional
15626 character, can change the base direction of the paragraph (unless
15627 the buffer specifies a fixed paragraph direction), which will
15628 require to redisplay the whole paragraph. It might be worthwhile
15629 to find the paragraph limits and widen the range of redisplayed
15630 lines to that, but for now just give up this optimization and
15631 redisplay from scratch. */
15632 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15633 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
15634 GIVE_UP (22);
15635
15636 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15637 only if buffer has really changed. The reason is that the gap is
15638 initially at Z for freshly visited files. The code below would
15639 set end_unchanged to 0 in that case. */
15640 if (MODIFF > SAVE_MODIFF
15641 /* This seems to happen sometimes after saving a buffer. */
15642 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15643 {
15644 if (GPT - BEG < BEG_UNCHANGED)
15645 BEG_UNCHANGED = GPT - BEG;
15646 if (Z - GPT < END_UNCHANGED)
15647 END_UNCHANGED = Z - GPT;
15648 }
15649
15650 /* The position of the first and last character that has been changed. */
15651 first_changed_charpos = BEG + BEG_UNCHANGED;
15652 last_changed_charpos = Z - END_UNCHANGED;
15653
15654 /* If window starts after a line end, and the last change is in
15655 front of that newline, then changes don't affect the display.
15656 This case happens with stealth-fontification. Note that although
15657 the display is unchanged, glyph positions in the matrix have to
15658 be adjusted, of course. */
15659 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15660 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15661 && ((last_changed_charpos < CHARPOS (start)
15662 && CHARPOS (start) == BEGV)
15663 || (last_changed_charpos < CHARPOS (start) - 1
15664 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15665 {
15666 int Z_old, delta, Z_BYTE_old, delta_bytes;
15667 struct glyph_row *r0;
15668
15669 /* Compute how many chars/bytes have been added to or removed
15670 from the buffer. */
15671 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15672 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15673 delta = Z - Z_old;
15674 delta_bytes = Z_BYTE - Z_BYTE_old;
15675
15676 /* Give up if PT is not in the window. Note that it already has
15677 been checked at the start of try_window_id that PT is not in
15678 front of the window start. */
15679 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
15680 GIVE_UP (13);
15681
15682 /* If window start is unchanged, we can reuse the whole matrix
15683 as is, after adjusting glyph positions. No need to compute
15684 the window end again, since its offset from Z hasn't changed. */
15685 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15686 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
15687 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
15688 /* PT must not be in a partially visible line. */
15689 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
15690 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15691 {
15692 /* Adjust positions in the glyph matrix. */
15693 if (delta || delta_bytes)
15694 {
15695 struct glyph_row *r1
15696 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15697 increment_matrix_positions (w->current_matrix,
15698 MATRIX_ROW_VPOS (r0, current_matrix),
15699 MATRIX_ROW_VPOS (r1, current_matrix),
15700 delta, delta_bytes);
15701 }
15702
15703 /* Set the cursor. */
15704 row = row_containing_pos (w, PT, r0, NULL, 0);
15705 if (row)
15706 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15707 else
15708 abort ();
15709 return 1;
15710 }
15711 }
15712
15713 /* Handle the case that changes are all below what is displayed in
15714 the window, and that PT is in the window. This shortcut cannot
15715 be taken if ZV is visible in the window, and text has been added
15716 there that is visible in the window. */
15717 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15718 /* ZV is not visible in the window, or there are no
15719 changes at ZV, actually. */
15720 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15721 || first_changed_charpos == last_changed_charpos))
15722 {
15723 struct glyph_row *r0;
15724
15725 /* Give up if PT is not in the window. Note that it already has
15726 been checked at the start of try_window_id that PT is not in
15727 front of the window start. */
15728 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15729 GIVE_UP (14);
15730
15731 /* If window start is unchanged, we can reuse the whole matrix
15732 as is, without changing glyph positions since no text has
15733 been added/removed in front of the window end. */
15734 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15735 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
15736 /* PT must not be in a partially visible line. */
15737 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15738 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15739 {
15740 /* We have to compute the window end anew since text
15741 can have been added/removed after it. */
15742 w->window_end_pos
15743 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15744 w->window_end_bytepos
15745 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15746
15747 /* Set the cursor. */
15748 row = row_containing_pos (w, PT, r0, NULL, 0);
15749 if (row)
15750 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15751 else
15752 abort ();
15753 return 2;
15754 }
15755 }
15756
15757 /* Give up if window start is in the changed area.
15758
15759 The condition used to read
15760
15761 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15762
15763 but why that was tested escapes me at the moment. */
15764 if (CHARPOS (start) >= first_changed_charpos
15765 && CHARPOS (start) <= last_changed_charpos)
15766 GIVE_UP (15);
15767
15768 /* Check that window start agrees with the start of the first glyph
15769 row in its current matrix. Check this after we know the window
15770 start is not in changed text, otherwise positions would not be
15771 comparable. */
15772 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15773 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
15774 GIVE_UP (16);
15775
15776 /* Give up if the window ends in strings. Overlay strings
15777 at the end are difficult to handle, so don't try. */
15778 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15779 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15780 GIVE_UP (20);
15781
15782 /* Compute the position at which we have to start displaying new
15783 lines. Some of the lines at the top of the window might be
15784 reusable because they are not displaying changed text. Find the
15785 last row in W's current matrix not affected by changes at the
15786 start of current_buffer. Value is null if changes start in the
15787 first line of window. */
15788 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15789 if (last_unchanged_at_beg_row)
15790 {
15791 /* Avoid starting to display in the moddle of a character, a TAB
15792 for instance. This is easier than to set up the iterator
15793 exactly, and it's not a frequent case, so the additional
15794 effort wouldn't really pay off. */
15795 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15796 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15797 && last_unchanged_at_beg_row > w->current_matrix->rows)
15798 --last_unchanged_at_beg_row;
15799
15800 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15801 GIVE_UP (17);
15802
15803 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15804 GIVE_UP (18);
15805 start_pos = it.current.pos;
15806
15807 /* Start displaying new lines in the desired matrix at the same
15808 vpos we would use in the current matrix, i.e. below
15809 last_unchanged_at_beg_row. */
15810 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15811 current_matrix);
15812 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15813 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15814
15815 xassert (it.hpos == 0 && it.current_x == 0);
15816 }
15817 else
15818 {
15819 /* There are no reusable lines at the start of the window.
15820 Start displaying in the first text line. */
15821 start_display (&it, w, start);
15822 it.vpos = it.first_vpos;
15823 start_pos = it.current.pos;
15824 }
15825
15826 /* Find the first row that is not affected by changes at the end of
15827 the buffer. Value will be null if there is no unchanged row, in
15828 which case we must redisplay to the end of the window. delta
15829 will be set to the value by which buffer positions beginning with
15830 first_unchanged_at_end_row have to be adjusted due to text
15831 changes. */
15832 first_unchanged_at_end_row
15833 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15834 IF_DEBUG (debug_delta = delta);
15835 IF_DEBUG (debug_delta_bytes = delta_bytes);
15836
15837 /* Set stop_pos to the buffer position up to which we will have to
15838 display new lines. If first_unchanged_at_end_row != NULL, this
15839 is the buffer position of the start of the line displayed in that
15840 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15841 that we don't stop at a buffer position. */
15842 stop_pos = 0;
15843 if (first_unchanged_at_end_row)
15844 {
15845 xassert (last_unchanged_at_beg_row == NULL
15846 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15847
15848 /* If this is a continuation line, move forward to the next one
15849 that isn't. Changes in lines above affect this line.
15850 Caution: this may move first_unchanged_at_end_row to a row
15851 not displaying text. */
15852 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15853 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15854 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15855 < it.last_visible_y))
15856 ++first_unchanged_at_end_row;
15857
15858 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15859 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15860 >= it.last_visible_y))
15861 first_unchanged_at_end_row = NULL;
15862 else
15863 {
15864 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15865 + delta);
15866 first_unchanged_at_end_vpos
15867 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15868 xassert (stop_pos >= Z - END_UNCHANGED);
15869 }
15870 }
15871 else if (last_unchanged_at_beg_row == NULL)
15872 GIVE_UP (19);
15873
15874
15875 #if GLYPH_DEBUG
15876
15877 /* Either there is no unchanged row at the end, or the one we have
15878 now displays text. This is a necessary condition for the window
15879 end pos calculation at the end of this function. */
15880 xassert (first_unchanged_at_end_row == NULL
15881 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15882
15883 debug_last_unchanged_at_beg_vpos
15884 = (last_unchanged_at_beg_row
15885 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15886 : -1);
15887 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15888
15889 #endif /* GLYPH_DEBUG != 0 */
15890
15891
15892 /* Display new lines. Set last_text_row to the last new line
15893 displayed which has text on it, i.e. might end up as being the
15894 line where the window_end_vpos is. */
15895 w->cursor.vpos = -1;
15896 last_text_row = NULL;
15897 overlay_arrow_seen = 0;
15898 while (it.current_y < it.last_visible_y
15899 && !fonts_changed_p
15900 && (first_unchanged_at_end_row == NULL
15901 || IT_CHARPOS (it) < stop_pos))
15902 {
15903 if (display_line (&it))
15904 last_text_row = it.glyph_row - 1;
15905 }
15906
15907 if (fonts_changed_p)
15908 return -1;
15909
15910
15911 /* Compute differences in buffer positions, y-positions etc. for
15912 lines reused at the bottom of the window. Compute what we can
15913 scroll. */
15914 if (first_unchanged_at_end_row
15915 /* No lines reused because we displayed everything up to the
15916 bottom of the window. */
15917 && it.current_y < it.last_visible_y)
15918 {
15919 dvpos = (it.vpos
15920 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15921 current_matrix));
15922 dy = it.current_y - first_unchanged_at_end_row->y;
15923 run.current_y = first_unchanged_at_end_row->y;
15924 run.desired_y = run.current_y + dy;
15925 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15926 }
15927 else
15928 {
15929 delta = delta_bytes = dvpos = dy
15930 = run.current_y = run.desired_y = run.height = 0;
15931 first_unchanged_at_end_row = NULL;
15932 }
15933 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15934
15935
15936 /* Find the cursor if not already found. We have to decide whether
15937 PT will appear on this window (it sometimes doesn't, but this is
15938 not a very frequent case.) This decision has to be made before
15939 the current matrix is altered. A value of cursor.vpos < 0 means
15940 that PT is either in one of the lines beginning at
15941 first_unchanged_at_end_row or below the window. Don't care for
15942 lines that might be displayed later at the window end; as
15943 mentioned, this is not a frequent case. */
15944 if (w->cursor.vpos < 0)
15945 {
15946 /* Cursor in unchanged rows at the top? */
15947 if (PT < CHARPOS (start_pos)
15948 && last_unchanged_at_beg_row)
15949 {
15950 row = row_containing_pos (w, PT,
15951 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15952 last_unchanged_at_beg_row + 1, 0);
15953 if (row)
15954 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15955 }
15956
15957 /* Start from first_unchanged_at_end_row looking for PT. */
15958 else if (first_unchanged_at_end_row)
15959 {
15960 row = row_containing_pos (w, PT - delta,
15961 first_unchanged_at_end_row, NULL, 0);
15962 if (row)
15963 set_cursor_from_row (w, row, w->current_matrix, delta,
15964 delta_bytes, dy, dvpos);
15965 }
15966
15967 /* Give up if cursor was not found. */
15968 if (w->cursor.vpos < 0)
15969 {
15970 clear_glyph_matrix (w->desired_matrix);
15971 return -1;
15972 }
15973 }
15974
15975 /* Don't let the cursor end in the scroll margins. */
15976 {
15977 int this_scroll_margin, cursor_height;
15978
15979 this_scroll_margin = max (0, scroll_margin);
15980 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15981 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15982 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15983
15984 if ((w->cursor.y < this_scroll_margin
15985 && CHARPOS (start) > BEGV)
15986 /* Old redisplay didn't take scroll margin into account at the bottom,
15987 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15988 || (w->cursor.y + (make_cursor_line_fully_visible_p
15989 ? cursor_height + this_scroll_margin
15990 : 1)) > it.last_visible_y)
15991 {
15992 w->cursor.vpos = -1;
15993 clear_glyph_matrix (w->desired_matrix);
15994 return -1;
15995 }
15996 }
15997
15998 /* Scroll the display. Do it before changing the current matrix so
15999 that xterm.c doesn't get confused about where the cursor glyph is
16000 found. */
16001 if (dy && run.height)
16002 {
16003 update_begin (f);
16004
16005 if (FRAME_WINDOW_P (f))
16006 {
16007 FRAME_RIF (f)->update_window_begin_hook (w);
16008 FRAME_RIF (f)->clear_window_mouse_face (w);
16009 FRAME_RIF (f)->scroll_run_hook (w, &run);
16010 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16011 }
16012 else
16013 {
16014 /* Terminal frame. In this case, dvpos gives the number of
16015 lines to scroll by; dvpos < 0 means scroll up. */
16016 int first_unchanged_at_end_vpos
16017 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
16018 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
16019 int end = (WINDOW_TOP_EDGE_LINE (w)
16020 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
16021 + window_internal_height (w));
16022
16023 /* Perform the operation on the screen. */
16024 if (dvpos > 0)
16025 {
16026 /* Scroll last_unchanged_at_beg_row to the end of the
16027 window down dvpos lines. */
16028 set_terminal_window (f, end);
16029
16030 /* On dumb terminals delete dvpos lines at the end
16031 before inserting dvpos empty lines. */
16032 if (!FRAME_SCROLL_REGION_OK (f))
16033 ins_del_lines (f, end - dvpos, -dvpos);
16034
16035 /* Insert dvpos empty lines in front of
16036 last_unchanged_at_beg_row. */
16037 ins_del_lines (f, from, dvpos);
16038 }
16039 else if (dvpos < 0)
16040 {
16041 /* Scroll up last_unchanged_at_beg_vpos to the end of
16042 the window to last_unchanged_at_beg_vpos - |dvpos|. */
16043 set_terminal_window (f, end);
16044
16045 /* Delete dvpos lines in front of
16046 last_unchanged_at_beg_vpos. ins_del_lines will set
16047 the cursor to the given vpos and emit |dvpos| delete
16048 line sequences. */
16049 ins_del_lines (f, from + dvpos, dvpos);
16050
16051 /* On a dumb terminal insert dvpos empty lines at the
16052 end. */
16053 if (!FRAME_SCROLL_REGION_OK (f))
16054 ins_del_lines (f, end + dvpos, -dvpos);
16055 }
16056
16057 set_terminal_window (f, 0);
16058 }
16059
16060 update_end (f);
16061 }
16062
16063 /* Shift reused rows of the current matrix to the right position.
16064 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
16065 text. */
16066 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16067 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
16068 if (dvpos < 0)
16069 {
16070 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
16071 bottom_vpos, dvpos);
16072 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
16073 bottom_vpos, 0);
16074 }
16075 else if (dvpos > 0)
16076 {
16077 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
16078 bottom_vpos, dvpos);
16079 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
16080 first_unchanged_at_end_vpos + dvpos, 0);
16081 }
16082
16083 /* For frame-based redisplay, make sure that current frame and window
16084 matrix are in sync with respect to glyph memory. */
16085 if (!FRAME_WINDOW_P (f))
16086 sync_frame_with_window_matrix_rows (w);
16087
16088 /* Adjust buffer positions in reused rows. */
16089 if (delta || delta_bytes)
16090 increment_matrix_positions (current_matrix,
16091 first_unchanged_at_end_vpos + dvpos,
16092 bottom_vpos, delta, delta_bytes);
16093
16094 /* Adjust Y positions. */
16095 if (dy)
16096 shift_glyph_matrix (w, current_matrix,
16097 first_unchanged_at_end_vpos + dvpos,
16098 bottom_vpos, dy);
16099
16100 if (first_unchanged_at_end_row)
16101 {
16102 first_unchanged_at_end_row += dvpos;
16103 if (first_unchanged_at_end_row->y >= it.last_visible_y
16104 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
16105 first_unchanged_at_end_row = NULL;
16106 }
16107
16108 /* If scrolling up, there may be some lines to display at the end of
16109 the window. */
16110 last_text_row_at_end = NULL;
16111 if (dy < 0)
16112 {
16113 /* Scrolling up can leave for example a partially visible line
16114 at the end of the window to be redisplayed. */
16115 /* Set last_row to the glyph row in the current matrix where the
16116 window end line is found. It has been moved up or down in
16117 the matrix by dvpos. */
16118 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
16119 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
16120
16121 /* If last_row is the window end line, it should display text. */
16122 xassert (last_row->displays_text_p);
16123
16124 /* If window end line was partially visible before, begin
16125 displaying at that line. Otherwise begin displaying with the
16126 line following it. */
16127 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16128 {
16129 init_to_row_start (&it, w, last_row);
16130 it.vpos = last_vpos;
16131 it.current_y = last_row->y;
16132 }
16133 else
16134 {
16135 init_to_row_end (&it, w, last_row);
16136 it.vpos = 1 + last_vpos;
16137 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16138 ++last_row;
16139 }
16140
16141 /* We may start in a continuation line. If so, we have to
16142 get the right continuation_lines_width and current_x. */
16143 it.continuation_lines_width = last_row->continuation_lines_width;
16144 it.hpos = it.current_x = 0;
16145
16146 /* Display the rest of the lines at the window end. */
16147 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16148 while (it.current_y < it.last_visible_y
16149 && !fonts_changed_p)
16150 {
16151 /* Is it always sure that the display agrees with lines in
16152 the current matrix? I don't think so, so we mark rows
16153 displayed invalid in the current matrix by setting their
16154 enabled_p flag to zero. */
16155 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16156 if (display_line (&it))
16157 last_text_row_at_end = it.glyph_row - 1;
16158 }
16159 }
16160
16161 /* Update window_end_pos and window_end_vpos. */
16162 if (first_unchanged_at_end_row
16163 && !last_text_row_at_end)
16164 {
16165 /* Window end line if one of the preserved rows from the current
16166 matrix. Set row to the last row displaying text in current
16167 matrix starting at first_unchanged_at_end_row, after
16168 scrolling. */
16169 xassert (first_unchanged_at_end_row->displays_text_p);
16170 row = find_last_row_displaying_text (w->current_matrix, &it,
16171 first_unchanged_at_end_row);
16172 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16173
16174 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16175 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16176 w->window_end_vpos
16177 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16178 xassert (w->window_end_bytepos >= 0);
16179 IF_DEBUG (debug_method_add (w, "A"));
16180 }
16181 else if (last_text_row_at_end)
16182 {
16183 w->window_end_pos
16184 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16185 w->window_end_bytepos
16186 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16187 w->window_end_vpos
16188 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16189 xassert (w->window_end_bytepos >= 0);
16190 IF_DEBUG (debug_method_add (w, "B"));
16191 }
16192 else if (last_text_row)
16193 {
16194 /* We have displayed either to the end of the window or at the
16195 end of the window, i.e. the last row with text is to be found
16196 in the desired matrix. */
16197 w->window_end_pos
16198 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16199 w->window_end_bytepos
16200 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16201 w->window_end_vpos
16202 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16203 xassert (w->window_end_bytepos >= 0);
16204 }
16205 else if (first_unchanged_at_end_row == NULL
16206 && last_text_row == NULL
16207 && last_text_row_at_end == NULL)
16208 {
16209 /* Displayed to end of window, but no line containing text was
16210 displayed. Lines were deleted at the end of the window. */
16211 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16212 int vpos = XFASTINT (w->window_end_vpos);
16213 struct glyph_row *current_row = current_matrix->rows + vpos;
16214 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16215
16216 for (row = NULL;
16217 row == NULL && vpos >= first_vpos;
16218 --vpos, --current_row, --desired_row)
16219 {
16220 if (desired_row->enabled_p)
16221 {
16222 if (desired_row->displays_text_p)
16223 row = desired_row;
16224 }
16225 else if (current_row->displays_text_p)
16226 row = current_row;
16227 }
16228
16229 xassert (row != NULL);
16230 w->window_end_vpos = make_number (vpos + 1);
16231 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16232 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16233 xassert (w->window_end_bytepos >= 0);
16234 IF_DEBUG (debug_method_add (w, "C"));
16235 }
16236 else
16237 abort ();
16238
16239 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16240 debug_end_vpos = XFASTINT (w->window_end_vpos));
16241
16242 /* Record that display has not been completed. */
16243 w->window_end_valid = Qnil;
16244 w->desired_matrix->no_scrolling_p = 1;
16245 return 3;
16246
16247 #undef GIVE_UP
16248 }
16249
16250
16251 \f
16252 /***********************************************************************
16253 More debugging support
16254 ***********************************************************************/
16255
16256 #if GLYPH_DEBUG
16257
16258 void dump_glyph_row P_ ((struct glyph_row *, int, int));
16259 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
16260 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
16261
16262
16263 /* Dump the contents of glyph matrix MATRIX on stderr.
16264
16265 GLYPHS 0 means don't show glyph contents.
16266 GLYPHS 1 means show glyphs in short form
16267 GLYPHS > 1 means show glyphs in long form. */
16268
16269 void
16270 dump_glyph_matrix (matrix, glyphs)
16271 struct glyph_matrix *matrix;
16272 int glyphs;
16273 {
16274 int i;
16275 for (i = 0; i < matrix->nrows; ++i)
16276 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16277 }
16278
16279
16280 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16281 the glyph row and area where the glyph comes from. */
16282
16283 void
16284 dump_glyph (row, glyph, area)
16285 struct glyph_row *row;
16286 struct glyph *glyph;
16287 int area;
16288 {
16289 if (glyph->type == CHAR_GLYPH)
16290 {
16291 fprintf (stderr,
16292 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16293 glyph - row->glyphs[TEXT_AREA],
16294 'C',
16295 glyph->charpos,
16296 (BUFFERP (glyph->object)
16297 ? 'B'
16298 : (STRINGP (glyph->object)
16299 ? 'S'
16300 : '-')),
16301 glyph->pixel_width,
16302 glyph->u.ch,
16303 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16304 ? glyph->u.ch
16305 : '.'),
16306 glyph->face_id,
16307 glyph->left_box_line_p,
16308 glyph->right_box_line_p);
16309 }
16310 else if (glyph->type == STRETCH_GLYPH)
16311 {
16312 fprintf (stderr,
16313 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16314 glyph - row->glyphs[TEXT_AREA],
16315 'S',
16316 glyph->charpos,
16317 (BUFFERP (glyph->object)
16318 ? 'B'
16319 : (STRINGP (glyph->object)
16320 ? 'S'
16321 : '-')),
16322 glyph->pixel_width,
16323 0,
16324 '.',
16325 glyph->face_id,
16326 glyph->left_box_line_p,
16327 glyph->right_box_line_p);
16328 }
16329 else if (glyph->type == IMAGE_GLYPH)
16330 {
16331 fprintf (stderr,
16332 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16333 glyph - row->glyphs[TEXT_AREA],
16334 'I',
16335 glyph->charpos,
16336 (BUFFERP (glyph->object)
16337 ? 'B'
16338 : (STRINGP (glyph->object)
16339 ? 'S'
16340 : '-')),
16341 glyph->pixel_width,
16342 glyph->u.img_id,
16343 '.',
16344 glyph->face_id,
16345 glyph->left_box_line_p,
16346 glyph->right_box_line_p);
16347 }
16348 else if (glyph->type == COMPOSITE_GLYPH)
16349 {
16350 fprintf (stderr,
16351 " %5d %4c %6d %c %3d 0x%05x",
16352 glyph - row->glyphs[TEXT_AREA],
16353 '+',
16354 glyph->charpos,
16355 (BUFFERP (glyph->object)
16356 ? 'B'
16357 : (STRINGP (glyph->object)
16358 ? 'S'
16359 : '-')),
16360 glyph->pixel_width,
16361 glyph->u.cmp.id);
16362 if (glyph->u.cmp.automatic)
16363 fprintf (stderr,
16364 "[%d-%d]",
16365 glyph->u.cmp.from, glyph->u.cmp.to);
16366 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16367 glyph->face_id,
16368 glyph->left_box_line_p,
16369 glyph->right_box_line_p);
16370 }
16371 }
16372
16373
16374 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16375 GLYPHS 0 means don't show glyph contents.
16376 GLYPHS 1 means show glyphs in short form
16377 GLYPHS > 1 means show glyphs in long form. */
16378
16379 void
16380 dump_glyph_row (row, vpos, glyphs)
16381 struct glyph_row *row;
16382 int vpos, glyphs;
16383 {
16384 if (glyphs != 1)
16385 {
16386 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16387 fprintf (stderr, "======================================================================\n");
16388
16389 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16390 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16391 vpos,
16392 MATRIX_ROW_START_CHARPOS (row),
16393 MATRIX_ROW_END_CHARPOS (row),
16394 row->used[TEXT_AREA],
16395 row->contains_overlapping_glyphs_p,
16396 row->enabled_p,
16397 row->truncated_on_left_p,
16398 row->truncated_on_right_p,
16399 row->continued_p,
16400 MATRIX_ROW_CONTINUATION_LINE_P (row),
16401 row->displays_text_p,
16402 row->ends_at_zv_p,
16403 row->fill_line_p,
16404 row->ends_in_middle_of_char_p,
16405 row->starts_in_middle_of_char_p,
16406 row->mouse_face_p,
16407 row->x,
16408 row->y,
16409 row->pixel_width,
16410 row->height,
16411 row->visible_height,
16412 row->ascent,
16413 row->phys_ascent);
16414 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16415 row->end.overlay_string_index,
16416 row->continuation_lines_width);
16417 fprintf (stderr, "%9d %5d\n",
16418 CHARPOS (row->start.string_pos),
16419 CHARPOS (row->end.string_pos));
16420 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16421 row->end.dpvec_index);
16422 }
16423
16424 if (glyphs > 1)
16425 {
16426 int area;
16427
16428 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16429 {
16430 struct glyph *glyph = row->glyphs[area];
16431 struct glyph *glyph_end = glyph + row->used[area];
16432
16433 /* Glyph for a line end in text. */
16434 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16435 ++glyph_end;
16436
16437 if (glyph < glyph_end)
16438 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16439
16440 for (; glyph < glyph_end; ++glyph)
16441 dump_glyph (row, glyph, area);
16442 }
16443 }
16444 else if (glyphs == 1)
16445 {
16446 int area;
16447
16448 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16449 {
16450 char *s = (char *) alloca (row->used[area] + 1);
16451 int i;
16452
16453 for (i = 0; i < row->used[area]; ++i)
16454 {
16455 struct glyph *glyph = row->glyphs[area] + i;
16456 if (glyph->type == CHAR_GLYPH
16457 && glyph->u.ch < 0x80
16458 && glyph->u.ch >= ' ')
16459 s[i] = glyph->u.ch;
16460 else
16461 s[i] = '.';
16462 }
16463
16464 s[i] = '\0';
16465 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16466 }
16467 }
16468 }
16469
16470
16471 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16472 Sdump_glyph_matrix, 0, 1, "p",
16473 doc: /* Dump the current matrix of the selected window to stderr.
16474 Shows contents of glyph row structures. With non-nil
16475 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16476 glyphs in short form, otherwise show glyphs in long form. */)
16477 (glyphs)
16478 Lisp_Object glyphs;
16479 {
16480 struct window *w = XWINDOW (selected_window);
16481 struct buffer *buffer = XBUFFER (w->buffer);
16482
16483 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16484 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16485 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16486 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16487 fprintf (stderr, "=============================================\n");
16488 dump_glyph_matrix (w->current_matrix,
16489 NILP (glyphs) ? 0 : XINT (glyphs));
16490 return Qnil;
16491 }
16492
16493
16494 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16495 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16496 ()
16497 {
16498 struct frame *f = XFRAME (selected_frame);
16499 dump_glyph_matrix (f->current_matrix, 1);
16500 return Qnil;
16501 }
16502
16503
16504 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16505 doc: /* Dump glyph row ROW to stderr.
16506 GLYPH 0 means don't dump glyphs.
16507 GLYPH 1 means dump glyphs in short form.
16508 GLYPH > 1 or omitted means dump glyphs in long form. */)
16509 (row, glyphs)
16510 Lisp_Object row, glyphs;
16511 {
16512 struct glyph_matrix *matrix;
16513 int vpos;
16514
16515 CHECK_NUMBER (row);
16516 matrix = XWINDOW (selected_window)->current_matrix;
16517 vpos = XINT (row);
16518 if (vpos >= 0 && vpos < matrix->nrows)
16519 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16520 vpos,
16521 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16522 return Qnil;
16523 }
16524
16525
16526 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16527 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16528 GLYPH 0 means don't dump glyphs.
16529 GLYPH 1 means dump glyphs in short form.
16530 GLYPH > 1 or omitted means dump glyphs in long form. */)
16531 (row, glyphs)
16532 Lisp_Object row, glyphs;
16533 {
16534 struct frame *sf = SELECTED_FRAME ();
16535 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16536 int vpos;
16537
16538 CHECK_NUMBER (row);
16539 vpos = XINT (row);
16540 if (vpos >= 0 && vpos < m->nrows)
16541 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16542 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16543 return Qnil;
16544 }
16545
16546
16547 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16548 doc: /* Toggle tracing of redisplay.
16549 With ARG, turn tracing on if and only if ARG is positive. */)
16550 (arg)
16551 Lisp_Object arg;
16552 {
16553 if (NILP (arg))
16554 trace_redisplay_p = !trace_redisplay_p;
16555 else
16556 {
16557 arg = Fprefix_numeric_value (arg);
16558 trace_redisplay_p = XINT (arg) > 0;
16559 }
16560
16561 return Qnil;
16562 }
16563
16564
16565 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16566 doc: /* Like `format', but print result to stderr.
16567 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16568 (nargs, args)
16569 int nargs;
16570 Lisp_Object *args;
16571 {
16572 Lisp_Object s = Fformat (nargs, args);
16573 fprintf (stderr, "%s", SDATA (s));
16574 return Qnil;
16575 }
16576
16577 #endif /* GLYPH_DEBUG */
16578
16579
16580 \f
16581 /***********************************************************************
16582 Building Desired Matrix Rows
16583 ***********************************************************************/
16584
16585 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16586 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16587
16588 static struct glyph_row *
16589 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
16590 struct window *w;
16591 Lisp_Object overlay_arrow_string;
16592 {
16593 struct frame *f = XFRAME (WINDOW_FRAME (w));
16594 struct buffer *buffer = XBUFFER (w->buffer);
16595 struct buffer *old = current_buffer;
16596 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16597 int arrow_len = SCHARS (overlay_arrow_string);
16598 const unsigned char *arrow_end = arrow_string + arrow_len;
16599 const unsigned char *p;
16600 struct it it;
16601 int multibyte_p;
16602 int n_glyphs_before;
16603
16604 set_buffer_temp (buffer);
16605 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16606 it.glyph_row->used[TEXT_AREA] = 0;
16607 SET_TEXT_POS (it.position, 0, 0);
16608
16609 multibyte_p = !NILP (buffer->enable_multibyte_characters);
16610 p = arrow_string;
16611 while (p < arrow_end)
16612 {
16613 Lisp_Object face, ilisp;
16614
16615 /* Get the next character. */
16616 if (multibyte_p)
16617 it.c = string_char_and_length (p, &it.len);
16618 else
16619 it.c = *p, it.len = 1;
16620 p += it.len;
16621
16622 /* Get its face. */
16623 ilisp = make_number (p - arrow_string);
16624 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16625 it.face_id = compute_char_face (f, it.c, face);
16626
16627 /* Compute its width, get its glyphs. */
16628 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16629 SET_TEXT_POS (it.position, -1, -1);
16630 PRODUCE_GLYPHS (&it);
16631
16632 /* If this character doesn't fit any more in the line, we have
16633 to remove some glyphs. */
16634 if (it.current_x > it.last_visible_x)
16635 {
16636 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16637 break;
16638 }
16639 }
16640
16641 set_buffer_temp (old);
16642 return it.glyph_row;
16643 }
16644
16645
16646 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16647 glyphs are only inserted for terminal frames since we can't really
16648 win with truncation glyphs when partially visible glyphs are
16649 involved. Which glyphs to insert is determined by
16650 produce_special_glyphs. */
16651
16652 static void
16653 insert_left_trunc_glyphs (it)
16654 struct it *it;
16655 {
16656 struct it truncate_it;
16657 struct glyph *from, *end, *to, *toend;
16658
16659 xassert (!FRAME_WINDOW_P (it->f));
16660
16661 /* Get the truncation glyphs. */
16662 truncate_it = *it;
16663 truncate_it.current_x = 0;
16664 truncate_it.face_id = DEFAULT_FACE_ID;
16665 truncate_it.glyph_row = &scratch_glyph_row;
16666 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16667 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16668 truncate_it.object = make_number (0);
16669 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16670
16671 /* Overwrite glyphs from IT with truncation glyphs. */
16672 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16673 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16674 to = it->glyph_row->glyphs[TEXT_AREA];
16675 toend = to + it->glyph_row->used[TEXT_AREA];
16676
16677 while (from < end)
16678 *to++ = *from++;
16679
16680 /* There may be padding glyphs left over. Overwrite them too. */
16681 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16682 {
16683 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16684 while (from < end)
16685 *to++ = *from++;
16686 }
16687
16688 if (to > toend)
16689 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16690 }
16691
16692
16693 /* Compute the pixel height and width of IT->glyph_row.
16694
16695 Most of the time, ascent and height of a display line will be equal
16696 to the max_ascent and max_height values of the display iterator
16697 structure. This is not the case if
16698
16699 1. We hit ZV without displaying anything. In this case, max_ascent
16700 and max_height will be zero.
16701
16702 2. We have some glyphs that don't contribute to the line height.
16703 (The glyph row flag contributes_to_line_height_p is for future
16704 pixmap extensions).
16705
16706 The first case is easily covered by using default values because in
16707 these cases, the line height does not really matter, except that it
16708 must not be zero. */
16709
16710 static void
16711 compute_line_metrics (it)
16712 struct it *it;
16713 {
16714 struct glyph_row *row = it->glyph_row;
16715 int area, i;
16716
16717 if (FRAME_WINDOW_P (it->f))
16718 {
16719 int i, min_y, max_y;
16720
16721 /* The line may consist of one space only, that was added to
16722 place the cursor on it. If so, the row's height hasn't been
16723 computed yet. */
16724 if (row->height == 0)
16725 {
16726 if (it->max_ascent + it->max_descent == 0)
16727 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16728 row->ascent = it->max_ascent;
16729 row->height = it->max_ascent + it->max_descent;
16730 row->phys_ascent = it->max_phys_ascent;
16731 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16732 row->extra_line_spacing = it->max_extra_line_spacing;
16733 }
16734
16735 /* Compute the width of this line. */
16736 row->pixel_width = row->x;
16737 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16738 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16739
16740 xassert (row->pixel_width >= 0);
16741 xassert (row->ascent >= 0 && row->height > 0);
16742
16743 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16744 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16745
16746 /* If first line's physical ascent is larger than its logical
16747 ascent, use the physical ascent, and make the row taller.
16748 This makes accented characters fully visible. */
16749 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16750 && row->phys_ascent > row->ascent)
16751 {
16752 row->height += row->phys_ascent - row->ascent;
16753 row->ascent = row->phys_ascent;
16754 }
16755
16756 /* Compute how much of the line is visible. */
16757 row->visible_height = row->height;
16758
16759 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16760 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16761
16762 if (row->y < min_y)
16763 row->visible_height -= min_y - row->y;
16764 if (row->y + row->height > max_y)
16765 row->visible_height -= row->y + row->height - max_y;
16766 }
16767 else
16768 {
16769 row->pixel_width = row->used[TEXT_AREA];
16770 if (row->continued_p)
16771 row->pixel_width -= it->continuation_pixel_width;
16772 else if (row->truncated_on_right_p)
16773 row->pixel_width -= it->truncation_pixel_width;
16774 row->ascent = row->phys_ascent = 0;
16775 row->height = row->phys_height = row->visible_height = 1;
16776 row->extra_line_spacing = 0;
16777 }
16778
16779 /* Compute a hash code for this row. */
16780 row->hash = 0;
16781 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16782 for (i = 0; i < row->used[area]; ++i)
16783 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16784 + row->glyphs[area][i].u.val
16785 + row->glyphs[area][i].face_id
16786 + row->glyphs[area][i].padding_p
16787 + (row->glyphs[area][i].type << 2));
16788
16789 it->max_ascent = it->max_descent = 0;
16790 it->max_phys_ascent = it->max_phys_descent = 0;
16791 }
16792
16793
16794 /* Append one space to the glyph row of iterator IT if doing a
16795 window-based redisplay. The space has the same face as
16796 IT->face_id. Value is non-zero if a space was added.
16797
16798 This function is called to make sure that there is always one glyph
16799 at the end of a glyph row that the cursor can be set on under
16800 window-systems. (If there weren't such a glyph we would not know
16801 how wide and tall a box cursor should be displayed).
16802
16803 At the same time this space let's a nicely handle clearing to the
16804 end of the line if the row ends in italic text. */
16805
16806 static int
16807 append_space_for_newline (it, default_face_p)
16808 struct it *it;
16809 int default_face_p;
16810 {
16811 if (FRAME_WINDOW_P (it->f))
16812 {
16813 int n = it->glyph_row->used[TEXT_AREA];
16814
16815 if (it->glyph_row->glyphs[TEXT_AREA] + n
16816 < it->glyph_row->glyphs[1 + TEXT_AREA])
16817 {
16818 /* Save some values that must not be changed.
16819 Must save IT->c and IT->len because otherwise
16820 ITERATOR_AT_END_P wouldn't work anymore after
16821 append_space_for_newline has been called. */
16822 enum display_element_type saved_what = it->what;
16823 int saved_c = it->c, saved_len = it->len;
16824 int saved_x = it->current_x;
16825 int saved_face_id = it->face_id;
16826 struct text_pos saved_pos;
16827 Lisp_Object saved_object;
16828 struct face *face;
16829
16830 saved_object = it->object;
16831 saved_pos = it->position;
16832
16833 it->what = IT_CHARACTER;
16834 bzero (&it->position, sizeof it->position);
16835 it->object = make_number (0);
16836 it->c = ' ';
16837 it->len = 1;
16838
16839 if (default_face_p)
16840 it->face_id = DEFAULT_FACE_ID;
16841 else if (it->face_before_selective_p)
16842 it->face_id = it->saved_face_id;
16843 face = FACE_FROM_ID (it->f, it->face_id);
16844 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16845
16846 PRODUCE_GLYPHS (it);
16847
16848 it->override_ascent = -1;
16849 it->constrain_row_ascent_descent_p = 0;
16850 it->current_x = saved_x;
16851 it->object = saved_object;
16852 it->position = saved_pos;
16853 it->what = saved_what;
16854 it->face_id = saved_face_id;
16855 it->len = saved_len;
16856 it->c = saved_c;
16857 return 1;
16858 }
16859 }
16860
16861 return 0;
16862 }
16863
16864
16865 /* Extend the face of the last glyph in the text area of IT->glyph_row
16866 to the end of the display line. Called from display_line. If the
16867 glyph row is empty, add a space glyph to it so that we know the
16868 face to draw. Set the glyph row flag fill_line_p. If the glyph
16869 row is R2L, prepend a stretch glyph to cover the empty space to the
16870 left of the leftmost glyph. */
16871
16872 static void
16873 extend_face_to_end_of_line (it)
16874 struct it *it;
16875 {
16876 struct face *face;
16877 struct frame *f = it->f;
16878
16879 /* If line is already filled, do nothing. Non window-system frames
16880 get a grace of one more ``pixel'' because their characters are
16881 1-``pixel'' wide, so they hit the equality too early. */
16882 if (it->current_x >= it->last_visible_x + !FRAME_WINDOW_P (f))
16883 return;
16884
16885 /* Face extension extends the background and box of IT->face_id
16886 to the end of the line. If the background equals the background
16887 of the frame, we don't have to do anything. */
16888 if (it->face_before_selective_p)
16889 face = FACE_FROM_ID (f, it->saved_face_id);
16890 else
16891 face = FACE_FROM_ID (f, it->face_id);
16892
16893 if (FRAME_WINDOW_P (f)
16894 && it->glyph_row->displays_text_p
16895 && face->box == FACE_NO_BOX
16896 && face->background == FRAME_BACKGROUND_PIXEL (f)
16897 && !face->stipple
16898 && !it->glyph_row->reversed_p)
16899 return;
16900
16901 /* Set the glyph row flag indicating that the face of the last glyph
16902 in the text area has to be drawn to the end of the text area. */
16903 it->glyph_row->fill_line_p = 1;
16904
16905 /* If current character of IT is not ASCII, make sure we have the
16906 ASCII face. This will be automatically undone the next time
16907 get_next_display_element returns a multibyte character. Note
16908 that the character will always be single byte in unibyte
16909 text. */
16910 if (!ASCII_CHAR_P (it->c))
16911 {
16912 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16913 }
16914
16915 if (FRAME_WINDOW_P (f))
16916 {
16917 /* If the row is empty, add a space with the current face of IT,
16918 so that we know which face to draw. */
16919 if (it->glyph_row->used[TEXT_AREA] == 0)
16920 {
16921 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16922 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16923 it->glyph_row->used[TEXT_AREA] = 1;
16924 }
16925 #ifdef HAVE_WINDOW_SYSTEM
16926 if (it->glyph_row->reversed_p)
16927 {
16928 /* Prepend a stretch glyph to the row, such that the
16929 rightmost glyph will be drawn flushed all the way to the
16930 right margin of the window. The stretch glyph that will
16931 occupy the empty space, if any, to the left of the
16932 glyphs. */
16933 struct font *font = face->font ? face->font : FRAME_FONT (f);
16934 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16935 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16936 struct glyph *g;
16937 int row_width, stretch_ascent, stretch_width;
16938 struct text_pos saved_pos;
16939 int saved_face_id, saved_avoid_cursor;
16940
16941 for (row_width = 0, g = row_start; g < row_end; g++)
16942 row_width += g->pixel_width;
16943 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
16944 if (stretch_width > 0)
16945 {
16946 stretch_ascent =
16947 (((it->ascent + it->descent)
16948 * FONT_BASE (font)) / FONT_HEIGHT (font));
16949 saved_pos = it->position;
16950 bzero (&it->position, sizeof it->position);
16951 saved_avoid_cursor = it->avoid_cursor_p;
16952 it->avoid_cursor_p = 1;
16953 saved_face_id = it->face_id;
16954 /* The last row's stretch glyph should get the default
16955 face, to avoid painting the rest of the window with
16956 the region face, if the region ends at ZV. */
16957 if (it->glyph_row->ends_at_zv_p)
16958 it->face_id = DEFAULT_FACE_ID;
16959 else
16960 it->face_id = face->id;
16961 append_stretch_glyph (it, make_number (0), stretch_width,
16962 it->ascent + it->descent, stretch_ascent);
16963 it->position = saved_pos;
16964 it->avoid_cursor_p = saved_avoid_cursor;
16965 it->face_id = saved_face_id;
16966 }
16967 }
16968 #endif /* HAVE_WINDOW_SYSTEM */
16969 }
16970 else
16971 {
16972 /* Save some values that must not be changed. */
16973 int saved_x = it->current_x;
16974 struct text_pos saved_pos;
16975 Lisp_Object saved_object;
16976 enum display_element_type saved_what = it->what;
16977 int saved_face_id = it->face_id;
16978
16979 saved_object = it->object;
16980 saved_pos = it->position;
16981
16982 it->what = IT_CHARACTER;
16983 bzero (&it->position, sizeof it->position);
16984 it->object = make_number (0);
16985 it->c = ' ';
16986 it->len = 1;
16987 /* The last row's blank glyphs should get the default face, to
16988 avoid painting the rest of the window with the region face,
16989 if the region ends at ZV. */
16990 if (it->glyph_row->ends_at_zv_p)
16991 it->face_id = DEFAULT_FACE_ID;
16992 else
16993 it->face_id = face->id;
16994
16995 PRODUCE_GLYPHS (it);
16996
16997 while (it->current_x <= it->last_visible_x)
16998 PRODUCE_GLYPHS (it);
16999
17000 /* Don't count these blanks really. It would let us insert a left
17001 truncation glyph below and make us set the cursor on them, maybe. */
17002 it->current_x = saved_x;
17003 it->object = saved_object;
17004 it->position = saved_pos;
17005 it->what = saved_what;
17006 it->face_id = saved_face_id;
17007 }
17008 }
17009
17010
17011 /* Value is non-zero if text starting at CHARPOS in current_buffer is
17012 trailing whitespace. */
17013
17014 static int
17015 trailing_whitespace_p (charpos)
17016 int charpos;
17017 {
17018 int bytepos = CHAR_TO_BYTE (charpos);
17019 int c = 0;
17020
17021 while (bytepos < ZV_BYTE
17022 && (c = FETCH_CHAR (bytepos),
17023 c == ' ' || c == '\t'))
17024 ++bytepos;
17025
17026 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
17027 {
17028 if (bytepos != PT_BYTE)
17029 return 1;
17030 }
17031 return 0;
17032 }
17033
17034
17035 /* Highlight trailing whitespace, if any, in ROW. */
17036
17037 void
17038 highlight_trailing_whitespace (f, row)
17039 struct frame *f;
17040 struct glyph_row *row;
17041 {
17042 int used = row->used[TEXT_AREA];
17043
17044 if (used)
17045 {
17046 struct glyph *start = row->glyphs[TEXT_AREA];
17047 struct glyph *glyph = start + used - 1;
17048
17049 if (row->reversed_p)
17050 {
17051 /* Right-to-left rows need to be processed in the opposite
17052 direction, so swap the edge pointers. */
17053 glyph = start;
17054 start = row->glyphs[TEXT_AREA] + used - 1;
17055 }
17056
17057 /* Skip over glyphs inserted to display the cursor at the
17058 end of a line, for extending the face of the last glyph
17059 to the end of the line on terminals, and for truncation
17060 and continuation glyphs. */
17061 if (!row->reversed_p)
17062 {
17063 while (glyph >= start
17064 && glyph->type == CHAR_GLYPH
17065 && INTEGERP (glyph->object))
17066 --glyph;
17067 }
17068 else
17069 {
17070 while (glyph <= start
17071 && glyph->type == CHAR_GLYPH
17072 && INTEGERP (glyph->object))
17073 ++glyph;
17074 }
17075
17076 /* If last glyph is a space or stretch, and it's trailing
17077 whitespace, set the face of all trailing whitespace glyphs in
17078 IT->glyph_row to `trailing-whitespace'. */
17079 if ((row->reversed_p ? glyph <= start : glyph >= start)
17080 && BUFFERP (glyph->object)
17081 && (glyph->type == STRETCH_GLYPH
17082 || (glyph->type == CHAR_GLYPH
17083 && glyph->u.ch == ' '))
17084 && trailing_whitespace_p (glyph->charpos))
17085 {
17086 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
17087 if (face_id < 0)
17088 return;
17089
17090 if (!row->reversed_p)
17091 {
17092 while (glyph >= start
17093 && BUFFERP (glyph->object)
17094 && (glyph->type == STRETCH_GLYPH
17095 || (glyph->type == CHAR_GLYPH
17096 && glyph->u.ch == ' ')))
17097 (glyph--)->face_id = face_id;
17098 }
17099 else
17100 {
17101 while (glyph <= start
17102 && BUFFERP (glyph->object)
17103 && (glyph->type == STRETCH_GLYPH
17104 || (glyph->type == CHAR_GLYPH
17105 && glyph->u.ch == ' ')))
17106 (glyph++)->face_id = face_id;
17107 }
17108 }
17109 }
17110 }
17111
17112
17113 /* Value is non-zero if glyph row ROW in window W should be
17114 used to hold the cursor. */
17115
17116 static int
17117 cursor_row_p (w, row)
17118 struct window *w;
17119 struct glyph_row *row;
17120 {
17121 int cursor_row_p = 1;
17122
17123 if (PT == MATRIX_ROW_END_CHARPOS (row))
17124 {
17125 /* Suppose the row ends on a string.
17126 Unless the row is continued, that means it ends on a newline
17127 in the string. If it's anything other than a display string
17128 (e.g. a before-string from an overlay), we don't want the
17129 cursor there. (This heuristic seems to give the optimal
17130 behavior for the various types of multi-line strings.) */
17131 if (CHARPOS (row->end.string_pos) >= 0)
17132 {
17133 if (row->continued_p)
17134 cursor_row_p = 1;
17135 else
17136 {
17137 /* Check for `display' property. */
17138 struct glyph *beg = row->glyphs[TEXT_AREA];
17139 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17140 struct glyph *glyph;
17141
17142 cursor_row_p = 0;
17143 for (glyph = end; glyph >= beg; --glyph)
17144 if (STRINGP (glyph->object))
17145 {
17146 Lisp_Object prop
17147 = Fget_char_property (make_number (PT),
17148 Qdisplay, Qnil);
17149 cursor_row_p =
17150 (!NILP (prop)
17151 && display_prop_string_p (prop, glyph->object));
17152 break;
17153 }
17154 }
17155 }
17156 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17157 {
17158 /* If the row ends in middle of a real character,
17159 and the line is continued, we want the cursor here.
17160 That's because MATRIX_ROW_END_CHARPOS would equal
17161 PT if PT is before the character. */
17162 if (!row->ends_in_ellipsis_p)
17163 cursor_row_p = row->continued_p;
17164 else
17165 /* If the row ends in an ellipsis, then
17166 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
17167 We want that position to be displayed after the ellipsis. */
17168 cursor_row_p = 0;
17169 }
17170 /* If the row ends at ZV, display the cursor at the end of that
17171 row instead of at the start of the row below. */
17172 else if (row->ends_at_zv_p)
17173 cursor_row_p = 1;
17174 else
17175 cursor_row_p = 0;
17176 }
17177
17178 return cursor_row_p;
17179 }
17180
17181 \f
17182
17183 /* Push the display property PROP so that it will be rendered at the
17184 current position in IT. Return 1 if PROP was successfully pushed,
17185 0 otherwise. */
17186
17187 static int
17188 push_display_prop (struct it *it, Lisp_Object prop)
17189 {
17190 push_it (it);
17191
17192 if (STRINGP (prop))
17193 {
17194 if (SCHARS (prop) == 0)
17195 {
17196 pop_it (it);
17197 return 0;
17198 }
17199
17200 it->string = prop;
17201 it->multibyte_p = STRING_MULTIBYTE (it->string);
17202 it->current.overlay_string_index = -1;
17203 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17204 it->end_charpos = it->string_nchars = SCHARS (it->string);
17205 it->method = GET_FROM_STRING;
17206 it->stop_charpos = 0;
17207 }
17208 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17209 {
17210 it->method = GET_FROM_STRETCH;
17211 it->object = prop;
17212 }
17213 #ifdef HAVE_WINDOW_SYSTEM
17214 else if (IMAGEP (prop))
17215 {
17216 it->what = IT_IMAGE;
17217 it->image_id = lookup_image (it->f, prop);
17218 it->method = GET_FROM_IMAGE;
17219 }
17220 #endif /* HAVE_WINDOW_SYSTEM */
17221 else
17222 {
17223 pop_it (it); /* bogus display property, give up */
17224 return 0;
17225 }
17226
17227 return 1;
17228 }
17229
17230 /* Return the character-property PROP at the current position in IT. */
17231
17232 static Lisp_Object
17233 get_it_property (it, prop)
17234 struct it *it;
17235 Lisp_Object prop;
17236 {
17237 Lisp_Object position;
17238
17239 if (STRINGP (it->object))
17240 position = make_number (IT_STRING_CHARPOS (*it));
17241 else if (BUFFERP (it->object))
17242 position = make_number (IT_CHARPOS (*it));
17243 else
17244 return Qnil;
17245
17246 return Fget_char_property (position, prop, it->object);
17247 }
17248
17249 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17250
17251 static void
17252 handle_line_prefix (struct it *it)
17253 {
17254 Lisp_Object prefix;
17255 if (it->continuation_lines_width > 0)
17256 {
17257 prefix = get_it_property (it, Qwrap_prefix);
17258 if (NILP (prefix))
17259 prefix = Vwrap_prefix;
17260 }
17261 else
17262 {
17263 prefix = get_it_property (it, Qline_prefix);
17264 if (NILP (prefix))
17265 prefix = Vline_prefix;
17266 }
17267 if (! NILP (prefix) && push_display_prop (it, prefix))
17268 {
17269 /* If the prefix is wider than the window, and we try to wrap
17270 it, it would acquire its own wrap prefix, and so on till the
17271 iterator stack overflows. So, don't wrap the prefix. */
17272 it->line_wrap = TRUNCATE;
17273 it->avoid_cursor_p = 1;
17274 }
17275 }
17276
17277 \f
17278
17279 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17280 only for R2L lines from display_line, when it decides that too many
17281 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17282 continued. */
17283 static void
17284 unproduce_glyphs (it, n)
17285 struct it *it;
17286 int n;
17287 {
17288 struct glyph *glyph, *end;
17289
17290 xassert (it->glyph_row);
17291 xassert (it->glyph_row->reversed_p);
17292 xassert (it->area == TEXT_AREA);
17293 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17294
17295 if (n > it->glyph_row->used[TEXT_AREA])
17296 n = it->glyph_row->used[TEXT_AREA];
17297 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17298 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17299 for ( ; glyph < end; glyph++)
17300 glyph[-n] = *glyph;
17301 }
17302
17303
17304 /* Construct the glyph row IT->glyph_row in the desired matrix of
17305 IT->w from text at the current position of IT. See dispextern.h
17306 for an overview of struct it. Value is non-zero if
17307 IT->glyph_row displays text, as opposed to a line displaying ZV
17308 only. */
17309
17310 static int
17311 display_line (it)
17312 struct it *it;
17313 {
17314 struct glyph_row *row = it->glyph_row;
17315 Lisp_Object overlay_arrow_string;
17316 struct it wrap_it;
17317 int may_wrap = 0, wrap_x;
17318 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
17319 int wrap_row_phys_ascent, wrap_row_phys_height;
17320 int wrap_row_extra_line_spacing;
17321 struct display_pos row_end;
17322 int cvpos;
17323
17324 /* We always start displaying at hpos zero even if hscrolled. */
17325 xassert (it->hpos == 0 && it->current_x == 0);
17326
17327 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17328 >= it->w->desired_matrix->nrows)
17329 {
17330 it->w->nrows_scale_factor++;
17331 fonts_changed_p = 1;
17332 return 0;
17333 }
17334
17335 /* Is IT->w showing the region? */
17336 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17337
17338 /* Clear the result glyph row and enable it. */
17339 prepare_desired_row (row);
17340
17341 row->y = it->current_y;
17342 row->start = it->start;
17343 row->continuation_lines_width = it->continuation_lines_width;
17344 row->displays_text_p = 1;
17345 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17346 it->starts_in_middle_of_char_p = 0;
17347
17348 /* Arrange the overlays nicely for our purposes. Usually, we call
17349 display_line on only one line at a time, in which case this
17350 can't really hurt too much, or we call it on lines which appear
17351 one after another in the buffer, in which case all calls to
17352 recenter_overlay_lists but the first will be pretty cheap. */
17353 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17354
17355 /* Move over display elements that are not visible because we are
17356 hscrolled. This may stop at an x-position < IT->first_visible_x
17357 if the first glyph is partially visible or if we hit a line end. */
17358 if (it->current_x < it->first_visible_x)
17359 {
17360 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17361 MOVE_TO_POS | MOVE_TO_X);
17362 }
17363 else
17364 {
17365 /* We only do this when not calling `move_it_in_display_line_to'
17366 above, because move_it_in_display_line_to calls
17367 handle_line_prefix itself. */
17368 handle_line_prefix (it);
17369 }
17370
17371 /* Get the initial row height. This is either the height of the
17372 text hscrolled, if there is any, or zero. */
17373 row->ascent = it->max_ascent;
17374 row->height = it->max_ascent + it->max_descent;
17375 row->phys_ascent = it->max_phys_ascent;
17376 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17377 row->extra_line_spacing = it->max_extra_line_spacing;
17378
17379 /* Loop generating characters. The loop is left with IT on the next
17380 character to display. */
17381 while (1)
17382 {
17383 int n_glyphs_before, hpos_before, x_before;
17384 int x, i, nglyphs;
17385 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17386
17387 /* Retrieve the next thing to display. Value is zero if end of
17388 buffer reached. */
17389 if (!get_next_display_element (it))
17390 {
17391 /* Maybe add a space at the end of this line that is used to
17392 display the cursor there under X. Set the charpos of the
17393 first glyph of blank lines not corresponding to any text
17394 to -1. */
17395 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17396 row->exact_window_width_line_p = 1;
17397 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17398 || row->used[TEXT_AREA] == 0)
17399 {
17400 row->glyphs[TEXT_AREA]->charpos = -1;
17401 row->displays_text_p = 0;
17402
17403 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
17404 && (!MINI_WINDOW_P (it->w)
17405 || (minibuf_level && EQ (it->window, minibuf_window))))
17406 row->indicate_empty_line_p = 1;
17407 }
17408
17409 it->continuation_lines_width = 0;
17410 row->ends_at_zv_p = 1;
17411 /* A row that displays right-to-left text must always have
17412 its last face extended all the way to the end of line,
17413 even if this row ends in ZV. */
17414 if (row->reversed_p)
17415 extend_face_to_end_of_line (it);
17416 break;
17417 }
17418
17419 /* Now, get the metrics of what we want to display. This also
17420 generates glyphs in `row' (which is IT->glyph_row). */
17421 n_glyphs_before = row->used[TEXT_AREA];
17422 x = it->current_x;
17423
17424 /* Remember the line height so far in case the next element doesn't
17425 fit on the line. */
17426 if (it->line_wrap != TRUNCATE)
17427 {
17428 ascent = it->max_ascent;
17429 descent = it->max_descent;
17430 phys_ascent = it->max_phys_ascent;
17431 phys_descent = it->max_phys_descent;
17432
17433 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17434 {
17435 if (IT_DISPLAYING_WHITESPACE (it))
17436 may_wrap = 1;
17437 else if (may_wrap)
17438 {
17439 wrap_it = *it;
17440 wrap_x = x;
17441 wrap_row_used = row->used[TEXT_AREA];
17442 wrap_row_ascent = row->ascent;
17443 wrap_row_height = row->height;
17444 wrap_row_phys_ascent = row->phys_ascent;
17445 wrap_row_phys_height = row->phys_height;
17446 wrap_row_extra_line_spacing = row->extra_line_spacing;
17447 may_wrap = 0;
17448 }
17449 }
17450 }
17451
17452 PRODUCE_GLYPHS (it);
17453
17454 /* If this display element was in marginal areas, continue with
17455 the next one. */
17456 if (it->area != TEXT_AREA)
17457 {
17458 row->ascent = max (row->ascent, it->max_ascent);
17459 row->height = max (row->height, it->max_ascent + it->max_descent);
17460 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17461 row->phys_height = max (row->phys_height,
17462 it->max_phys_ascent + it->max_phys_descent);
17463 row->extra_line_spacing = max (row->extra_line_spacing,
17464 it->max_extra_line_spacing);
17465 set_iterator_to_next (it, 1);
17466 continue;
17467 }
17468
17469 /* Does the display element fit on the line? If we truncate
17470 lines, we should draw past the right edge of the window. If
17471 we don't truncate, we want to stop so that we can display the
17472 continuation glyph before the right margin. If lines are
17473 continued, there are two possible strategies for characters
17474 resulting in more than 1 glyph (e.g. tabs): Display as many
17475 glyphs as possible in this line and leave the rest for the
17476 continuation line, or display the whole element in the next
17477 line. Original redisplay did the former, so we do it also. */
17478 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17479 hpos_before = it->hpos;
17480 x_before = x;
17481
17482 if (/* Not a newline. */
17483 nglyphs > 0
17484 /* Glyphs produced fit entirely in the line. */
17485 && it->current_x < it->last_visible_x)
17486 {
17487 it->hpos += nglyphs;
17488 row->ascent = max (row->ascent, it->max_ascent);
17489 row->height = max (row->height, it->max_ascent + it->max_descent);
17490 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17491 row->phys_height = max (row->phys_height,
17492 it->max_phys_ascent + it->max_phys_descent);
17493 row->extra_line_spacing = max (row->extra_line_spacing,
17494 it->max_extra_line_spacing);
17495 if (it->current_x - it->pixel_width < it->first_visible_x)
17496 row->x = x - it->first_visible_x;
17497 }
17498 else
17499 {
17500 int new_x;
17501 struct glyph *glyph;
17502
17503 for (i = 0; i < nglyphs; ++i, x = new_x)
17504 {
17505 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17506 new_x = x + glyph->pixel_width;
17507
17508 if (/* Lines are continued. */
17509 it->line_wrap != TRUNCATE
17510 && (/* Glyph doesn't fit on the line. */
17511 new_x > it->last_visible_x
17512 /* Or it fits exactly on a window system frame. */
17513 || (new_x == it->last_visible_x
17514 && FRAME_WINDOW_P (it->f))))
17515 {
17516 /* End of a continued line. */
17517
17518 if (it->hpos == 0
17519 || (new_x == it->last_visible_x
17520 && FRAME_WINDOW_P (it->f)))
17521 {
17522 /* Current glyph is the only one on the line or
17523 fits exactly on the line. We must continue
17524 the line because we can't draw the cursor
17525 after the glyph. */
17526 row->continued_p = 1;
17527 it->current_x = new_x;
17528 it->continuation_lines_width += new_x;
17529 ++it->hpos;
17530 if (i == nglyphs - 1)
17531 {
17532 /* If line-wrap is on, check if a previous
17533 wrap point was found. */
17534 if (wrap_row_used > 0
17535 /* Even if there is a previous wrap
17536 point, continue the line here as
17537 usual, if (i) the previous character
17538 was a space or tab AND (ii) the
17539 current character is not. */
17540 && (!may_wrap
17541 || IT_DISPLAYING_WHITESPACE (it)))
17542 goto back_to_wrap;
17543
17544 set_iterator_to_next (it, 1);
17545 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17546 {
17547 if (!get_next_display_element (it))
17548 {
17549 row->exact_window_width_line_p = 1;
17550 it->continuation_lines_width = 0;
17551 row->continued_p = 0;
17552 row->ends_at_zv_p = 1;
17553 }
17554 else if (ITERATOR_AT_END_OF_LINE_P (it))
17555 {
17556 row->continued_p = 0;
17557 row->exact_window_width_line_p = 1;
17558 }
17559 }
17560 }
17561 }
17562 else if (CHAR_GLYPH_PADDING_P (*glyph)
17563 && !FRAME_WINDOW_P (it->f))
17564 {
17565 /* A padding glyph that doesn't fit on this line.
17566 This means the whole character doesn't fit
17567 on the line. */
17568 if (row->reversed_p)
17569 unproduce_glyphs (it, row->used[TEXT_AREA]
17570 - n_glyphs_before);
17571 row->used[TEXT_AREA] = n_glyphs_before;
17572
17573 /* Fill the rest of the row with continuation
17574 glyphs like in 20.x. */
17575 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17576 < row->glyphs[1 + TEXT_AREA])
17577 produce_special_glyphs (it, IT_CONTINUATION);
17578
17579 row->continued_p = 1;
17580 it->current_x = x_before;
17581 it->continuation_lines_width += x_before;
17582
17583 /* Restore the height to what it was before the
17584 element not fitting on the line. */
17585 it->max_ascent = ascent;
17586 it->max_descent = descent;
17587 it->max_phys_ascent = phys_ascent;
17588 it->max_phys_descent = phys_descent;
17589 }
17590 else if (wrap_row_used > 0)
17591 {
17592 back_to_wrap:
17593 if (row->reversed_p)
17594 unproduce_glyphs (it,
17595 row->used[TEXT_AREA] - wrap_row_used);
17596 *it = wrap_it;
17597 it->continuation_lines_width += wrap_x;
17598 row->used[TEXT_AREA] = wrap_row_used;
17599 row->ascent = wrap_row_ascent;
17600 row->height = wrap_row_height;
17601 row->phys_ascent = wrap_row_phys_ascent;
17602 row->phys_height = wrap_row_phys_height;
17603 row->extra_line_spacing = wrap_row_extra_line_spacing;
17604 row->continued_p = 1;
17605 row->ends_at_zv_p = 0;
17606 row->exact_window_width_line_p = 0;
17607 it->continuation_lines_width += x;
17608
17609 /* Make sure that a non-default face is extended
17610 up to the right margin of the window. */
17611 extend_face_to_end_of_line (it);
17612 }
17613 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17614 {
17615 /* A TAB that extends past the right edge of the
17616 window. This produces a single glyph on
17617 window system frames. We leave the glyph in
17618 this row and let it fill the row, but don't
17619 consume the TAB. */
17620 it->continuation_lines_width += it->last_visible_x;
17621 row->ends_in_middle_of_char_p = 1;
17622 row->continued_p = 1;
17623 glyph->pixel_width = it->last_visible_x - x;
17624 it->starts_in_middle_of_char_p = 1;
17625 }
17626 else
17627 {
17628 /* Something other than a TAB that draws past
17629 the right edge of the window. Restore
17630 positions to values before the element. */
17631 if (row->reversed_p)
17632 unproduce_glyphs (it, row->used[TEXT_AREA]
17633 - (n_glyphs_before + i));
17634 row->used[TEXT_AREA] = n_glyphs_before + i;
17635
17636 /* Display continuation glyphs. */
17637 if (!FRAME_WINDOW_P (it->f))
17638 produce_special_glyphs (it, IT_CONTINUATION);
17639 row->continued_p = 1;
17640
17641 it->current_x = x_before;
17642 it->continuation_lines_width += x;
17643 extend_face_to_end_of_line (it);
17644
17645 if (nglyphs > 1 && i > 0)
17646 {
17647 row->ends_in_middle_of_char_p = 1;
17648 it->starts_in_middle_of_char_p = 1;
17649 }
17650
17651 /* Restore the height to what it was before the
17652 element not fitting on the line. */
17653 it->max_ascent = ascent;
17654 it->max_descent = descent;
17655 it->max_phys_ascent = phys_ascent;
17656 it->max_phys_descent = phys_descent;
17657 }
17658
17659 break;
17660 }
17661 else if (new_x > it->first_visible_x)
17662 {
17663 /* Increment number of glyphs actually displayed. */
17664 ++it->hpos;
17665
17666 if (x < it->first_visible_x)
17667 /* Glyph is partially visible, i.e. row starts at
17668 negative X position. */
17669 row->x = x - it->first_visible_x;
17670 }
17671 else
17672 {
17673 /* Glyph is completely off the left margin of the
17674 window. This should not happen because of the
17675 move_it_in_display_line at the start of this
17676 function, unless the text display area of the
17677 window is empty. */
17678 xassert (it->first_visible_x <= it->last_visible_x);
17679 }
17680 }
17681
17682 row->ascent = max (row->ascent, it->max_ascent);
17683 row->height = max (row->height, it->max_ascent + it->max_descent);
17684 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17685 row->phys_height = max (row->phys_height,
17686 it->max_phys_ascent + it->max_phys_descent);
17687 row->extra_line_spacing = max (row->extra_line_spacing,
17688 it->max_extra_line_spacing);
17689
17690 /* End of this display line if row is continued. */
17691 if (row->continued_p || row->ends_at_zv_p)
17692 break;
17693 }
17694
17695 at_end_of_line:
17696 /* Is this a line end? If yes, we're also done, after making
17697 sure that a non-default face is extended up to the right
17698 margin of the window. */
17699 if (ITERATOR_AT_END_OF_LINE_P (it))
17700 {
17701 int used_before = row->used[TEXT_AREA];
17702
17703 row->ends_in_newline_from_string_p = STRINGP (it->object);
17704
17705 /* Add a space at the end of the line that is used to
17706 display the cursor there. */
17707 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17708 append_space_for_newline (it, 0);
17709
17710 /* Extend the face to the end of the line. */
17711 extend_face_to_end_of_line (it);
17712
17713 /* Make sure we have the position. */
17714 if (used_before == 0)
17715 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17716
17717 /* Consume the line end. This skips over invisible lines. */
17718 set_iterator_to_next (it, 1);
17719 it->continuation_lines_width = 0;
17720 break;
17721 }
17722
17723 /* Proceed with next display element. Note that this skips
17724 over lines invisible because of selective display. */
17725 set_iterator_to_next (it, 1);
17726
17727 /* If we truncate lines, we are done when the last displayed
17728 glyphs reach past the right margin of the window. */
17729 if (it->line_wrap == TRUNCATE
17730 && (FRAME_WINDOW_P (it->f)
17731 ? (it->current_x >= it->last_visible_x)
17732 : (it->current_x > it->last_visible_x)))
17733 {
17734 /* Maybe add truncation glyphs. */
17735 if (!FRAME_WINDOW_P (it->f))
17736 {
17737 int i, n;
17738
17739 if (!row->reversed_p)
17740 {
17741 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17742 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17743 break;
17744 }
17745 else
17746 {
17747 for (i = 0; i < row->used[TEXT_AREA]; i++)
17748 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17749 break;
17750 /* Remove padding glyphs at the front of ROW, to
17751 make room for the truncation glyphs we will be
17752 adding below. */
17753 unproduce_glyphs (it, i);
17754 }
17755
17756 for (n = row->used[TEXT_AREA]; i < n; ++i)
17757 {
17758 row->used[TEXT_AREA] = i;
17759 produce_special_glyphs (it, IT_TRUNCATION);
17760 }
17761 }
17762 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17763 {
17764 /* Don't truncate if we can overflow newline into fringe. */
17765 if (!get_next_display_element (it))
17766 {
17767 it->continuation_lines_width = 0;
17768 row->ends_at_zv_p = 1;
17769 row->exact_window_width_line_p = 1;
17770 break;
17771 }
17772 if (ITERATOR_AT_END_OF_LINE_P (it))
17773 {
17774 row->exact_window_width_line_p = 1;
17775 goto at_end_of_line;
17776 }
17777 }
17778
17779 row->truncated_on_right_p = 1;
17780 it->continuation_lines_width = 0;
17781 reseat_at_next_visible_line_start (it, 0);
17782 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17783 it->hpos = hpos_before;
17784 it->current_x = x_before;
17785 break;
17786 }
17787 }
17788
17789 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17790 at the left window margin. */
17791 if (it->first_visible_x
17792 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
17793 {
17794 if (!FRAME_WINDOW_P (it->f))
17795 insert_left_trunc_glyphs (it);
17796 row->truncated_on_left_p = 1;
17797 }
17798
17799 /* If the start of this line is the overlay arrow-position, then
17800 mark this glyph row as the one containing the overlay arrow.
17801 This is clearly a mess with variable size fonts. It would be
17802 better to let it be displayed like cursors under X. */
17803 if ((row->displays_text_p || !overlay_arrow_seen)
17804 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
17805 !NILP (overlay_arrow_string)))
17806 {
17807 /* Overlay arrow in window redisplay is a fringe bitmap. */
17808 if (STRINGP (overlay_arrow_string))
17809 {
17810 struct glyph_row *arrow_row
17811 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
17812 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
17813 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
17814 struct glyph *p = row->glyphs[TEXT_AREA];
17815 struct glyph *p2, *end;
17816
17817 /* Copy the arrow glyphs. */
17818 while (glyph < arrow_end)
17819 *p++ = *glyph++;
17820
17821 /* Throw away padding glyphs. */
17822 p2 = p;
17823 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17824 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
17825 ++p2;
17826 if (p2 > p)
17827 {
17828 while (p2 < end)
17829 *p++ = *p2++;
17830 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
17831 }
17832 }
17833 else
17834 {
17835 xassert (INTEGERP (overlay_arrow_string));
17836 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
17837 }
17838 overlay_arrow_seen = 1;
17839 }
17840
17841 /* Compute pixel dimensions of this line. */
17842 compute_line_metrics (it);
17843
17844 /* Remember the position at which this line ends. */
17845 row->end = row_end = it->current;
17846 if (it->bidi_p)
17847 {
17848 /* ROW->start and ROW->end must be the smallest and largest
17849 buffer positions in ROW. But if ROW was bidi-reordered,
17850 these two positions can be anywhere in the row, so we must
17851 rescan all of the ROW's glyphs to find them. */
17852 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17853 lines' rows is implemented for bidi-reordered rows. */
17854 EMACS_INT min_pos = ZV + 1, max_pos = 0;
17855 struct glyph *g;
17856 struct it save_it;
17857 struct text_pos tpos;
17858
17859 for (g = row->glyphs[TEXT_AREA];
17860 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17861 g++)
17862 {
17863 if (BUFFERP (g->object))
17864 {
17865 if (g->charpos > 0 && g->charpos < min_pos)
17866 min_pos = g->charpos;
17867 if (g->charpos > max_pos)
17868 max_pos = g->charpos;
17869 }
17870 }
17871 /* Empty lines have a valid buffer position at their first
17872 glyph, but that glyph's OBJECT is zero, as if it didn't come
17873 from a buffer. If we didn't find any valid buffer positions
17874 in this row, maybe we have such an empty line. */
17875 if (min_pos == ZV + 1 && row->used[TEXT_AREA])
17876 {
17877 for (g = row->glyphs[TEXT_AREA];
17878 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17879 g++)
17880 {
17881 if (INTEGERP (g->object))
17882 {
17883 if (g->charpos > 0 && g->charpos < min_pos)
17884 min_pos = g->charpos;
17885 if (g->charpos > max_pos)
17886 max_pos = g->charpos;
17887 }
17888 }
17889 }
17890 if (min_pos <= ZV)
17891 {
17892 if (min_pos != row->start.pos.charpos)
17893 {
17894 row->start.pos.charpos = min_pos;
17895 row->start.pos.bytepos = CHAR_TO_BYTE (min_pos);
17896 }
17897 if (max_pos == 0)
17898 max_pos = min_pos;
17899 }
17900 /* For ROW->end, we need the position that is _after_ max_pos,
17901 in the logical order, unless we are at ZV. */
17902 if (row->ends_at_zv_p)
17903 {
17904 row_end = row->end = it->current;
17905 if (!row->used[TEXT_AREA])
17906 {
17907 row->start.pos.charpos = row_end.pos.charpos;
17908 row->start.pos.bytepos = row_end.pos.bytepos;
17909 }
17910 }
17911 else if (row->used[TEXT_AREA] && max_pos)
17912 {
17913 SET_TEXT_POS (tpos, max_pos + 1, CHAR_TO_BYTE (max_pos + 1));
17914 row_end = it->current;
17915 row_end.pos = tpos;
17916 /* If the character at max_pos+1 is a newline, skip that as
17917 well. Note that this may skip some invisible text. */
17918 if (FETCH_CHAR (tpos.bytepos) == '\n'
17919 || (FETCH_CHAR (tpos.bytepos) == '\r' && it->selective))
17920 {
17921 save_it = *it;
17922 it->bidi_p = 0;
17923 reseat_1 (it, tpos, 0);
17924 set_iterator_to_next (it, 1);
17925 /* Record the position after the newline of a continued
17926 row. We will need that to set ROW->end of the last
17927 row produced for a continued line. */
17928 if (row->continued_p)
17929 {
17930 save_it.eol_pos.charpos = IT_CHARPOS (*it);
17931 save_it.eol_pos.bytepos = IT_BYTEPOS (*it);
17932 }
17933 else
17934 {
17935 row_end = it->current;
17936 save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0;
17937 }
17938 *it = save_it;
17939 }
17940 else if (!row->continued_p
17941 && MATRIX_ROW_CONTINUATION_LINE_P (row)
17942 && it->eol_pos.charpos > 0)
17943 {
17944 /* Last row of a continued line. Use the position
17945 recorded in ROW->eol_pos, to the effect that the
17946 newline belongs to this row, not to the row which
17947 displays the character with the largest buffer
17948 position. */
17949 row_end.pos = it->eol_pos;
17950 it->eol_pos.charpos = it->eol_pos.bytepos = 0;
17951 }
17952 row->end = row_end;
17953 }
17954 }
17955
17956 /* Record whether this row ends inside an ellipsis. */
17957 row->ends_in_ellipsis_p
17958 = (it->method == GET_FROM_DISPLAY_VECTOR
17959 && it->ellipsis_p);
17960
17961 /* Save fringe bitmaps in this row. */
17962 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
17963 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
17964 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
17965 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
17966
17967 it->left_user_fringe_bitmap = 0;
17968 it->left_user_fringe_face_id = 0;
17969 it->right_user_fringe_bitmap = 0;
17970 it->right_user_fringe_face_id = 0;
17971
17972 /* Maybe set the cursor. */
17973 cvpos = it->w->cursor.vpos;
17974 if ((cvpos < 0
17975 /* In bidi-reordered rows, keep checking for proper cursor
17976 position even if one has been found already, because buffer
17977 positions in such rows change non-linearly with ROW->VPOS,
17978 when a line is continued. One exception: when we are at ZV,
17979 display cursor on the first suitable glyph row, since all
17980 the empty rows after that also have their position set to ZV. */
17981 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17982 lines' rows is implemented for bidi-reordered rows. */
17983 || (it->bidi_p
17984 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
17985 && PT >= MATRIX_ROW_START_CHARPOS (row)
17986 && PT <= MATRIX_ROW_END_CHARPOS (row)
17987 && cursor_row_p (it->w, row))
17988 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
17989
17990 /* Highlight trailing whitespace. */
17991 if (!NILP (Vshow_trailing_whitespace))
17992 highlight_trailing_whitespace (it->f, it->glyph_row);
17993
17994 /* Prepare for the next line. This line starts horizontally at (X
17995 HPOS) = (0 0). Vertical positions are incremented. As a
17996 convenience for the caller, IT->glyph_row is set to the next
17997 row to be used. */
17998 it->current_x = it->hpos = 0;
17999 it->current_y += row->height;
18000 ++it->vpos;
18001 ++it->glyph_row;
18002 /* The next row should by default use the same value of the
18003 reversed_p flag as this one. set_iterator_to_next decides when
18004 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
18005 the flag accordingly. */
18006 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
18007 it->glyph_row->reversed_p = row->reversed_p;
18008 it->start = row_end;
18009 return row->displays_text_p;
18010 }
18011
18012
18013 \f
18014 /***********************************************************************
18015 Menu Bar
18016 ***********************************************************************/
18017
18018 /* Redisplay the menu bar in the frame for window W.
18019
18020 The menu bar of X frames that don't have X toolkit support is
18021 displayed in a special window W->frame->menu_bar_window.
18022
18023 The menu bar of terminal frames is treated specially as far as
18024 glyph matrices are concerned. Menu bar lines are not part of
18025 windows, so the update is done directly on the frame matrix rows
18026 for the menu bar. */
18027
18028 static void
18029 display_menu_bar (w)
18030 struct window *w;
18031 {
18032 struct frame *f = XFRAME (WINDOW_FRAME (w));
18033 struct it it;
18034 Lisp_Object items;
18035 int i;
18036
18037 /* Don't do all this for graphical frames. */
18038 #ifdef HAVE_NTGUI
18039 if (FRAME_W32_P (f))
18040 return;
18041 #endif
18042 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18043 if (FRAME_X_P (f))
18044 return;
18045 #endif
18046
18047 #ifdef HAVE_NS
18048 if (FRAME_NS_P (f))
18049 return;
18050 #endif /* HAVE_NS */
18051
18052 #ifdef USE_X_TOOLKIT
18053 xassert (!FRAME_WINDOW_P (f));
18054 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18055 it.first_visible_x = 0;
18056 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18057 #else /* not USE_X_TOOLKIT */
18058 if (FRAME_WINDOW_P (f))
18059 {
18060 /* Menu bar lines are displayed in the desired matrix of the
18061 dummy window menu_bar_window. */
18062 struct window *menu_w;
18063 xassert (WINDOWP (f->menu_bar_window));
18064 menu_w = XWINDOW (f->menu_bar_window);
18065 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18066 MENU_FACE_ID);
18067 it.first_visible_x = 0;
18068 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18069 }
18070 else
18071 {
18072 /* This is a TTY frame, i.e. character hpos/vpos are used as
18073 pixel x/y. */
18074 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18075 MENU_FACE_ID);
18076 it.first_visible_x = 0;
18077 it.last_visible_x = FRAME_COLS (f);
18078 }
18079 #endif /* not USE_X_TOOLKIT */
18080
18081 if (! mode_line_inverse_video)
18082 /* Force the menu-bar to be displayed in the default face. */
18083 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18084
18085 /* Clear all rows of the menu bar. */
18086 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18087 {
18088 struct glyph_row *row = it.glyph_row + i;
18089 clear_glyph_row (row);
18090 row->enabled_p = 1;
18091 row->full_width_p = 1;
18092 }
18093
18094 /* Display all items of the menu bar. */
18095 items = FRAME_MENU_BAR_ITEMS (it.f);
18096 for (i = 0; i < XVECTOR (items)->size; i += 4)
18097 {
18098 Lisp_Object string;
18099
18100 /* Stop at nil string. */
18101 string = AREF (items, i + 1);
18102 if (NILP (string))
18103 break;
18104
18105 /* Remember where item was displayed. */
18106 ASET (items, i + 3, make_number (it.hpos));
18107
18108 /* Display the item, pad with one space. */
18109 if (it.current_x < it.last_visible_x)
18110 display_string (NULL, string, Qnil, 0, 0, &it,
18111 SCHARS (string) + 1, 0, 0, -1);
18112 }
18113
18114 /* Fill out the line with spaces. */
18115 if (it.current_x < it.last_visible_x)
18116 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18117
18118 /* Compute the total height of the lines. */
18119 compute_line_metrics (&it);
18120 }
18121
18122
18123 \f
18124 /***********************************************************************
18125 Mode Line
18126 ***********************************************************************/
18127
18128 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18129 FORCE is non-zero, redisplay mode lines unconditionally.
18130 Otherwise, redisplay only mode lines that are garbaged. Value is
18131 the number of windows whose mode lines were redisplayed. */
18132
18133 static int
18134 redisplay_mode_lines (window, force)
18135 Lisp_Object window;
18136 int force;
18137 {
18138 int nwindows = 0;
18139
18140 while (!NILP (window))
18141 {
18142 struct window *w = XWINDOW (window);
18143
18144 if (WINDOWP (w->hchild))
18145 nwindows += redisplay_mode_lines (w->hchild, force);
18146 else if (WINDOWP (w->vchild))
18147 nwindows += redisplay_mode_lines (w->vchild, force);
18148 else if (force
18149 || FRAME_GARBAGED_P (XFRAME (w->frame))
18150 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18151 {
18152 struct text_pos lpoint;
18153 struct buffer *old = current_buffer;
18154
18155 /* Set the window's buffer for the mode line display. */
18156 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18157 set_buffer_internal_1 (XBUFFER (w->buffer));
18158
18159 /* Point refers normally to the selected window. For any
18160 other window, set up appropriate value. */
18161 if (!EQ (window, selected_window))
18162 {
18163 struct text_pos pt;
18164
18165 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18166 if (CHARPOS (pt) < BEGV)
18167 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18168 else if (CHARPOS (pt) > (ZV - 1))
18169 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18170 else
18171 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18172 }
18173
18174 /* Display mode lines. */
18175 clear_glyph_matrix (w->desired_matrix);
18176 if (display_mode_lines (w))
18177 {
18178 ++nwindows;
18179 w->must_be_updated_p = 1;
18180 }
18181
18182 /* Restore old settings. */
18183 set_buffer_internal_1 (old);
18184 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18185 }
18186
18187 window = w->next;
18188 }
18189
18190 return nwindows;
18191 }
18192
18193
18194 /* Display the mode and/or header line of window W. Value is the
18195 sum number of mode lines and header lines displayed. */
18196
18197 static int
18198 display_mode_lines (w)
18199 struct window *w;
18200 {
18201 Lisp_Object old_selected_window, old_selected_frame;
18202 int n = 0;
18203
18204 old_selected_frame = selected_frame;
18205 selected_frame = w->frame;
18206 old_selected_window = selected_window;
18207 XSETWINDOW (selected_window, w);
18208
18209 /* These will be set while the mode line specs are processed. */
18210 line_number_displayed = 0;
18211 w->column_number_displayed = Qnil;
18212
18213 if (WINDOW_WANTS_MODELINE_P (w))
18214 {
18215 struct window *sel_w = XWINDOW (old_selected_window);
18216
18217 /* Select mode line face based on the real selected window. */
18218 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18219 current_buffer->mode_line_format);
18220 ++n;
18221 }
18222
18223 if (WINDOW_WANTS_HEADER_LINE_P (w))
18224 {
18225 display_mode_line (w, HEADER_LINE_FACE_ID,
18226 current_buffer->header_line_format);
18227 ++n;
18228 }
18229
18230 selected_frame = old_selected_frame;
18231 selected_window = old_selected_window;
18232 return n;
18233 }
18234
18235
18236 /* Display mode or header line of window W. FACE_ID specifies which
18237 line to display; it is either MODE_LINE_FACE_ID or
18238 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18239 display. Value is the pixel height of the mode/header line
18240 displayed. */
18241
18242 static int
18243 display_mode_line (w, face_id, format)
18244 struct window *w;
18245 enum face_id face_id;
18246 Lisp_Object format;
18247 {
18248 struct it it;
18249 struct face *face;
18250 int count = SPECPDL_INDEX ();
18251
18252 init_iterator (&it, w, -1, -1, NULL, face_id);
18253 /* Don't extend on a previously drawn mode-line.
18254 This may happen if called from pos_visible_p. */
18255 it.glyph_row->enabled_p = 0;
18256 prepare_desired_row (it.glyph_row);
18257
18258 it.glyph_row->mode_line_p = 1;
18259
18260 if (! mode_line_inverse_video)
18261 /* Force the mode-line to be displayed in the default face. */
18262 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18263
18264 record_unwind_protect (unwind_format_mode_line,
18265 format_mode_line_unwind_data (NULL, Qnil, 0));
18266
18267 mode_line_target = MODE_LINE_DISPLAY;
18268
18269 /* Temporarily make frame's keyboard the current kboard so that
18270 kboard-local variables in the mode_line_format will get the right
18271 values. */
18272 push_kboard (FRAME_KBOARD (it.f));
18273 record_unwind_save_match_data ();
18274 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18275 pop_kboard ();
18276
18277 unbind_to (count, Qnil);
18278
18279 /* Fill up with spaces. */
18280 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18281
18282 compute_line_metrics (&it);
18283 it.glyph_row->full_width_p = 1;
18284 it.glyph_row->continued_p = 0;
18285 it.glyph_row->truncated_on_left_p = 0;
18286 it.glyph_row->truncated_on_right_p = 0;
18287
18288 /* Make a 3D mode-line have a shadow at its right end. */
18289 face = FACE_FROM_ID (it.f, face_id);
18290 extend_face_to_end_of_line (&it);
18291 if (face->box != FACE_NO_BOX)
18292 {
18293 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18294 + it.glyph_row->used[TEXT_AREA] - 1);
18295 last->right_box_line_p = 1;
18296 }
18297
18298 return it.glyph_row->height;
18299 }
18300
18301 /* Move element ELT in LIST to the front of LIST.
18302 Return the updated list. */
18303
18304 static Lisp_Object
18305 move_elt_to_front (elt, list)
18306 Lisp_Object elt, list;
18307 {
18308 register Lisp_Object tail, prev;
18309 register Lisp_Object tem;
18310
18311 tail = list;
18312 prev = Qnil;
18313 while (CONSP (tail))
18314 {
18315 tem = XCAR (tail);
18316
18317 if (EQ (elt, tem))
18318 {
18319 /* Splice out the link TAIL. */
18320 if (NILP (prev))
18321 list = XCDR (tail);
18322 else
18323 Fsetcdr (prev, XCDR (tail));
18324
18325 /* Now make it the first. */
18326 Fsetcdr (tail, list);
18327 return tail;
18328 }
18329 else
18330 prev = tail;
18331 tail = XCDR (tail);
18332 QUIT;
18333 }
18334
18335 /* Not found--return unchanged LIST. */
18336 return list;
18337 }
18338
18339 /* Contribute ELT to the mode line for window IT->w. How it
18340 translates into text depends on its data type.
18341
18342 IT describes the display environment in which we display, as usual.
18343
18344 DEPTH is the depth in recursion. It is used to prevent
18345 infinite recursion here.
18346
18347 FIELD_WIDTH is the number of characters the display of ELT should
18348 occupy in the mode line, and PRECISION is the maximum number of
18349 characters to display from ELT's representation. See
18350 display_string for details.
18351
18352 Returns the hpos of the end of the text generated by ELT.
18353
18354 PROPS is a property list to add to any string we encounter.
18355
18356 If RISKY is nonzero, remove (disregard) any properties in any string
18357 we encounter, and ignore :eval and :propertize.
18358
18359 The global variable `mode_line_target' determines whether the
18360 output is passed to `store_mode_line_noprop',
18361 `store_mode_line_string', or `display_string'. */
18362
18363 static int
18364 display_mode_element (it, depth, field_width, precision, elt, props, risky)
18365 struct it *it;
18366 int depth;
18367 int field_width, precision;
18368 Lisp_Object elt, props;
18369 int risky;
18370 {
18371 int n = 0, field, prec;
18372 int literal = 0;
18373
18374 tail_recurse:
18375 if (depth > 100)
18376 elt = build_string ("*too-deep*");
18377
18378 depth++;
18379
18380 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18381 {
18382 case Lisp_String:
18383 {
18384 /* A string: output it and check for %-constructs within it. */
18385 unsigned char c;
18386 int offset = 0;
18387
18388 if (SCHARS (elt) > 0
18389 && (!NILP (props) || risky))
18390 {
18391 Lisp_Object oprops, aelt;
18392 oprops = Ftext_properties_at (make_number (0), elt);
18393
18394 /* If the starting string's properties are not what
18395 we want, translate the string. Also, if the string
18396 is risky, do that anyway. */
18397
18398 if (NILP (Fequal (props, oprops)) || risky)
18399 {
18400 /* If the starting string has properties,
18401 merge the specified ones onto the existing ones. */
18402 if (! NILP (oprops) && !risky)
18403 {
18404 Lisp_Object tem;
18405
18406 oprops = Fcopy_sequence (oprops);
18407 tem = props;
18408 while (CONSP (tem))
18409 {
18410 oprops = Fplist_put (oprops, XCAR (tem),
18411 XCAR (XCDR (tem)));
18412 tem = XCDR (XCDR (tem));
18413 }
18414 props = oprops;
18415 }
18416
18417 aelt = Fassoc (elt, mode_line_proptrans_alist);
18418 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18419 {
18420 /* AELT is what we want. Move it to the front
18421 without consing. */
18422 elt = XCAR (aelt);
18423 mode_line_proptrans_alist
18424 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18425 }
18426 else
18427 {
18428 Lisp_Object tem;
18429
18430 /* If AELT has the wrong props, it is useless.
18431 so get rid of it. */
18432 if (! NILP (aelt))
18433 mode_line_proptrans_alist
18434 = Fdelq (aelt, mode_line_proptrans_alist);
18435
18436 elt = Fcopy_sequence (elt);
18437 Fset_text_properties (make_number (0), Flength (elt),
18438 props, elt);
18439 /* Add this item to mode_line_proptrans_alist. */
18440 mode_line_proptrans_alist
18441 = Fcons (Fcons (elt, props),
18442 mode_line_proptrans_alist);
18443 /* Truncate mode_line_proptrans_alist
18444 to at most 50 elements. */
18445 tem = Fnthcdr (make_number (50),
18446 mode_line_proptrans_alist);
18447 if (! NILP (tem))
18448 XSETCDR (tem, Qnil);
18449 }
18450 }
18451 }
18452
18453 offset = 0;
18454
18455 if (literal)
18456 {
18457 prec = precision - n;
18458 switch (mode_line_target)
18459 {
18460 case MODE_LINE_NOPROP:
18461 case MODE_LINE_TITLE:
18462 n += store_mode_line_noprop (SDATA (elt), -1, prec);
18463 break;
18464 case MODE_LINE_STRING:
18465 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18466 break;
18467 case MODE_LINE_DISPLAY:
18468 n += display_string (NULL, elt, Qnil, 0, 0, it,
18469 0, prec, 0, STRING_MULTIBYTE (elt));
18470 break;
18471 }
18472
18473 break;
18474 }
18475
18476 /* Handle the non-literal case. */
18477
18478 while ((precision <= 0 || n < precision)
18479 && SREF (elt, offset) != 0
18480 && (mode_line_target != MODE_LINE_DISPLAY
18481 || it->current_x < it->last_visible_x))
18482 {
18483 int last_offset = offset;
18484
18485 /* Advance to end of string or next format specifier. */
18486 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18487 ;
18488
18489 if (offset - 1 != last_offset)
18490 {
18491 int nchars, nbytes;
18492
18493 /* Output to end of string or up to '%'. Field width
18494 is length of string. Don't output more than
18495 PRECISION allows us. */
18496 offset--;
18497
18498 prec = c_string_width (SDATA (elt) + last_offset,
18499 offset - last_offset, precision - n,
18500 &nchars, &nbytes);
18501
18502 switch (mode_line_target)
18503 {
18504 case MODE_LINE_NOPROP:
18505 case MODE_LINE_TITLE:
18506 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
18507 break;
18508 case MODE_LINE_STRING:
18509 {
18510 int bytepos = last_offset;
18511 int charpos = string_byte_to_char (elt, bytepos);
18512 int endpos = (precision <= 0
18513 ? string_byte_to_char (elt, offset)
18514 : charpos + nchars);
18515
18516 n += store_mode_line_string (NULL,
18517 Fsubstring (elt, make_number (charpos),
18518 make_number (endpos)),
18519 0, 0, 0, Qnil);
18520 }
18521 break;
18522 case MODE_LINE_DISPLAY:
18523 {
18524 int bytepos = last_offset;
18525 int charpos = string_byte_to_char (elt, bytepos);
18526
18527 if (precision <= 0)
18528 nchars = string_byte_to_char (elt, offset) - charpos;
18529 n += display_string (NULL, elt, Qnil, 0, charpos,
18530 it, 0, nchars, 0,
18531 STRING_MULTIBYTE (elt));
18532 }
18533 break;
18534 }
18535 }
18536 else /* c == '%' */
18537 {
18538 int percent_position = offset;
18539
18540 /* Get the specified minimum width. Zero means
18541 don't pad. */
18542 field = 0;
18543 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18544 field = field * 10 + c - '0';
18545
18546 /* Don't pad beyond the total padding allowed. */
18547 if (field_width - n > 0 && field > field_width - n)
18548 field = field_width - n;
18549
18550 /* Note that either PRECISION <= 0 or N < PRECISION. */
18551 prec = precision - n;
18552
18553 if (c == 'M')
18554 n += display_mode_element (it, depth, field, prec,
18555 Vglobal_mode_string, props,
18556 risky);
18557 else if (c != 0)
18558 {
18559 int multibyte;
18560 int bytepos, charpos;
18561 unsigned char *spec;
18562 Lisp_Object string;
18563
18564 bytepos = percent_position;
18565 charpos = (STRING_MULTIBYTE (elt)
18566 ? string_byte_to_char (elt, bytepos)
18567 : bytepos);
18568 spec = decode_mode_spec (it->w, c, field, prec, &string);
18569 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18570
18571 switch (mode_line_target)
18572 {
18573 case MODE_LINE_NOPROP:
18574 case MODE_LINE_TITLE:
18575 n += store_mode_line_noprop (spec, field, prec);
18576 break;
18577 case MODE_LINE_STRING:
18578 {
18579 int len = strlen (spec);
18580 Lisp_Object tem = make_string (spec, len);
18581 props = Ftext_properties_at (make_number (charpos), elt);
18582 /* Should only keep face property in props */
18583 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18584 }
18585 break;
18586 case MODE_LINE_DISPLAY:
18587 {
18588 int nglyphs_before, nwritten;
18589
18590 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18591 nwritten = display_string (spec, string, elt,
18592 charpos, 0, it,
18593 field, prec, 0,
18594 multibyte);
18595
18596 /* Assign to the glyphs written above the
18597 string where the `%x' came from, position
18598 of the `%'. */
18599 if (nwritten > 0)
18600 {
18601 struct glyph *glyph
18602 = (it->glyph_row->glyphs[TEXT_AREA]
18603 + nglyphs_before);
18604 int i;
18605
18606 for (i = 0; i < nwritten; ++i)
18607 {
18608 glyph[i].object = elt;
18609 glyph[i].charpos = charpos;
18610 }
18611
18612 n += nwritten;
18613 }
18614 }
18615 break;
18616 }
18617 }
18618 else /* c == 0 */
18619 break;
18620 }
18621 }
18622 }
18623 break;
18624
18625 case Lisp_Symbol:
18626 /* A symbol: process the value of the symbol recursively
18627 as if it appeared here directly. Avoid error if symbol void.
18628 Special case: if value of symbol is a string, output the string
18629 literally. */
18630 {
18631 register Lisp_Object tem;
18632
18633 /* If the variable is not marked as risky to set
18634 then its contents are risky to use. */
18635 if (NILP (Fget (elt, Qrisky_local_variable)))
18636 risky = 1;
18637
18638 tem = Fboundp (elt);
18639 if (!NILP (tem))
18640 {
18641 tem = Fsymbol_value (elt);
18642 /* If value is a string, output that string literally:
18643 don't check for % within it. */
18644 if (STRINGP (tem))
18645 literal = 1;
18646
18647 if (!EQ (tem, elt))
18648 {
18649 /* Give up right away for nil or t. */
18650 elt = tem;
18651 goto tail_recurse;
18652 }
18653 }
18654 }
18655 break;
18656
18657 case Lisp_Cons:
18658 {
18659 register Lisp_Object car, tem;
18660
18661 /* A cons cell: five distinct cases.
18662 If first element is :eval or :propertize, do something special.
18663 If first element is a string or a cons, process all the elements
18664 and effectively concatenate them.
18665 If first element is a negative number, truncate displaying cdr to
18666 at most that many characters. If positive, pad (with spaces)
18667 to at least that many characters.
18668 If first element is a symbol, process the cadr or caddr recursively
18669 according to whether the symbol's value is non-nil or nil. */
18670 car = XCAR (elt);
18671 if (EQ (car, QCeval))
18672 {
18673 /* An element of the form (:eval FORM) means evaluate FORM
18674 and use the result as mode line elements. */
18675
18676 if (risky)
18677 break;
18678
18679 if (CONSP (XCDR (elt)))
18680 {
18681 Lisp_Object spec;
18682 spec = safe_eval (XCAR (XCDR (elt)));
18683 n += display_mode_element (it, depth, field_width - n,
18684 precision - n, spec, props,
18685 risky);
18686 }
18687 }
18688 else if (EQ (car, QCpropertize))
18689 {
18690 /* An element of the form (:propertize ELT PROPS...)
18691 means display ELT but applying properties PROPS. */
18692
18693 if (risky)
18694 break;
18695
18696 if (CONSP (XCDR (elt)))
18697 n += display_mode_element (it, depth, field_width - n,
18698 precision - n, XCAR (XCDR (elt)),
18699 XCDR (XCDR (elt)), risky);
18700 }
18701 else if (SYMBOLP (car))
18702 {
18703 tem = Fboundp (car);
18704 elt = XCDR (elt);
18705 if (!CONSP (elt))
18706 goto invalid;
18707 /* elt is now the cdr, and we know it is a cons cell.
18708 Use its car if CAR has a non-nil value. */
18709 if (!NILP (tem))
18710 {
18711 tem = Fsymbol_value (car);
18712 if (!NILP (tem))
18713 {
18714 elt = XCAR (elt);
18715 goto tail_recurse;
18716 }
18717 }
18718 /* Symbol's value is nil (or symbol is unbound)
18719 Get the cddr of the original list
18720 and if possible find the caddr and use that. */
18721 elt = XCDR (elt);
18722 if (NILP (elt))
18723 break;
18724 else if (!CONSP (elt))
18725 goto invalid;
18726 elt = XCAR (elt);
18727 goto tail_recurse;
18728 }
18729 else if (INTEGERP (car))
18730 {
18731 register int lim = XINT (car);
18732 elt = XCDR (elt);
18733 if (lim < 0)
18734 {
18735 /* Negative int means reduce maximum width. */
18736 if (precision <= 0)
18737 precision = -lim;
18738 else
18739 precision = min (precision, -lim);
18740 }
18741 else if (lim > 0)
18742 {
18743 /* Padding specified. Don't let it be more than
18744 current maximum. */
18745 if (precision > 0)
18746 lim = min (precision, lim);
18747
18748 /* If that's more padding than already wanted, queue it.
18749 But don't reduce padding already specified even if
18750 that is beyond the current truncation point. */
18751 field_width = max (lim, field_width);
18752 }
18753 goto tail_recurse;
18754 }
18755 else if (STRINGP (car) || CONSP (car))
18756 {
18757 Lisp_Object halftail = elt;
18758 int len = 0;
18759
18760 while (CONSP (elt)
18761 && (precision <= 0 || n < precision))
18762 {
18763 n += display_mode_element (it, depth,
18764 /* Do padding only after the last
18765 element in the list. */
18766 (! CONSP (XCDR (elt))
18767 ? field_width - n
18768 : 0),
18769 precision - n, XCAR (elt),
18770 props, risky);
18771 elt = XCDR (elt);
18772 len++;
18773 if ((len & 1) == 0)
18774 halftail = XCDR (halftail);
18775 /* Check for cycle. */
18776 if (EQ (halftail, elt))
18777 break;
18778 }
18779 }
18780 }
18781 break;
18782
18783 default:
18784 invalid:
18785 elt = build_string ("*invalid*");
18786 goto tail_recurse;
18787 }
18788
18789 /* Pad to FIELD_WIDTH. */
18790 if (field_width > 0 && n < field_width)
18791 {
18792 switch (mode_line_target)
18793 {
18794 case MODE_LINE_NOPROP:
18795 case MODE_LINE_TITLE:
18796 n += store_mode_line_noprop ("", field_width - n, 0);
18797 break;
18798 case MODE_LINE_STRING:
18799 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18800 break;
18801 case MODE_LINE_DISPLAY:
18802 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18803 0, 0, 0);
18804 break;
18805 }
18806 }
18807
18808 return n;
18809 }
18810
18811 /* Store a mode-line string element in mode_line_string_list.
18812
18813 If STRING is non-null, display that C string. Otherwise, the Lisp
18814 string LISP_STRING is displayed.
18815
18816 FIELD_WIDTH is the minimum number of output glyphs to produce.
18817 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18818 with spaces. FIELD_WIDTH <= 0 means don't pad.
18819
18820 PRECISION is the maximum number of characters to output from
18821 STRING. PRECISION <= 0 means don't truncate the string.
18822
18823 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18824 properties to the string.
18825
18826 PROPS are the properties to add to the string.
18827 The mode_line_string_face face property is always added to the string.
18828 */
18829
18830 static int
18831 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
18832 char *string;
18833 Lisp_Object lisp_string;
18834 int copy_string;
18835 int field_width;
18836 int precision;
18837 Lisp_Object props;
18838 {
18839 int len;
18840 int n = 0;
18841
18842 if (string != NULL)
18843 {
18844 len = strlen (string);
18845 if (precision > 0 && len > precision)
18846 len = precision;
18847 lisp_string = make_string (string, len);
18848 if (NILP (props))
18849 props = mode_line_string_face_prop;
18850 else if (!NILP (mode_line_string_face))
18851 {
18852 Lisp_Object face = Fplist_get (props, Qface);
18853 props = Fcopy_sequence (props);
18854 if (NILP (face))
18855 face = mode_line_string_face;
18856 else
18857 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18858 props = Fplist_put (props, Qface, face);
18859 }
18860 Fadd_text_properties (make_number (0), make_number (len),
18861 props, lisp_string);
18862 }
18863 else
18864 {
18865 len = XFASTINT (Flength (lisp_string));
18866 if (precision > 0 && len > precision)
18867 {
18868 len = precision;
18869 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
18870 precision = -1;
18871 }
18872 if (!NILP (mode_line_string_face))
18873 {
18874 Lisp_Object face;
18875 if (NILP (props))
18876 props = Ftext_properties_at (make_number (0), lisp_string);
18877 face = Fplist_get (props, Qface);
18878 if (NILP (face))
18879 face = mode_line_string_face;
18880 else
18881 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18882 props = Fcons (Qface, Fcons (face, Qnil));
18883 if (copy_string)
18884 lisp_string = Fcopy_sequence (lisp_string);
18885 }
18886 if (!NILP (props))
18887 Fadd_text_properties (make_number (0), make_number (len),
18888 props, lisp_string);
18889 }
18890
18891 if (len > 0)
18892 {
18893 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18894 n += len;
18895 }
18896
18897 if (field_width > len)
18898 {
18899 field_width -= len;
18900 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
18901 if (!NILP (props))
18902 Fadd_text_properties (make_number (0), make_number (field_width),
18903 props, lisp_string);
18904 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18905 n += field_width;
18906 }
18907
18908 return n;
18909 }
18910
18911
18912 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
18913 1, 4, 0,
18914 doc: /* Format a string out of a mode line format specification.
18915 First arg FORMAT specifies the mode line format (see `mode-line-format'
18916 for details) to use.
18917
18918 Optional second arg FACE specifies the face property to put
18919 on all characters for which no face is specified.
18920 The value t means whatever face the window's mode line currently uses
18921 \(either `mode-line' or `mode-line-inactive', depending).
18922 A value of nil means the default is no face property.
18923 If FACE is an integer, the value string has no text properties.
18924
18925 Optional third and fourth args WINDOW and BUFFER specify the window
18926 and buffer to use as the context for the formatting (defaults
18927 are the selected window and the window's buffer). */)
18928 (format, face, window, buffer)
18929 Lisp_Object format, face, window, buffer;
18930 {
18931 struct it it;
18932 int len;
18933 struct window *w;
18934 struct buffer *old_buffer = NULL;
18935 int face_id = -1;
18936 int no_props = INTEGERP (face);
18937 int count = SPECPDL_INDEX ();
18938 Lisp_Object str;
18939 int string_start = 0;
18940
18941 if (NILP (window))
18942 window = selected_window;
18943 CHECK_WINDOW (window);
18944 w = XWINDOW (window);
18945
18946 if (NILP (buffer))
18947 buffer = w->buffer;
18948 CHECK_BUFFER (buffer);
18949
18950 /* Make formatting the modeline a non-op when noninteractive, otherwise
18951 there will be problems later caused by a partially initialized frame. */
18952 if (NILP (format) || noninteractive)
18953 return empty_unibyte_string;
18954
18955 if (no_props)
18956 face = Qnil;
18957
18958 if (!NILP (face))
18959 {
18960 if (EQ (face, Qt))
18961 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
18962 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
18963 }
18964
18965 if (face_id < 0)
18966 face_id = DEFAULT_FACE_ID;
18967
18968 if (XBUFFER (buffer) != current_buffer)
18969 old_buffer = current_buffer;
18970
18971 /* Save things including mode_line_proptrans_alist,
18972 and set that to nil so that we don't alter the outer value. */
18973 record_unwind_protect (unwind_format_mode_line,
18974 format_mode_line_unwind_data
18975 (old_buffer, selected_window, 1));
18976 mode_line_proptrans_alist = Qnil;
18977
18978 Fselect_window (window, Qt);
18979 if (old_buffer)
18980 set_buffer_internal_1 (XBUFFER (buffer));
18981
18982 init_iterator (&it, w, -1, -1, NULL, face_id);
18983
18984 if (no_props)
18985 {
18986 mode_line_target = MODE_LINE_NOPROP;
18987 mode_line_string_face_prop = Qnil;
18988 mode_line_string_list = Qnil;
18989 string_start = MODE_LINE_NOPROP_LEN (0);
18990 }
18991 else
18992 {
18993 mode_line_target = MODE_LINE_STRING;
18994 mode_line_string_list = Qnil;
18995 mode_line_string_face = face;
18996 mode_line_string_face_prop
18997 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
18998 }
18999
19000 push_kboard (FRAME_KBOARD (it.f));
19001 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19002 pop_kboard ();
19003
19004 if (no_props)
19005 {
19006 len = MODE_LINE_NOPROP_LEN (string_start);
19007 str = make_string (mode_line_noprop_buf + string_start, len);
19008 }
19009 else
19010 {
19011 mode_line_string_list = Fnreverse (mode_line_string_list);
19012 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19013 empty_unibyte_string);
19014 }
19015
19016 unbind_to (count, Qnil);
19017 return str;
19018 }
19019
19020 /* Write a null-terminated, right justified decimal representation of
19021 the positive integer D to BUF using a minimal field width WIDTH. */
19022
19023 static void
19024 pint2str (buf, width, d)
19025 register char *buf;
19026 register int width;
19027 register int d;
19028 {
19029 register char *p = buf;
19030
19031 if (d <= 0)
19032 *p++ = '0';
19033 else
19034 {
19035 while (d > 0)
19036 {
19037 *p++ = d % 10 + '0';
19038 d /= 10;
19039 }
19040 }
19041
19042 for (width -= (int) (p - buf); width > 0; --width)
19043 *p++ = ' ';
19044 *p-- = '\0';
19045 while (p > buf)
19046 {
19047 d = *buf;
19048 *buf++ = *p;
19049 *p-- = d;
19050 }
19051 }
19052
19053 /* Write a null-terminated, right justified decimal and "human
19054 readable" representation of the nonnegative integer D to BUF using
19055 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19056
19057 static const char power_letter[] =
19058 {
19059 0, /* not used */
19060 'k', /* kilo */
19061 'M', /* mega */
19062 'G', /* giga */
19063 'T', /* tera */
19064 'P', /* peta */
19065 'E', /* exa */
19066 'Z', /* zetta */
19067 'Y' /* yotta */
19068 };
19069
19070 static void
19071 pint2hrstr (buf, width, d)
19072 char *buf;
19073 int width;
19074 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 (coding_system, buf, eol_flag)
19176 Lisp_Object coding_system;
19177 register char *buf;
19178 int eol_flag;
19179 {
19180 Lisp_Object val;
19181 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
19182 const unsigned char *eol_str;
19183 int eol_str_len;
19184 /* The EOL conversion we are using. */
19185 Lisp_Object eoltype;
19186
19187 val = CODING_SYSTEM_SPEC (coding_system);
19188 eoltype = Qnil;
19189
19190 if (!VECTORP (val)) /* Not yet decided. */
19191 {
19192 if (multibyte)
19193 *buf++ = '-';
19194 if (eol_flag)
19195 eoltype = eol_mnemonic_undecided;
19196 /* Don't mention EOL conversion if it isn't decided. */
19197 }
19198 else
19199 {
19200 Lisp_Object attrs;
19201 Lisp_Object eolvalue;
19202
19203 attrs = AREF (val, 0);
19204 eolvalue = AREF (val, 2);
19205
19206 if (multibyte)
19207 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19208
19209 if (eol_flag)
19210 {
19211 /* The EOL conversion that is normal on this system. */
19212
19213 if (NILP (eolvalue)) /* Not yet decided. */
19214 eoltype = eol_mnemonic_undecided;
19215 else if (VECTORP (eolvalue)) /* Not yet decided. */
19216 eoltype = eol_mnemonic_undecided;
19217 else /* eolvalue is Qunix, Qdos, or Qmac. */
19218 eoltype = (EQ (eolvalue, Qunix)
19219 ? eol_mnemonic_unix
19220 : (EQ (eolvalue, Qdos) == 1
19221 ? eol_mnemonic_dos : eol_mnemonic_mac));
19222 }
19223 }
19224
19225 if (eol_flag)
19226 {
19227 /* Mention the EOL conversion if it is not the usual one. */
19228 if (STRINGP (eoltype))
19229 {
19230 eol_str = SDATA (eoltype);
19231 eol_str_len = SBYTES (eoltype);
19232 }
19233 else if (CHARACTERP (eoltype))
19234 {
19235 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19236 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19237 eol_str = tmp;
19238 }
19239 else
19240 {
19241 eol_str = invalid_eol_type;
19242 eol_str_len = sizeof (invalid_eol_type) - 1;
19243 }
19244 bcopy (eol_str, buf, eol_str_len);
19245 buf += eol_str_len;
19246 }
19247
19248 return buf;
19249 }
19250
19251 /* Return a string for the output of a mode line %-spec for window W,
19252 generated by character C. PRECISION >= 0 means don't return a
19253 string longer than that value. FIELD_WIDTH > 0 means pad the
19254 string returned with spaces to that value. Return a Lisp string in
19255 *STRING if the resulting string is taken from that Lisp string.
19256
19257 Note we operate on the current buffer for most purposes,
19258 the exception being w->base_line_pos. */
19259
19260 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19261
19262 static char *
19263 decode_mode_spec (w, c, field_width, precision, string)
19264 struct window *w;
19265 register int c;
19266 int field_width, precision;
19267 Lisp_Object *string;
19268 {
19269 Lisp_Object obj;
19270 struct frame *f = XFRAME (WINDOW_FRAME (w));
19271 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19272 struct buffer *b = current_buffer;
19273
19274 obj = Qnil;
19275 *string = Qnil;
19276
19277 switch (c)
19278 {
19279 case '*':
19280 if (!NILP (b->read_only))
19281 return "%";
19282 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19283 return "*";
19284 return "-";
19285
19286 case '+':
19287 /* This differs from %* only for a modified read-only buffer. */
19288 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19289 return "*";
19290 if (!NILP (b->read_only))
19291 return "%";
19292 return "-";
19293
19294 case '&':
19295 /* This differs from %* in ignoring read-only-ness. */
19296 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19297 return "*";
19298 return "-";
19299
19300 case '%':
19301 return "%";
19302
19303 case '[':
19304 {
19305 int i;
19306 char *p;
19307
19308 if (command_loop_level > 5)
19309 return "[[[... ";
19310 p = decode_mode_spec_buf;
19311 for (i = 0; i < command_loop_level; i++)
19312 *p++ = '[';
19313 *p = 0;
19314 return decode_mode_spec_buf;
19315 }
19316
19317 case ']':
19318 {
19319 int i;
19320 char *p;
19321
19322 if (command_loop_level > 5)
19323 return " ...]]]";
19324 p = decode_mode_spec_buf;
19325 for (i = 0; i < command_loop_level; i++)
19326 *p++ = ']';
19327 *p = 0;
19328 return decode_mode_spec_buf;
19329 }
19330
19331 case '-':
19332 {
19333 register int i;
19334
19335 /* Let lots_of_dashes be a string of infinite length. */
19336 if (mode_line_target == MODE_LINE_NOPROP ||
19337 mode_line_target == MODE_LINE_STRING)
19338 return "--";
19339 if (field_width <= 0
19340 || field_width > sizeof (lots_of_dashes))
19341 {
19342 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19343 decode_mode_spec_buf[i] = '-';
19344 decode_mode_spec_buf[i] = '\0';
19345 return decode_mode_spec_buf;
19346 }
19347 else
19348 return lots_of_dashes;
19349 }
19350
19351 case 'b':
19352 obj = b->name;
19353 break;
19354
19355 case 'c':
19356 /* %c and %l are ignored in `frame-title-format'.
19357 (In redisplay_internal, the frame title is drawn _before_ the
19358 windows are updated, so the stuff which depends on actual
19359 window contents (such as %l) may fail to render properly, or
19360 even crash emacs.) */
19361 if (mode_line_target == MODE_LINE_TITLE)
19362 return "";
19363 else
19364 {
19365 int col = (int) current_column (); /* iftc */
19366 w->column_number_displayed = make_number (col);
19367 pint2str (decode_mode_spec_buf, field_width, col);
19368 return decode_mode_spec_buf;
19369 }
19370
19371 case 'e':
19372 #ifndef SYSTEM_MALLOC
19373 {
19374 if (NILP (Vmemory_full))
19375 return "";
19376 else
19377 return "!MEM FULL! ";
19378 }
19379 #else
19380 return "";
19381 #endif
19382
19383 case 'F':
19384 /* %F displays the frame name. */
19385 if (!NILP (f->title))
19386 return (char *) SDATA (f->title);
19387 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19388 return (char *) SDATA (f->name);
19389 return "Emacs";
19390
19391 case 'f':
19392 obj = b->filename;
19393 break;
19394
19395 case 'i':
19396 {
19397 int size = ZV - BEGV;
19398 pint2str (decode_mode_spec_buf, field_width, size);
19399 return decode_mode_spec_buf;
19400 }
19401
19402 case 'I':
19403 {
19404 int size = ZV - BEGV;
19405 pint2hrstr (decode_mode_spec_buf, field_width, size);
19406 return decode_mode_spec_buf;
19407 }
19408
19409 case 'l':
19410 {
19411 int startpos, startpos_byte, line, linepos, linepos_byte;
19412 int topline, nlines, junk, height;
19413
19414 /* %c and %l are ignored in `frame-title-format'. */
19415 if (mode_line_target == MODE_LINE_TITLE)
19416 return "";
19417
19418 startpos = XMARKER (w->start)->charpos;
19419 startpos_byte = marker_byte_position (w->start);
19420 height = WINDOW_TOTAL_LINES (w);
19421
19422 /* If we decided that this buffer isn't suitable for line numbers,
19423 don't forget that too fast. */
19424 if (EQ (w->base_line_pos, w->buffer))
19425 goto no_value;
19426 /* But do forget it, if the window shows a different buffer now. */
19427 else if (BUFFERP (w->base_line_pos))
19428 w->base_line_pos = Qnil;
19429
19430 /* If the buffer is very big, don't waste time. */
19431 if (INTEGERP (Vline_number_display_limit)
19432 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19433 {
19434 w->base_line_pos = Qnil;
19435 w->base_line_number = Qnil;
19436 goto no_value;
19437 }
19438
19439 if (INTEGERP (w->base_line_number)
19440 && INTEGERP (w->base_line_pos)
19441 && XFASTINT (w->base_line_pos) <= startpos)
19442 {
19443 line = XFASTINT (w->base_line_number);
19444 linepos = XFASTINT (w->base_line_pos);
19445 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19446 }
19447 else
19448 {
19449 line = 1;
19450 linepos = BUF_BEGV (b);
19451 linepos_byte = BUF_BEGV_BYTE (b);
19452 }
19453
19454 /* Count lines from base line to window start position. */
19455 nlines = display_count_lines (linepos, linepos_byte,
19456 startpos_byte,
19457 startpos, &junk);
19458
19459 topline = nlines + line;
19460
19461 /* Determine a new base line, if the old one is too close
19462 or too far away, or if we did not have one.
19463 "Too close" means it's plausible a scroll-down would
19464 go back past it. */
19465 if (startpos == BUF_BEGV (b))
19466 {
19467 w->base_line_number = make_number (topline);
19468 w->base_line_pos = make_number (BUF_BEGV (b));
19469 }
19470 else if (nlines < height + 25 || nlines > height * 3 + 50
19471 || linepos == BUF_BEGV (b))
19472 {
19473 int limit = BUF_BEGV (b);
19474 int limit_byte = BUF_BEGV_BYTE (b);
19475 int position;
19476 int distance = (height * 2 + 30) * line_number_display_limit_width;
19477
19478 if (startpos - distance > limit)
19479 {
19480 limit = startpos - distance;
19481 limit_byte = CHAR_TO_BYTE (limit);
19482 }
19483
19484 nlines = display_count_lines (startpos, startpos_byte,
19485 limit_byte,
19486 - (height * 2 + 30),
19487 &position);
19488 /* If we couldn't find the lines we wanted within
19489 line_number_display_limit_width chars per line,
19490 give up on line numbers for this window. */
19491 if (position == limit_byte && limit == startpos - distance)
19492 {
19493 w->base_line_pos = w->buffer;
19494 w->base_line_number = Qnil;
19495 goto no_value;
19496 }
19497
19498 w->base_line_number = make_number (topline - nlines);
19499 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19500 }
19501
19502 /* Now count lines from the start pos to point. */
19503 nlines = display_count_lines (startpos, startpos_byte,
19504 PT_BYTE, PT, &junk);
19505
19506 /* Record that we did display the line number. */
19507 line_number_displayed = 1;
19508
19509 /* Make the string to show. */
19510 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19511 return decode_mode_spec_buf;
19512 no_value:
19513 {
19514 char* p = decode_mode_spec_buf;
19515 int pad = field_width - 2;
19516 while (pad-- > 0)
19517 *p++ = ' ';
19518 *p++ = '?';
19519 *p++ = '?';
19520 *p = '\0';
19521 return decode_mode_spec_buf;
19522 }
19523 }
19524 break;
19525
19526 case 'm':
19527 obj = b->mode_name;
19528 break;
19529
19530 case 'n':
19531 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19532 return " Narrow";
19533 break;
19534
19535 case 'p':
19536 {
19537 int pos = marker_position (w->start);
19538 int total = BUF_ZV (b) - BUF_BEGV (b);
19539
19540 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19541 {
19542 if (pos <= BUF_BEGV (b))
19543 return "All";
19544 else
19545 return "Bottom";
19546 }
19547 else if (pos <= BUF_BEGV (b))
19548 return "Top";
19549 else
19550 {
19551 if (total > 1000000)
19552 /* Do it differently for a large value, to avoid overflow. */
19553 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19554 else
19555 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19556 /* We can't normally display a 3-digit number,
19557 so get us a 2-digit number that is close. */
19558 if (total == 100)
19559 total = 99;
19560 sprintf (decode_mode_spec_buf, "%2d%%", total);
19561 return decode_mode_spec_buf;
19562 }
19563 }
19564
19565 /* Display percentage of size above the bottom of the screen. */
19566 case 'P':
19567 {
19568 int toppos = marker_position (w->start);
19569 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19570 int total = BUF_ZV (b) - BUF_BEGV (b);
19571
19572 if (botpos >= BUF_ZV (b))
19573 {
19574 if (toppos <= BUF_BEGV (b))
19575 return "All";
19576 else
19577 return "Bottom";
19578 }
19579 else
19580 {
19581 if (total > 1000000)
19582 /* Do it differently for a large value, to avoid overflow. */
19583 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19584 else
19585 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19586 /* We can't normally display a 3-digit number,
19587 so get us a 2-digit number that is close. */
19588 if (total == 100)
19589 total = 99;
19590 if (toppos <= BUF_BEGV (b))
19591 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
19592 else
19593 sprintf (decode_mode_spec_buf, "%2d%%", total);
19594 return decode_mode_spec_buf;
19595 }
19596 }
19597
19598 case 's':
19599 /* status of process */
19600 obj = Fget_buffer_process (Fcurrent_buffer ());
19601 if (NILP (obj))
19602 return "no process";
19603 #ifdef subprocesses
19604 obj = Fsymbol_name (Fprocess_status (obj));
19605 #endif
19606 break;
19607
19608 case '@':
19609 {
19610 int count = inhibit_garbage_collection ();
19611 Lisp_Object val = call1 (intern ("file-remote-p"),
19612 current_buffer->directory);
19613 unbind_to (count, Qnil);
19614
19615 if (NILP (val))
19616 return "-";
19617 else
19618 return "@";
19619 }
19620
19621 case 't': /* indicate TEXT or BINARY */
19622 #ifdef MODE_LINE_BINARY_TEXT
19623 return MODE_LINE_BINARY_TEXT (b);
19624 #else
19625 return "T";
19626 #endif
19627
19628 case 'z':
19629 /* coding-system (not including end-of-line format) */
19630 case 'Z':
19631 /* coding-system (including end-of-line type) */
19632 {
19633 int eol_flag = (c == 'Z');
19634 char *p = decode_mode_spec_buf;
19635
19636 if (! FRAME_WINDOW_P (f))
19637 {
19638 /* No need to mention EOL here--the terminal never needs
19639 to do EOL conversion. */
19640 p = decode_mode_spec_coding (CODING_ID_NAME
19641 (FRAME_KEYBOARD_CODING (f)->id),
19642 p, 0);
19643 p = decode_mode_spec_coding (CODING_ID_NAME
19644 (FRAME_TERMINAL_CODING (f)->id),
19645 p, 0);
19646 }
19647 p = decode_mode_spec_coding (b->buffer_file_coding_system,
19648 p, eol_flag);
19649
19650 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19651 #ifdef subprocesses
19652 obj = Fget_buffer_process (Fcurrent_buffer ());
19653 if (PROCESSP (obj))
19654 {
19655 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19656 p, eol_flag);
19657 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19658 p, eol_flag);
19659 }
19660 #endif /* subprocesses */
19661 #endif /* 0 */
19662 *p = 0;
19663 return decode_mode_spec_buf;
19664 }
19665 }
19666
19667 if (STRINGP (obj))
19668 {
19669 *string = obj;
19670 return (char *) SDATA (obj);
19671 }
19672 else
19673 return "";
19674 }
19675
19676
19677 /* Count up to COUNT lines starting from START / START_BYTE.
19678 But don't go beyond LIMIT_BYTE.
19679 Return the number of lines thus found (always nonnegative).
19680
19681 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19682
19683 static int
19684 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
19685 int start, start_byte, limit_byte, count;
19686 int *byte_pos_ptr;
19687 {
19688 register unsigned char *cursor;
19689 unsigned char *base;
19690
19691 register int ceiling;
19692 register unsigned char *ceiling_addr;
19693 int orig_count = count;
19694
19695 /* If we are not in selective display mode,
19696 check only for newlines. */
19697 int selective_display = (!NILP (current_buffer->selective_display)
19698 && !INTEGERP (current_buffer->selective_display));
19699
19700 if (count > 0)
19701 {
19702 while (start_byte < limit_byte)
19703 {
19704 ceiling = BUFFER_CEILING_OF (start_byte);
19705 ceiling = min (limit_byte - 1, ceiling);
19706 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19707 base = (cursor = BYTE_POS_ADDR (start_byte));
19708 while (1)
19709 {
19710 if (selective_display)
19711 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19712 ;
19713 else
19714 while (*cursor != '\n' && ++cursor != ceiling_addr)
19715 ;
19716
19717 if (cursor != ceiling_addr)
19718 {
19719 if (--count == 0)
19720 {
19721 start_byte += cursor - base + 1;
19722 *byte_pos_ptr = start_byte;
19723 return orig_count;
19724 }
19725 else
19726 if (++cursor == ceiling_addr)
19727 break;
19728 }
19729 else
19730 break;
19731 }
19732 start_byte += cursor - base;
19733 }
19734 }
19735 else
19736 {
19737 while (start_byte > limit_byte)
19738 {
19739 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19740 ceiling = max (limit_byte, ceiling);
19741 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19742 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19743 while (1)
19744 {
19745 if (selective_display)
19746 while (--cursor != ceiling_addr
19747 && *cursor != '\n' && *cursor != 015)
19748 ;
19749 else
19750 while (--cursor != ceiling_addr && *cursor != '\n')
19751 ;
19752
19753 if (cursor != ceiling_addr)
19754 {
19755 if (++count == 0)
19756 {
19757 start_byte += cursor - base + 1;
19758 *byte_pos_ptr = start_byte;
19759 /* When scanning backwards, we should
19760 not count the newline posterior to which we stop. */
19761 return - orig_count - 1;
19762 }
19763 }
19764 else
19765 break;
19766 }
19767 /* Here we add 1 to compensate for the last decrement
19768 of CURSOR, which took it past the valid range. */
19769 start_byte += cursor - base + 1;
19770 }
19771 }
19772
19773 *byte_pos_ptr = limit_byte;
19774
19775 if (count < 0)
19776 return - orig_count + count;
19777 return orig_count - count;
19778
19779 }
19780
19781
19782 \f
19783 /***********************************************************************
19784 Displaying strings
19785 ***********************************************************************/
19786
19787 /* Display a NUL-terminated string, starting with index START.
19788
19789 If STRING is non-null, display that C string. Otherwise, the Lisp
19790 string LISP_STRING is displayed. There's a case that STRING is
19791 non-null and LISP_STRING is not nil. It means STRING is a string
19792 data of LISP_STRING. In that case, we display LISP_STRING while
19793 ignoring its text properties.
19794
19795 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19796 FACE_STRING. Display STRING or LISP_STRING with the face at
19797 FACE_STRING_POS in FACE_STRING:
19798
19799 Display the string in the environment given by IT, but use the
19800 standard display table, temporarily.
19801
19802 FIELD_WIDTH is the minimum number of output glyphs to produce.
19803 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19804 with spaces. If STRING has more characters, more than FIELD_WIDTH
19805 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19806
19807 PRECISION is the maximum number of characters to output from
19808 STRING. PRECISION < 0 means don't truncate the string.
19809
19810 This is roughly equivalent to printf format specifiers:
19811
19812 FIELD_WIDTH PRECISION PRINTF
19813 ----------------------------------------
19814 -1 -1 %s
19815 -1 10 %.10s
19816 10 -1 %10s
19817 20 10 %20.10s
19818
19819 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19820 display them, and < 0 means obey the current buffer's value of
19821 enable_multibyte_characters.
19822
19823 Value is the number of columns displayed. */
19824
19825 static int
19826 display_string (string, lisp_string, face_string, face_string_pos,
19827 start, it, field_width, precision, max_x, multibyte)
19828 unsigned char *string;
19829 Lisp_Object lisp_string;
19830 Lisp_Object face_string;
19831 EMACS_INT face_string_pos;
19832 EMACS_INT start;
19833 struct it *it;
19834 int field_width, precision, max_x;
19835 int multibyte;
19836 {
19837 int hpos_at_start = it->hpos;
19838 int saved_face_id = it->face_id;
19839 struct glyph_row *row = it->glyph_row;
19840
19841 /* Initialize the iterator IT for iteration over STRING beginning
19842 with index START. */
19843 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19844 precision, field_width, multibyte);
19845 if (string && STRINGP (lisp_string))
19846 /* LISP_STRING is the one returned by decode_mode_spec. We should
19847 ignore its text properties. */
19848 it->stop_charpos = -1;
19849
19850 /* If displaying STRING, set up the face of the iterator
19851 from LISP_STRING, if that's given. */
19852 if (STRINGP (face_string))
19853 {
19854 EMACS_INT endptr;
19855 struct face *face;
19856
19857 it->face_id
19858 = face_at_string_position (it->w, face_string, face_string_pos,
19859 0, it->region_beg_charpos,
19860 it->region_end_charpos,
19861 &endptr, it->base_face_id, 0);
19862 face = FACE_FROM_ID (it->f, it->face_id);
19863 it->face_box_p = face->box != FACE_NO_BOX;
19864 }
19865
19866 /* Set max_x to the maximum allowed X position. Don't let it go
19867 beyond the right edge of the window. */
19868 if (max_x <= 0)
19869 max_x = it->last_visible_x;
19870 else
19871 max_x = min (max_x, it->last_visible_x);
19872
19873 /* Skip over display elements that are not visible. because IT->w is
19874 hscrolled. */
19875 if (it->current_x < it->first_visible_x)
19876 move_it_in_display_line_to (it, 100000, it->first_visible_x,
19877 MOVE_TO_POS | MOVE_TO_X);
19878
19879 row->ascent = it->max_ascent;
19880 row->height = it->max_ascent + it->max_descent;
19881 row->phys_ascent = it->max_phys_ascent;
19882 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19883 row->extra_line_spacing = it->max_extra_line_spacing;
19884
19885 /* This condition is for the case that we are called with current_x
19886 past last_visible_x. */
19887 while (it->current_x < max_x)
19888 {
19889 int x_before, x, n_glyphs_before, i, nglyphs;
19890
19891 /* Get the next display element. */
19892 if (!get_next_display_element (it))
19893 break;
19894
19895 /* Produce glyphs. */
19896 x_before = it->current_x;
19897 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
19898 PRODUCE_GLYPHS (it);
19899
19900 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
19901 i = 0;
19902 x = x_before;
19903 while (i < nglyphs)
19904 {
19905 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19906
19907 if (it->line_wrap != TRUNCATE
19908 && x + glyph->pixel_width > max_x)
19909 {
19910 /* End of continued line or max_x reached. */
19911 if (CHAR_GLYPH_PADDING_P (*glyph))
19912 {
19913 /* A wide character is unbreakable. */
19914 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
19915 it->current_x = x_before;
19916 }
19917 else
19918 {
19919 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
19920 it->current_x = x;
19921 }
19922 break;
19923 }
19924 else if (x + glyph->pixel_width >= it->first_visible_x)
19925 {
19926 /* Glyph is at least partially visible. */
19927 ++it->hpos;
19928 if (x < it->first_visible_x)
19929 it->glyph_row->x = x - it->first_visible_x;
19930 }
19931 else
19932 {
19933 /* Glyph is off the left margin of the display area.
19934 Should not happen. */
19935 abort ();
19936 }
19937
19938 row->ascent = max (row->ascent, it->max_ascent);
19939 row->height = max (row->height, it->max_ascent + it->max_descent);
19940 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19941 row->phys_height = max (row->phys_height,
19942 it->max_phys_ascent + it->max_phys_descent);
19943 row->extra_line_spacing = max (row->extra_line_spacing,
19944 it->max_extra_line_spacing);
19945 x += glyph->pixel_width;
19946 ++i;
19947 }
19948
19949 /* Stop if max_x reached. */
19950 if (i < nglyphs)
19951 break;
19952
19953 /* Stop at line ends. */
19954 if (ITERATOR_AT_END_OF_LINE_P (it))
19955 {
19956 it->continuation_lines_width = 0;
19957 break;
19958 }
19959
19960 set_iterator_to_next (it, 1);
19961
19962 /* Stop if truncating at the right edge. */
19963 if (it->line_wrap == TRUNCATE
19964 && it->current_x >= it->last_visible_x)
19965 {
19966 /* Add truncation mark, but don't do it if the line is
19967 truncated at a padding space. */
19968 if (IT_CHARPOS (*it) < it->string_nchars)
19969 {
19970 if (!FRAME_WINDOW_P (it->f))
19971 {
19972 int i, n;
19973
19974 if (it->current_x > it->last_visible_x)
19975 {
19976 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19977 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19978 break;
19979 for (n = row->used[TEXT_AREA]; i < n; ++i)
19980 {
19981 row->used[TEXT_AREA] = i;
19982 produce_special_glyphs (it, IT_TRUNCATION);
19983 }
19984 }
19985 produce_special_glyphs (it, IT_TRUNCATION);
19986 }
19987 it->glyph_row->truncated_on_right_p = 1;
19988 }
19989 break;
19990 }
19991 }
19992
19993 /* Maybe insert a truncation at the left. */
19994 if (it->first_visible_x
19995 && IT_CHARPOS (*it) > 0)
19996 {
19997 if (!FRAME_WINDOW_P (it->f))
19998 insert_left_trunc_glyphs (it);
19999 it->glyph_row->truncated_on_left_p = 1;
20000 }
20001
20002 it->face_id = saved_face_id;
20003
20004 /* Value is number of columns displayed. */
20005 return it->hpos - hpos_at_start;
20006 }
20007
20008
20009 \f
20010 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
20011 appears as an element of LIST or as the car of an element of LIST.
20012 If PROPVAL is a list, compare each element against LIST in that
20013 way, and return 1/2 if any element of PROPVAL is found in LIST.
20014 Otherwise return 0. This function cannot quit.
20015 The return value is 2 if the text is invisible but with an ellipsis
20016 and 1 if it's invisible and without an ellipsis. */
20017
20018 int
20019 invisible_p (propval, list)
20020 register Lisp_Object propval;
20021 Lisp_Object list;
20022 {
20023 register Lisp_Object tail, proptail;
20024
20025 for (tail = list; CONSP (tail); tail = XCDR (tail))
20026 {
20027 register Lisp_Object tem;
20028 tem = XCAR (tail);
20029 if (EQ (propval, tem))
20030 return 1;
20031 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20032 return NILP (XCDR (tem)) ? 1 : 2;
20033 }
20034
20035 if (CONSP (propval))
20036 {
20037 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20038 {
20039 Lisp_Object propelt;
20040 propelt = XCAR (proptail);
20041 for (tail = list; CONSP (tail); tail = XCDR (tail))
20042 {
20043 register Lisp_Object tem;
20044 tem = XCAR (tail);
20045 if (EQ (propelt, tem))
20046 return 1;
20047 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20048 return NILP (XCDR (tem)) ? 1 : 2;
20049 }
20050 }
20051 }
20052
20053 return 0;
20054 }
20055
20056 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20057 doc: /* Non-nil if the property makes the text invisible.
20058 POS-OR-PROP can be a marker or number, in which case it is taken to be
20059 a position in the current buffer and the value of the `invisible' property
20060 is checked; or it can be some other value, which is then presumed to be the
20061 value of the `invisible' property of the text of interest.
20062 The non-nil value returned can be t for truly invisible text or something
20063 else if the text is replaced by an ellipsis. */)
20064 (pos_or_prop)
20065 Lisp_Object pos_or_prop;
20066 {
20067 Lisp_Object prop
20068 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20069 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20070 : pos_or_prop);
20071 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20072 return (invis == 0 ? Qnil
20073 : invis == 1 ? Qt
20074 : make_number (invis));
20075 }
20076
20077 /* Calculate a width or height in pixels from a specification using
20078 the following elements:
20079
20080 SPEC ::=
20081 NUM - a (fractional) multiple of the default font width/height
20082 (NUM) - specifies exactly NUM pixels
20083 UNIT - a fixed number of pixels, see below.
20084 ELEMENT - size of a display element in pixels, see below.
20085 (NUM . SPEC) - equals NUM * SPEC
20086 (+ SPEC SPEC ...) - add pixel values
20087 (- SPEC SPEC ...) - subtract pixel values
20088 (- SPEC) - negate pixel value
20089
20090 NUM ::=
20091 INT or FLOAT - a number constant
20092 SYMBOL - use symbol's (buffer local) variable binding.
20093
20094 UNIT ::=
20095 in - pixels per inch *)
20096 mm - pixels per 1/1000 meter *)
20097 cm - pixels per 1/100 meter *)
20098 width - width of current font in pixels.
20099 height - height of current font in pixels.
20100
20101 *) using the ratio(s) defined in display-pixels-per-inch.
20102
20103 ELEMENT ::=
20104
20105 left-fringe - left fringe width in pixels
20106 right-fringe - right fringe width in pixels
20107
20108 left-margin - left margin width in pixels
20109 right-margin - right margin width in pixels
20110
20111 scroll-bar - scroll-bar area width in pixels
20112
20113 Examples:
20114
20115 Pixels corresponding to 5 inches:
20116 (5 . in)
20117
20118 Total width of non-text areas on left side of window (if scroll-bar is on left):
20119 '(space :width (+ left-fringe left-margin scroll-bar))
20120
20121 Align to first text column (in header line):
20122 '(space :align-to 0)
20123
20124 Align to middle of text area minus half the width of variable `my-image'
20125 containing a loaded image:
20126 '(space :align-to (0.5 . (- text my-image)))
20127
20128 Width of left margin minus width of 1 character in the default font:
20129 '(space :width (- left-margin 1))
20130
20131 Width of left margin minus width of 2 characters in the current font:
20132 '(space :width (- left-margin (2 . width)))
20133
20134 Center 1 character over left-margin (in header line):
20135 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20136
20137 Different ways to express width of left fringe plus left margin minus one pixel:
20138 '(space :width (- (+ left-fringe left-margin) (1)))
20139 '(space :width (+ left-fringe left-margin (- (1))))
20140 '(space :width (+ left-fringe left-margin (-1)))
20141
20142 */
20143
20144 #define NUMVAL(X) \
20145 ((INTEGERP (X) || FLOATP (X)) \
20146 ? XFLOATINT (X) \
20147 : - 1)
20148
20149 int
20150 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
20151 double *res;
20152 struct it *it;
20153 Lisp_Object prop;
20154 struct font *font;
20155 int width_p, *align_to;
20156 {
20157 double pixels;
20158
20159 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20160 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20161
20162 if (NILP (prop))
20163 return OK_PIXELS (0);
20164
20165 xassert (FRAME_LIVE_P (it->f));
20166
20167 if (SYMBOLP (prop))
20168 {
20169 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20170 {
20171 char *unit = SDATA (SYMBOL_NAME (prop));
20172
20173 if (unit[0] == 'i' && unit[1] == 'n')
20174 pixels = 1.0;
20175 else if (unit[0] == 'm' && unit[1] == 'm')
20176 pixels = 25.4;
20177 else if (unit[0] == 'c' && unit[1] == 'm')
20178 pixels = 2.54;
20179 else
20180 pixels = 0;
20181 if (pixels > 0)
20182 {
20183 double ppi;
20184 #ifdef HAVE_WINDOW_SYSTEM
20185 if (FRAME_WINDOW_P (it->f)
20186 && (ppi = (width_p
20187 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20188 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20189 ppi > 0))
20190 return OK_PIXELS (ppi / pixels);
20191 #endif
20192
20193 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20194 || (CONSP (Vdisplay_pixels_per_inch)
20195 && (ppi = (width_p
20196 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20197 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20198 ppi > 0)))
20199 return OK_PIXELS (ppi / pixels);
20200
20201 return 0;
20202 }
20203 }
20204
20205 #ifdef HAVE_WINDOW_SYSTEM
20206 if (EQ (prop, Qheight))
20207 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20208 if (EQ (prop, Qwidth))
20209 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20210 #else
20211 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20212 return OK_PIXELS (1);
20213 #endif
20214
20215 if (EQ (prop, Qtext))
20216 return OK_PIXELS (width_p
20217 ? window_box_width (it->w, TEXT_AREA)
20218 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20219
20220 if (align_to && *align_to < 0)
20221 {
20222 *res = 0;
20223 if (EQ (prop, Qleft))
20224 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20225 if (EQ (prop, Qright))
20226 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20227 if (EQ (prop, Qcenter))
20228 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20229 + window_box_width (it->w, TEXT_AREA) / 2);
20230 if (EQ (prop, Qleft_fringe))
20231 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20232 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20233 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20234 if (EQ (prop, Qright_fringe))
20235 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20236 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20237 : window_box_right_offset (it->w, TEXT_AREA));
20238 if (EQ (prop, Qleft_margin))
20239 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20240 if (EQ (prop, Qright_margin))
20241 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20242 if (EQ (prop, Qscroll_bar))
20243 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20244 ? 0
20245 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20246 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20247 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20248 : 0)));
20249 }
20250 else
20251 {
20252 if (EQ (prop, Qleft_fringe))
20253 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20254 if (EQ (prop, Qright_fringe))
20255 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20256 if (EQ (prop, Qleft_margin))
20257 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20258 if (EQ (prop, Qright_margin))
20259 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20260 if (EQ (prop, Qscroll_bar))
20261 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20262 }
20263
20264 prop = Fbuffer_local_value (prop, it->w->buffer);
20265 }
20266
20267 if (INTEGERP (prop) || FLOATP (prop))
20268 {
20269 int base_unit = (width_p
20270 ? FRAME_COLUMN_WIDTH (it->f)
20271 : FRAME_LINE_HEIGHT (it->f));
20272 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20273 }
20274
20275 if (CONSP (prop))
20276 {
20277 Lisp_Object car = XCAR (prop);
20278 Lisp_Object cdr = XCDR (prop);
20279
20280 if (SYMBOLP (car))
20281 {
20282 #ifdef HAVE_WINDOW_SYSTEM
20283 if (FRAME_WINDOW_P (it->f)
20284 && valid_image_p (prop))
20285 {
20286 int id = lookup_image (it->f, prop);
20287 struct image *img = IMAGE_FROM_ID (it->f, id);
20288
20289 return OK_PIXELS (width_p ? img->width : img->height);
20290 }
20291 #endif
20292 if (EQ (car, Qplus) || EQ (car, Qminus))
20293 {
20294 int first = 1;
20295 double px;
20296
20297 pixels = 0;
20298 while (CONSP (cdr))
20299 {
20300 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20301 font, width_p, align_to))
20302 return 0;
20303 if (first)
20304 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20305 else
20306 pixels += px;
20307 cdr = XCDR (cdr);
20308 }
20309 if (EQ (car, Qminus))
20310 pixels = -pixels;
20311 return OK_PIXELS (pixels);
20312 }
20313
20314 car = Fbuffer_local_value (car, it->w->buffer);
20315 }
20316
20317 if (INTEGERP (car) || FLOATP (car))
20318 {
20319 double fact;
20320 pixels = XFLOATINT (car);
20321 if (NILP (cdr))
20322 return OK_PIXELS (pixels);
20323 if (calc_pixel_width_or_height (&fact, it, cdr,
20324 font, width_p, align_to))
20325 return OK_PIXELS (pixels * fact);
20326 return 0;
20327 }
20328
20329 return 0;
20330 }
20331
20332 return 0;
20333 }
20334
20335 \f
20336 /***********************************************************************
20337 Glyph Display
20338 ***********************************************************************/
20339
20340 #ifdef HAVE_WINDOW_SYSTEM
20341
20342 #if GLYPH_DEBUG
20343
20344 void
20345 dump_glyph_string (s)
20346 struct glyph_string *s;
20347 {
20348 fprintf (stderr, "glyph string\n");
20349 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20350 s->x, s->y, s->width, s->height);
20351 fprintf (stderr, " ybase = %d\n", s->ybase);
20352 fprintf (stderr, " hl = %d\n", s->hl);
20353 fprintf (stderr, " left overhang = %d, right = %d\n",
20354 s->left_overhang, s->right_overhang);
20355 fprintf (stderr, " nchars = %d\n", s->nchars);
20356 fprintf (stderr, " extends to end of line = %d\n",
20357 s->extends_to_end_of_line_p);
20358 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20359 fprintf (stderr, " bg width = %d\n", s->background_width);
20360 }
20361
20362 #endif /* GLYPH_DEBUG */
20363
20364 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20365 of XChar2b structures for S; it can't be allocated in
20366 init_glyph_string because it must be allocated via `alloca'. W
20367 is the window on which S is drawn. ROW and AREA are the glyph row
20368 and area within the row from which S is constructed. START is the
20369 index of the first glyph structure covered by S. HL is a
20370 face-override for drawing S. */
20371
20372 #ifdef HAVE_NTGUI
20373 #define OPTIONAL_HDC(hdc) hdc,
20374 #define DECLARE_HDC(hdc) HDC hdc;
20375 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20376 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20377 #endif
20378
20379 #ifndef OPTIONAL_HDC
20380 #define OPTIONAL_HDC(hdc)
20381 #define DECLARE_HDC(hdc)
20382 #define ALLOCATE_HDC(hdc, f)
20383 #define RELEASE_HDC(hdc, f)
20384 #endif
20385
20386 static void
20387 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
20388 struct glyph_string *s;
20389 DECLARE_HDC (hdc)
20390 XChar2b *char2b;
20391 struct window *w;
20392 struct glyph_row *row;
20393 enum glyph_row_area area;
20394 int start;
20395 enum draw_glyphs_face hl;
20396 {
20397 bzero (s, sizeof *s);
20398 s->w = w;
20399 s->f = XFRAME (w->frame);
20400 #ifdef HAVE_NTGUI
20401 s->hdc = hdc;
20402 #endif
20403 s->display = FRAME_X_DISPLAY (s->f);
20404 s->window = FRAME_X_WINDOW (s->f);
20405 s->char2b = char2b;
20406 s->hl = hl;
20407 s->row = row;
20408 s->area = area;
20409 s->first_glyph = row->glyphs[area] + start;
20410 s->height = row->height;
20411 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20412 s->ybase = s->y + row->ascent;
20413 }
20414
20415
20416 /* Append the list of glyph strings with head H and tail T to the list
20417 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20418
20419 static INLINE void
20420 append_glyph_string_lists (head, tail, h, t)
20421 struct glyph_string **head, **tail;
20422 struct glyph_string *h, *t;
20423 {
20424 if (h)
20425 {
20426 if (*head)
20427 (*tail)->next = h;
20428 else
20429 *head = h;
20430 h->prev = *tail;
20431 *tail = t;
20432 }
20433 }
20434
20435
20436 /* Prepend the list of glyph strings with head H and tail T to the
20437 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20438 result. */
20439
20440 static INLINE void
20441 prepend_glyph_string_lists (head, tail, h, t)
20442 struct glyph_string **head, **tail;
20443 struct glyph_string *h, *t;
20444 {
20445 if (h)
20446 {
20447 if (*head)
20448 (*head)->prev = t;
20449 else
20450 *tail = t;
20451 t->next = *head;
20452 *head = h;
20453 }
20454 }
20455
20456
20457 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20458 Set *HEAD and *TAIL to the resulting list. */
20459
20460 static INLINE void
20461 append_glyph_string (head, tail, s)
20462 struct glyph_string **head, **tail;
20463 struct glyph_string *s;
20464 {
20465 s->next = s->prev = NULL;
20466 append_glyph_string_lists (head, tail, s, s);
20467 }
20468
20469
20470 /* Get face and two-byte form of character C in face FACE_ID on frame
20471 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
20472 means we want to display multibyte text. DISPLAY_P non-zero means
20473 make sure that X resources for the face returned are allocated.
20474 Value is a pointer to a realized face that is ready for display if
20475 DISPLAY_P is non-zero. */
20476
20477 static INLINE struct face *
20478 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
20479 struct frame *f;
20480 int c, face_id;
20481 XChar2b *char2b;
20482 int multibyte_p, display_p;
20483 {
20484 struct face *face = FACE_FROM_ID (f, face_id);
20485
20486 if (face->font)
20487 {
20488 unsigned code = face->font->driver->encode_char (face->font, c);
20489
20490 if (code != FONT_INVALID_CODE)
20491 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20492 else
20493 STORE_XCHAR2B (char2b, 0, 0);
20494 }
20495
20496 /* Make sure X resources of the face are allocated. */
20497 #ifdef HAVE_X_WINDOWS
20498 if (display_p)
20499 #endif
20500 {
20501 xassert (face != NULL);
20502 PREPARE_FACE_FOR_DISPLAY (f, face);
20503 }
20504
20505 return face;
20506 }
20507
20508
20509 /* Get face and two-byte form of character glyph GLYPH on frame F.
20510 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20511 a pointer to a realized face that is ready for display. */
20512
20513 static INLINE struct face *
20514 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
20515 struct frame *f;
20516 struct glyph *glyph;
20517 XChar2b *char2b;
20518 int *two_byte_p;
20519 {
20520 struct face *face;
20521
20522 xassert (glyph->type == CHAR_GLYPH);
20523 face = FACE_FROM_ID (f, glyph->face_id);
20524
20525 if (two_byte_p)
20526 *two_byte_p = 0;
20527
20528 if (face->font)
20529 {
20530 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
20531
20532 if (code != FONT_INVALID_CODE)
20533 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20534 else
20535 STORE_XCHAR2B (char2b, 0, 0);
20536 }
20537
20538 /* Make sure X resources of the face are allocated. */
20539 xassert (face != NULL);
20540 PREPARE_FACE_FOR_DISPLAY (f, face);
20541 return face;
20542 }
20543
20544
20545 /* Fill glyph string S with composition components specified by S->cmp.
20546
20547 BASE_FACE is the base face of the composition.
20548 S->cmp_from is the index of the first component for S.
20549
20550 OVERLAPS non-zero means S should draw the foreground only, and use
20551 its physical height for clipping. See also draw_glyphs.
20552
20553 Value is the index of a component not in S. */
20554
20555 static int
20556 fill_composite_glyph_string (s, base_face, overlaps)
20557 struct glyph_string *s;
20558 struct face *base_face;
20559 int overlaps;
20560 {
20561 int i;
20562 /* For all glyphs of this composition, starting at the offset
20563 S->cmp_from, until we reach the end of the definition or encounter a
20564 glyph that requires the different face, add it to S. */
20565 struct face *face;
20566
20567 xassert (s);
20568
20569 s->for_overlaps = overlaps;
20570 s->face = NULL;
20571 s->font = NULL;
20572 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20573 {
20574 int c = COMPOSITION_GLYPH (s->cmp, i);
20575
20576 if (c != '\t')
20577 {
20578 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20579 -1, Qnil);
20580
20581 face = get_char_face_and_encoding (s->f, c, face_id,
20582 s->char2b + i, 1, 1);
20583 if (face)
20584 {
20585 if (! s->face)
20586 {
20587 s->face = face;
20588 s->font = s->face->font;
20589 }
20590 else if (s->face != face)
20591 break;
20592 }
20593 }
20594 ++s->nchars;
20595 }
20596 s->cmp_to = i;
20597
20598 /* All glyph strings for the same composition has the same width,
20599 i.e. the width set for the first component of the composition. */
20600 s->width = s->first_glyph->pixel_width;
20601
20602 /* If the specified font could not be loaded, use the frame's
20603 default font, but record the fact that we couldn't load it in
20604 the glyph string so that we can draw rectangles for the
20605 characters of the glyph string. */
20606 if (s->font == NULL)
20607 {
20608 s->font_not_found_p = 1;
20609 s->font = FRAME_FONT (s->f);
20610 }
20611
20612 /* Adjust base line for subscript/superscript text. */
20613 s->ybase += s->first_glyph->voffset;
20614
20615 /* This glyph string must always be drawn with 16-bit functions. */
20616 s->two_byte_p = 1;
20617
20618 return s->cmp_to;
20619 }
20620
20621 static int
20622 fill_gstring_glyph_string (s, face_id, start, end, overlaps)
20623 struct glyph_string *s;
20624 int face_id;
20625 int start, end, overlaps;
20626 {
20627 struct glyph *glyph, *last;
20628 Lisp_Object lgstring;
20629 int i;
20630
20631 s->for_overlaps = overlaps;
20632 glyph = s->row->glyphs[s->area] + start;
20633 last = s->row->glyphs[s->area] + end;
20634 s->cmp_id = glyph->u.cmp.id;
20635 s->cmp_from = glyph->u.cmp.from;
20636 s->cmp_to = glyph->u.cmp.to + 1;
20637 s->face = FACE_FROM_ID (s->f, face_id);
20638 lgstring = composition_gstring_from_id (s->cmp_id);
20639 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20640 glyph++;
20641 while (glyph < last
20642 && glyph->u.cmp.automatic
20643 && glyph->u.cmp.id == s->cmp_id
20644 && s->cmp_to == glyph->u.cmp.from)
20645 s->cmp_to = (glyph++)->u.cmp.to + 1;
20646
20647 for (i = s->cmp_from; i < s->cmp_to; i++)
20648 {
20649 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20650 unsigned code = LGLYPH_CODE (lglyph);
20651
20652 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20653 }
20654 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20655 return glyph - s->row->glyphs[s->area];
20656 }
20657
20658
20659 /* Fill glyph string S from a sequence of character glyphs.
20660
20661 FACE_ID is the face id of the string. START is the index of the
20662 first glyph to consider, END is the index of the last + 1.
20663 OVERLAPS non-zero means S should draw the foreground only, and use
20664 its physical height for clipping. See also draw_glyphs.
20665
20666 Value is the index of the first glyph not in S. */
20667
20668 static int
20669 fill_glyph_string (s, face_id, start, end, overlaps)
20670 struct glyph_string *s;
20671 int face_id;
20672 int start, end, overlaps;
20673 {
20674 struct glyph *glyph, *last;
20675 int voffset;
20676 int glyph_not_available_p;
20677
20678 xassert (s->f == XFRAME (s->w->frame));
20679 xassert (s->nchars == 0);
20680 xassert (start >= 0 && end > start);
20681
20682 s->for_overlaps = overlaps;
20683 glyph = s->row->glyphs[s->area] + start;
20684 last = s->row->glyphs[s->area] + end;
20685 voffset = glyph->voffset;
20686 s->padding_p = glyph->padding_p;
20687 glyph_not_available_p = glyph->glyph_not_available_p;
20688
20689 while (glyph < last
20690 && glyph->type == CHAR_GLYPH
20691 && glyph->voffset == voffset
20692 /* Same face id implies same font, nowadays. */
20693 && glyph->face_id == face_id
20694 && glyph->glyph_not_available_p == glyph_not_available_p)
20695 {
20696 int two_byte_p;
20697
20698 s->face = get_glyph_face_and_encoding (s->f, glyph,
20699 s->char2b + s->nchars,
20700 &two_byte_p);
20701 s->two_byte_p = two_byte_p;
20702 ++s->nchars;
20703 xassert (s->nchars <= end - start);
20704 s->width += glyph->pixel_width;
20705 if (glyph++->padding_p != s->padding_p)
20706 break;
20707 }
20708
20709 s->font = s->face->font;
20710
20711 /* If the specified font could not be loaded, use the frame's font,
20712 but record the fact that we couldn't load it in
20713 S->font_not_found_p so that we can draw rectangles for the
20714 characters of the glyph string. */
20715 if (s->font == NULL || glyph_not_available_p)
20716 {
20717 s->font_not_found_p = 1;
20718 s->font = FRAME_FONT (s->f);
20719 }
20720
20721 /* Adjust base line for subscript/superscript text. */
20722 s->ybase += voffset;
20723
20724 xassert (s->face && s->face->gc);
20725 return glyph - s->row->glyphs[s->area];
20726 }
20727
20728
20729 /* Fill glyph string S from image glyph S->first_glyph. */
20730
20731 static void
20732 fill_image_glyph_string (s)
20733 struct glyph_string *s;
20734 {
20735 xassert (s->first_glyph->type == IMAGE_GLYPH);
20736 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20737 xassert (s->img);
20738 s->slice = s->first_glyph->slice;
20739 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20740 s->font = s->face->font;
20741 s->width = s->first_glyph->pixel_width;
20742
20743 /* Adjust base line for subscript/superscript text. */
20744 s->ybase += s->first_glyph->voffset;
20745 }
20746
20747
20748 /* Fill glyph string S from a sequence of stretch glyphs.
20749
20750 ROW is the glyph row in which the glyphs are found, AREA is the
20751 area within the row. START is the index of the first glyph to
20752 consider, END is the index of the last + 1.
20753
20754 Value is the index of the first glyph not in S. */
20755
20756 static int
20757 fill_stretch_glyph_string (s, row, area, start, end)
20758 struct glyph_string *s;
20759 struct glyph_row *row;
20760 enum glyph_row_area area;
20761 int start, end;
20762 {
20763 struct glyph *glyph, *last;
20764 int voffset, face_id;
20765
20766 xassert (s->first_glyph->type == STRETCH_GLYPH);
20767
20768 glyph = s->row->glyphs[s->area] + start;
20769 last = s->row->glyphs[s->area] + end;
20770 face_id = glyph->face_id;
20771 s->face = FACE_FROM_ID (s->f, face_id);
20772 s->font = s->face->font;
20773 s->width = glyph->pixel_width;
20774 s->nchars = 1;
20775 voffset = glyph->voffset;
20776
20777 for (++glyph;
20778 (glyph < last
20779 && glyph->type == STRETCH_GLYPH
20780 && glyph->voffset == voffset
20781 && glyph->face_id == face_id);
20782 ++glyph)
20783 s->width += glyph->pixel_width;
20784
20785 /* Adjust base line for subscript/superscript text. */
20786 s->ybase += voffset;
20787
20788 /* The case that face->gc == 0 is handled when drawing the glyph
20789 string by calling PREPARE_FACE_FOR_DISPLAY. */
20790 xassert (s->face);
20791 return glyph - s->row->glyphs[s->area];
20792 }
20793
20794 static struct font_metrics *
20795 get_per_char_metric (f, font, char2b)
20796 struct frame *f;
20797 struct font *font;
20798 XChar2b *char2b;
20799 {
20800 static struct font_metrics metrics;
20801 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20802
20803 if (! font || code == FONT_INVALID_CODE)
20804 return NULL;
20805 font->driver->text_extents (font, &code, 1, &metrics);
20806 return &metrics;
20807 }
20808
20809 /* EXPORT for RIF:
20810 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20811 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20812 assumed to be zero. */
20813
20814 void
20815 x_get_glyph_overhangs (glyph, f, left, right)
20816 struct glyph *glyph;
20817 struct frame *f;
20818 int *left, *right;
20819 {
20820 *left = *right = 0;
20821
20822 if (glyph->type == CHAR_GLYPH)
20823 {
20824 struct face *face;
20825 XChar2b char2b;
20826 struct font_metrics *pcm;
20827
20828 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20829 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
20830 {
20831 if (pcm->rbearing > pcm->width)
20832 *right = pcm->rbearing - pcm->width;
20833 if (pcm->lbearing < 0)
20834 *left = -pcm->lbearing;
20835 }
20836 }
20837 else if (glyph->type == COMPOSITE_GLYPH)
20838 {
20839 if (! glyph->u.cmp.automatic)
20840 {
20841 struct composition *cmp = composition_table[glyph->u.cmp.id];
20842
20843 if (cmp->rbearing > cmp->pixel_width)
20844 *right = cmp->rbearing - cmp->pixel_width;
20845 if (cmp->lbearing < 0)
20846 *left = - cmp->lbearing;
20847 }
20848 else
20849 {
20850 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
20851 struct font_metrics metrics;
20852
20853 composition_gstring_width (gstring, glyph->u.cmp.from,
20854 glyph->u.cmp.to + 1, &metrics);
20855 if (metrics.rbearing > metrics.width)
20856 *right = metrics.rbearing - metrics.width;
20857 if (metrics.lbearing < 0)
20858 *left = - metrics.lbearing;
20859 }
20860 }
20861 }
20862
20863
20864 /* Return the index of the first glyph preceding glyph string S that
20865 is overwritten by S because of S's left overhang. Value is -1
20866 if no glyphs are overwritten. */
20867
20868 static int
20869 left_overwritten (s)
20870 struct glyph_string *s;
20871 {
20872 int k;
20873
20874 if (s->left_overhang)
20875 {
20876 int x = 0, i;
20877 struct glyph *glyphs = s->row->glyphs[s->area];
20878 int first = s->first_glyph - glyphs;
20879
20880 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
20881 x -= glyphs[i].pixel_width;
20882
20883 k = i + 1;
20884 }
20885 else
20886 k = -1;
20887
20888 return k;
20889 }
20890
20891
20892 /* Return the index of the first glyph preceding glyph string S that
20893 is overwriting S because of its right overhang. Value is -1 if no
20894 glyph in front of S overwrites S. */
20895
20896 static int
20897 left_overwriting (s)
20898 struct glyph_string *s;
20899 {
20900 int i, k, x;
20901 struct glyph *glyphs = s->row->glyphs[s->area];
20902 int first = s->first_glyph - glyphs;
20903
20904 k = -1;
20905 x = 0;
20906 for (i = first - 1; i >= 0; --i)
20907 {
20908 int left, right;
20909 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20910 if (x + right > 0)
20911 k = i;
20912 x -= glyphs[i].pixel_width;
20913 }
20914
20915 return k;
20916 }
20917
20918
20919 /* Return the index of the last glyph following glyph string S that is
20920 overwritten by S because of S's right overhang. Value is -1 if
20921 no such glyph is found. */
20922
20923 static int
20924 right_overwritten (s)
20925 struct glyph_string *s;
20926 {
20927 int k = -1;
20928
20929 if (s->right_overhang)
20930 {
20931 int x = 0, i;
20932 struct glyph *glyphs = s->row->glyphs[s->area];
20933 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20934 int end = s->row->used[s->area];
20935
20936 for (i = first; i < end && s->right_overhang > x; ++i)
20937 x += glyphs[i].pixel_width;
20938
20939 k = i;
20940 }
20941
20942 return k;
20943 }
20944
20945
20946 /* Return the index of the last glyph following glyph string S that
20947 overwrites S because of its left overhang. Value is negative
20948 if no such glyph is found. */
20949
20950 static int
20951 right_overwriting (s)
20952 struct glyph_string *s;
20953 {
20954 int i, k, x;
20955 int end = s->row->used[s->area];
20956 struct glyph *glyphs = s->row->glyphs[s->area];
20957 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20958
20959 k = -1;
20960 x = 0;
20961 for (i = first; i < end; ++i)
20962 {
20963 int left, right;
20964 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20965 if (x - left < 0)
20966 k = i;
20967 x += glyphs[i].pixel_width;
20968 }
20969
20970 return k;
20971 }
20972
20973
20974 /* Set background width of glyph string S. START is the index of the
20975 first glyph following S. LAST_X is the right-most x-position + 1
20976 in the drawing area. */
20977
20978 static INLINE void
20979 set_glyph_string_background_width (s, start, last_x)
20980 struct glyph_string *s;
20981 int start;
20982 int last_x;
20983 {
20984 /* If the face of this glyph string has to be drawn to the end of
20985 the drawing area, set S->extends_to_end_of_line_p. */
20986
20987 if (start == s->row->used[s->area]
20988 && s->area == TEXT_AREA
20989 && ((s->row->fill_line_p
20990 && (s->hl == DRAW_NORMAL_TEXT
20991 || s->hl == DRAW_IMAGE_RAISED
20992 || s->hl == DRAW_IMAGE_SUNKEN))
20993 || s->hl == DRAW_MOUSE_FACE))
20994 s->extends_to_end_of_line_p = 1;
20995
20996 /* If S extends its face to the end of the line, set its
20997 background_width to the distance to the right edge of the drawing
20998 area. */
20999 if (s->extends_to_end_of_line_p)
21000 s->background_width = last_x - s->x + 1;
21001 else
21002 s->background_width = s->width;
21003 }
21004
21005
21006 /* Compute overhangs and x-positions for glyph string S and its
21007 predecessors, or successors. X is the starting x-position for S.
21008 BACKWARD_P non-zero means process predecessors. */
21009
21010 static void
21011 compute_overhangs_and_x (s, x, backward_p)
21012 struct glyph_string *s;
21013 int x;
21014 int backward_p;
21015 {
21016 if (backward_p)
21017 {
21018 while (s)
21019 {
21020 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21021 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21022 x -= s->width;
21023 s->x = x;
21024 s = s->prev;
21025 }
21026 }
21027 else
21028 {
21029 while (s)
21030 {
21031 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21032 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21033 s->x = x;
21034 x += s->width;
21035 s = s->next;
21036 }
21037 }
21038 }
21039
21040
21041
21042 /* The following macros are only called from draw_glyphs below.
21043 They reference the following parameters of that function directly:
21044 `w', `row', `area', and `overlap_p'
21045 as well as the following local variables:
21046 `s', `f', and `hdc' (in W32) */
21047
21048 #ifdef HAVE_NTGUI
21049 /* On W32, silently add local `hdc' variable to argument list of
21050 init_glyph_string. */
21051 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21052 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
21053 #else
21054 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21055 init_glyph_string (s, char2b, w, row, area, start, hl)
21056 #endif
21057
21058 /* Add a glyph string for a stretch glyph to the list of strings
21059 between HEAD and TAIL. START is the index of the stretch glyph in
21060 row area AREA of glyph row ROW. END is the index of the last glyph
21061 in that glyph row area. X is the current output position assigned
21062 to the new glyph string constructed. HL overrides that face of the
21063 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21064 is the right-most x-position of the drawing area. */
21065
21066 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21067 and below -- keep them on one line. */
21068 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21069 do \
21070 { \
21071 s = (struct glyph_string *) alloca (sizeof *s); \
21072 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21073 START = fill_stretch_glyph_string (s, row, area, START, END); \
21074 append_glyph_string (&HEAD, &TAIL, s); \
21075 s->x = (X); \
21076 } \
21077 while (0)
21078
21079
21080 /* Add a glyph string for an image glyph to the list of strings
21081 between HEAD and TAIL. START is the index of the image glyph in
21082 row area AREA of glyph row ROW. END is the index of the last glyph
21083 in that glyph row area. X is the current output position assigned
21084 to the new glyph string constructed. HL overrides that face of the
21085 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21086 is the right-most x-position of the drawing area. */
21087
21088 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21089 do \
21090 { \
21091 s = (struct glyph_string *) alloca (sizeof *s); \
21092 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21093 fill_image_glyph_string (s); \
21094 append_glyph_string (&HEAD, &TAIL, s); \
21095 ++START; \
21096 s->x = (X); \
21097 } \
21098 while (0)
21099
21100
21101 /* Add a glyph string for a sequence of character glyphs to the list
21102 of strings between HEAD and TAIL. START is the index of the first
21103 glyph in row area AREA of glyph row ROW that is part of the new
21104 glyph string. END is the index of the last glyph in that glyph row
21105 area. X is the current output position assigned to the new glyph
21106 string constructed. HL overrides that face of the glyph; e.g. it
21107 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21108 right-most x-position of the drawing area. */
21109
21110 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21111 do \
21112 { \
21113 int face_id; \
21114 XChar2b *char2b; \
21115 \
21116 face_id = (row)->glyphs[area][START].face_id; \
21117 \
21118 s = (struct glyph_string *) alloca (sizeof *s); \
21119 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21120 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21121 append_glyph_string (&HEAD, &TAIL, s); \
21122 s->x = (X); \
21123 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21124 } \
21125 while (0)
21126
21127
21128 /* Add a glyph string for a composite sequence to the list of strings
21129 between HEAD and TAIL. START is the index of the first glyph in
21130 row area AREA of glyph row ROW that is part of the new glyph
21131 string. END is the index of the last glyph in that glyph row area.
21132 X is the current output position assigned to the new glyph string
21133 constructed. HL overrides that face of the glyph; e.g. it is
21134 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21135 x-position of the drawing area. */
21136
21137 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21138 do { \
21139 int face_id = (row)->glyphs[area][START].face_id; \
21140 struct face *base_face = FACE_FROM_ID (f, face_id); \
21141 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21142 struct composition *cmp = composition_table[cmp_id]; \
21143 XChar2b *char2b; \
21144 struct glyph_string *first_s; \
21145 int n; \
21146 \
21147 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21148 \
21149 /* Make glyph_strings for each glyph sequence that is drawable by \
21150 the same face, and append them to HEAD/TAIL. */ \
21151 for (n = 0; n < cmp->glyph_len;) \
21152 { \
21153 s = (struct glyph_string *) alloca (sizeof *s); \
21154 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21155 append_glyph_string (&(HEAD), &(TAIL), s); \
21156 s->cmp = cmp; \
21157 s->cmp_from = n; \
21158 s->x = (X); \
21159 if (n == 0) \
21160 first_s = s; \
21161 n = fill_composite_glyph_string (s, base_face, overlaps); \
21162 } \
21163 \
21164 ++START; \
21165 s = first_s; \
21166 } while (0)
21167
21168
21169 /* Add a glyph string for a glyph-string sequence to the list of strings
21170 between HEAD and TAIL. */
21171
21172 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21173 do { \
21174 int face_id; \
21175 XChar2b *char2b; \
21176 Lisp_Object gstring; \
21177 \
21178 face_id = (row)->glyphs[area][START].face_id; \
21179 gstring = (composition_gstring_from_id \
21180 ((row)->glyphs[area][START].u.cmp.id)); \
21181 s = (struct glyph_string *) alloca (sizeof *s); \
21182 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21183 * LGSTRING_GLYPH_LEN (gstring)); \
21184 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21185 append_glyph_string (&(HEAD), &(TAIL), s); \
21186 s->x = (X); \
21187 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21188 } while (0)
21189
21190
21191 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21192 of AREA of glyph row ROW on window W between indices START and END.
21193 HL overrides the face for drawing glyph strings, e.g. it is
21194 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21195 x-positions of the drawing area.
21196
21197 This is an ugly monster macro construct because we must use alloca
21198 to allocate glyph strings (because draw_glyphs can be called
21199 asynchronously). */
21200
21201 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21202 do \
21203 { \
21204 HEAD = TAIL = NULL; \
21205 while (START < END) \
21206 { \
21207 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21208 switch (first_glyph->type) \
21209 { \
21210 case CHAR_GLYPH: \
21211 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21212 HL, X, LAST_X); \
21213 break; \
21214 \
21215 case COMPOSITE_GLYPH: \
21216 if (first_glyph->u.cmp.automatic) \
21217 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21218 HL, X, LAST_X); \
21219 else \
21220 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21221 HL, X, LAST_X); \
21222 break; \
21223 \
21224 case STRETCH_GLYPH: \
21225 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21226 HL, X, LAST_X); \
21227 break; \
21228 \
21229 case IMAGE_GLYPH: \
21230 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21231 HL, X, LAST_X); \
21232 break; \
21233 \
21234 default: \
21235 abort (); \
21236 } \
21237 \
21238 if (s) \
21239 { \
21240 set_glyph_string_background_width (s, START, LAST_X); \
21241 (X) += s->width; \
21242 } \
21243 } \
21244 } while (0)
21245
21246
21247 /* Draw glyphs between START and END in AREA of ROW on window W,
21248 starting at x-position X. X is relative to AREA in W. HL is a
21249 face-override with the following meaning:
21250
21251 DRAW_NORMAL_TEXT draw normally
21252 DRAW_CURSOR draw in cursor face
21253 DRAW_MOUSE_FACE draw in mouse face.
21254 DRAW_INVERSE_VIDEO draw in mode line face
21255 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21256 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21257
21258 If OVERLAPS is non-zero, draw only the foreground of characters and
21259 clip to the physical height of ROW. Non-zero value also defines
21260 the overlapping part to be drawn:
21261
21262 OVERLAPS_PRED overlap with preceding rows
21263 OVERLAPS_SUCC overlap with succeeding rows
21264 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21265 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21266
21267 Value is the x-position reached, relative to AREA of W. */
21268
21269 static int
21270 draw_glyphs (w, x, row, area, start, end, hl, overlaps)
21271 struct window *w;
21272 int x;
21273 struct glyph_row *row;
21274 enum glyph_row_area area;
21275 EMACS_INT start, end;
21276 enum draw_glyphs_face hl;
21277 int overlaps;
21278 {
21279 struct glyph_string *head, *tail;
21280 struct glyph_string *s;
21281 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21282 int i, j, x_reached, last_x, area_left = 0;
21283 struct frame *f = XFRAME (WINDOW_FRAME (w));
21284 DECLARE_HDC (hdc);
21285
21286 ALLOCATE_HDC (hdc, f);
21287
21288 /* Let's rather be paranoid than getting a SEGV. */
21289 end = min (end, row->used[area]);
21290 start = max (0, start);
21291 start = min (end, start);
21292
21293 /* Translate X to frame coordinates. Set last_x to the right
21294 end of the drawing area. */
21295 if (row->full_width_p)
21296 {
21297 /* X is relative to the left edge of W, without scroll bars
21298 or fringes. */
21299 area_left = WINDOW_LEFT_EDGE_X (w);
21300 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21301 }
21302 else
21303 {
21304 area_left = window_box_left (w, area);
21305 last_x = area_left + window_box_width (w, area);
21306 }
21307 x += area_left;
21308
21309 /* Build a doubly-linked list of glyph_string structures between
21310 head and tail from what we have to draw. Note that the macro
21311 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21312 the reason we use a separate variable `i'. */
21313 i = start;
21314 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21315 if (tail)
21316 x_reached = tail->x + tail->background_width;
21317 else
21318 x_reached = x;
21319
21320 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21321 the row, redraw some glyphs in front or following the glyph
21322 strings built above. */
21323 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21324 {
21325 struct glyph_string *h, *t;
21326 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21327 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
21328 int dummy_x = 0;
21329
21330 /* If mouse highlighting is on, we may need to draw adjacent
21331 glyphs using mouse-face highlighting. */
21332 if (area == TEXT_AREA && row->mouse_face_p)
21333 {
21334 struct glyph_row *mouse_beg_row, *mouse_end_row;
21335
21336 mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21337 mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21338
21339 if (row >= mouse_beg_row && row <= mouse_end_row)
21340 {
21341 check_mouse_face = 1;
21342 mouse_beg_col = (row == mouse_beg_row)
21343 ? dpyinfo->mouse_face_beg_col : 0;
21344 mouse_end_col = (row == mouse_end_row)
21345 ? dpyinfo->mouse_face_end_col
21346 : row->used[TEXT_AREA];
21347 }
21348 }
21349
21350 /* Compute overhangs for all glyph strings. */
21351 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21352 for (s = head; s; s = s->next)
21353 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21354
21355 /* Prepend glyph strings for glyphs in front of the first glyph
21356 string that are overwritten because of the first glyph
21357 string's left overhang. The background of all strings
21358 prepended must be drawn because the first glyph string
21359 draws over it. */
21360 i = left_overwritten (head);
21361 if (i >= 0)
21362 {
21363 enum draw_glyphs_face overlap_hl;
21364
21365 /* If this row contains mouse highlighting, attempt to draw
21366 the overlapped glyphs with the correct highlight. This
21367 code fails if the overlap encompasses more than one glyph
21368 and mouse-highlight spans only some of these glyphs.
21369 However, making it work perfectly involves a lot more
21370 code, and I don't know if the pathological case occurs in
21371 practice, so we'll stick to this for now. --- cyd */
21372 if (check_mouse_face
21373 && mouse_beg_col < start && mouse_end_col > i)
21374 overlap_hl = DRAW_MOUSE_FACE;
21375 else
21376 overlap_hl = DRAW_NORMAL_TEXT;
21377
21378 j = i;
21379 BUILD_GLYPH_STRINGS (j, start, h, t,
21380 overlap_hl, dummy_x, last_x);
21381 start = i;
21382 compute_overhangs_and_x (t, head->x, 1);
21383 prepend_glyph_string_lists (&head, &tail, h, t);
21384 clip_head = head;
21385 }
21386
21387 /* Prepend glyph strings for glyphs in front of the first glyph
21388 string that overwrite that glyph string because of their
21389 right overhang. For these strings, only the foreground must
21390 be drawn, because it draws over the glyph string at `head'.
21391 The background must not be drawn because this would overwrite
21392 right overhangs of preceding glyphs for which no glyph
21393 strings exist. */
21394 i = left_overwriting (head);
21395 if (i >= 0)
21396 {
21397 enum draw_glyphs_face overlap_hl;
21398
21399 if (check_mouse_face
21400 && mouse_beg_col < start && mouse_end_col > i)
21401 overlap_hl = DRAW_MOUSE_FACE;
21402 else
21403 overlap_hl = DRAW_NORMAL_TEXT;
21404
21405 clip_head = head;
21406 BUILD_GLYPH_STRINGS (i, start, h, t,
21407 overlap_hl, dummy_x, last_x);
21408 for (s = h; s; s = s->next)
21409 s->background_filled_p = 1;
21410 compute_overhangs_and_x (t, head->x, 1);
21411 prepend_glyph_string_lists (&head, &tail, h, t);
21412 }
21413
21414 /* Append glyphs strings for glyphs following the last glyph
21415 string tail that are overwritten by tail. The background of
21416 these strings has to be drawn because tail's foreground draws
21417 over it. */
21418 i = right_overwritten (tail);
21419 if (i >= 0)
21420 {
21421 enum draw_glyphs_face overlap_hl;
21422
21423 if (check_mouse_face
21424 && mouse_beg_col < i && mouse_end_col > end)
21425 overlap_hl = DRAW_MOUSE_FACE;
21426 else
21427 overlap_hl = DRAW_NORMAL_TEXT;
21428
21429 BUILD_GLYPH_STRINGS (end, i, h, t,
21430 overlap_hl, x, last_x);
21431 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21432 we don't have `end = i;' here. */
21433 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21434 append_glyph_string_lists (&head, &tail, h, t);
21435 clip_tail = tail;
21436 }
21437
21438 /* Append glyph strings for glyphs following the last glyph
21439 string tail that overwrite tail. The foreground of such
21440 glyphs has to be drawn because it writes into the background
21441 of tail. The background must not be drawn because it could
21442 paint over the foreground of following glyphs. */
21443 i = right_overwriting (tail);
21444 if (i >= 0)
21445 {
21446 enum draw_glyphs_face overlap_hl;
21447 if (check_mouse_face
21448 && mouse_beg_col < i && mouse_end_col > end)
21449 overlap_hl = DRAW_MOUSE_FACE;
21450 else
21451 overlap_hl = DRAW_NORMAL_TEXT;
21452
21453 clip_tail = tail;
21454 i++; /* We must include the Ith glyph. */
21455 BUILD_GLYPH_STRINGS (end, i, h, t,
21456 overlap_hl, x, last_x);
21457 for (s = h; s; s = s->next)
21458 s->background_filled_p = 1;
21459 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21460 append_glyph_string_lists (&head, &tail, h, t);
21461 }
21462 if (clip_head || clip_tail)
21463 for (s = head; s; s = s->next)
21464 {
21465 s->clip_head = clip_head;
21466 s->clip_tail = clip_tail;
21467 }
21468 }
21469
21470 /* Draw all strings. */
21471 for (s = head; s; s = s->next)
21472 FRAME_RIF (f)->draw_glyph_string (s);
21473
21474 #ifndef HAVE_NS
21475 /* When focus a sole frame and move horizontally, this sets on_p to 0
21476 causing a failure to erase prev cursor position. */
21477 if (area == TEXT_AREA
21478 && !row->full_width_p
21479 /* When drawing overlapping rows, only the glyph strings'
21480 foreground is drawn, which doesn't erase a cursor
21481 completely. */
21482 && !overlaps)
21483 {
21484 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21485 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21486 : (tail ? tail->x + tail->background_width : x));
21487 x0 -= area_left;
21488 x1 -= area_left;
21489
21490 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21491 row->y, MATRIX_ROW_BOTTOM_Y (row));
21492 }
21493 #endif
21494
21495 /* Value is the x-position up to which drawn, relative to AREA of W.
21496 This doesn't include parts drawn because of overhangs. */
21497 if (row->full_width_p)
21498 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21499 else
21500 x_reached -= area_left;
21501
21502 RELEASE_HDC (hdc, f);
21503
21504 return x_reached;
21505 }
21506
21507 /* Expand row matrix if too narrow. Don't expand if area
21508 is not present. */
21509
21510 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21511 { \
21512 if (!fonts_changed_p \
21513 && (it->glyph_row->glyphs[area] \
21514 < it->glyph_row->glyphs[area + 1])) \
21515 { \
21516 it->w->ncols_scale_factor++; \
21517 fonts_changed_p = 1; \
21518 } \
21519 }
21520
21521 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21522 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21523
21524 static INLINE void
21525 append_glyph (it)
21526 struct it *it;
21527 {
21528 struct glyph *glyph;
21529 enum glyph_row_area area = it->area;
21530
21531 xassert (it->glyph_row);
21532 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21533
21534 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21535 if (glyph < it->glyph_row->glyphs[area + 1])
21536 {
21537 /* If the glyph row is reversed, we need to prepend the glyph
21538 rather than append it. */
21539 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21540 {
21541 struct glyph *g;
21542
21543 /* Make room for the additional glyph. */
21544 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21545 g[1] = *g;
21546 glyph = it->glyph_row->glyphs[area];
21547 }
21548 glyph->charpos = CHARPOS (it->position);
21549 glyph->object = it->object;
21550 if (it->pixel_width > 0)
21551 {
21552 glyph->pixel_width = it->pixel_width;
21553 glyph->padding_p = 0;
21554 }
21555 else
21556 {
21557 /* Assure at least 1-pixel width. Otherwise, cursor can't
21558 be displayed correctly. */
21559 glyph->pixel_width = 1;
21560 glyph->padding_p = 1;
21561 }
21562 glyph->ascent = it->ascent;
21563 glyph->descent = it->descent;
21564 glyph->voffset = it->voffset;
21565 glyph->type = CHAR_GLYPH;
21566 glyph->avoid_cursor_p = it->avoid_cursor_p;
21567 glyph->multibyte_p = it->multibyte_p;
21568 glyph->left_box_line_p = it->start_of_box_run_p;
21569 glyph->right_box_line_p = it->end_of_box_run_p;
21570 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21571 || it->phys_descent > it->descent);
21572 glyph->glyph_not_available_p = it->glyph_not_available_p;
21573 glyph->face_id = it->face_id;
21574 glyph->u.ch = it->char_to_display;
21575 glyph->slice = null_glyph_slice;
21576 glyph->font_type = FONT_TYPE_UNKNOWN;
21577 if (it->bidi_p)
21578 {
21579 glyph->resolved_level = it->bidi_it.resolved_level;
21580 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21581 abort ();
21582 glyph->bidi_type = it->bidi_it.type;
21583 }
21584 else
21585 {
21586 glyph->resolved_level = 0;
21587 glyph->bidi_type = UNKNOWN_BT;
21588 }
21589 ++it->glyph_row->used[area];
21590 }
21591 else
21592 IT_EXPAND_MATRIX_WIDTH (it, area);
21593 }
21594
21595 /* Store one glyph for the composition IT->cmp_it.id in
21596 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21597 non-null. */
21598
21599 static INLINE void
21600 append_composite_glyph (it)
21601 struct it *it;
21602 {
21603 struct glyph *glyph;
21604 enum glyph_row_area area = it->area;
21605
21606 xassert (it->glyph_row);
21607
21608 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21609 if (glyph < it->glyph_row->glyphs[area + 1])
21610 {
21611 /* If the glyph row is reversed, we need to prepend the glyph
21612 rather than append it. */
21613 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21614 {
21615 struct glyph *g;
21616
21617 /* Make room for the new glyph. */
21618 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21619 g[1] = *g;
21620 glyph = it->glyph_row->glyphs[it->area];
21621 }
21622 glyph->charpos = CHARPOS (it->position);
21623 glyph->object = it->object;
21624 glyph->pixel_width = it->pixel_width;
21625 glyph->ascent = it->ascent;
21626 glyph->descent = it->descent;
21627 glyph->voffset = it->voffset;
21628 glyph->type = COMPOSITE_GLYPH;
21629 if (it->cmp_it.ch < 0)
21630 {
21631 glyph->u.cmp.automatic = 0;
21632 glyph->u.cmp.id = it->cmp_it.id;
21633 }
21634 else
21635 {
21636 glyph->u.cmp.automatic = 1;
21637 glyph->u.cmp.id = it->cmp_it.id;
21638 glyph->u.cmp.from = it->cmp_it.from;
21639 glyph->u.cmp.to = it->cmp_it.to - 1;
21640 }
21641 glyph->avoid_cursor_p = it->avoid_cursor_p;
21642 glyph->multibyte_p = it->multibyte_p;
21643 glyph->left_box_line_p = it->start_of_box_run_p;
21644 glyph->right_box_line_p = it->end_of_box_run_p;
21645 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21646 || it->phys_descent > it->descent);
21647 glyph->padding_p = 0;
21648 glyph->glyph_not_available_p = 0;
21649 glyph->face_id = it->face_id;
21650 glyph->slice = null_glyph_slice;
21651 glyph->font_type = FONT_TYPE_UNKNOWN;
21652 if (it->bidi_p)
21653 {
21654 glyph->resolved_level = it->bidi_it.resolved_level;
21655 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21656 abort ();
21657 glyph->bidi_type = it->bidi_it.type;
21658 }
21659 ++it->glyph_row->used[area];
21660 }
21661 else
21662 IT_EXPAND_MATRIX_WIDTH (it, area);
21663 }
21664
21665
21666 /* Change IT->ascent and IT->height according to the setting of
21667 IT->voffset. */
21668
21669 static INLINE void
21670 take_vertical_position_into_account (it)
21671 struct it *it;
21672 {
21673 if (it->voffset)
21674 {
21675 if (it->voffset < 0)
21676 /* Increase the ascent so that we can display the text higher
21677 in the line. */
21678 it->ascent -= it->voffset;
21679 else
21680 /* Increase the descent so that we can display the text lower
21681 in the line. */
21682 it->descent += it->voffset;
21683 }
21684 }
21685
21686
21687 /* Produce glyphs/get display metrics for the image IT is loaded with.
21688 See the description of struct display_iterator in dispextern.h for
21689 an overview of struct display_iterator. */
21690
21691 static void
21692 produce_image_glyph (it)
21693 struct it *it;
21694 {
21695 struct image *img;
21696 struct face *face;
21697 int glyph_ascent, crop;
21698 struct glyph_slice slice;
21699
21700 xassert (it->what == IT_IMAGE);
21701
21702 face = FACE_FROM_ID (it->f, it->face_id);
21703 xassert (face);
21704 /* Make sure X resources of the face is loaded. */
21705 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21706
21707 if (it->image_id < 0)
21708 {
21709 /* Fringe bitmap. */
21710 it->ascent = it->phys_ascent = 0;
21711 it->descent = it->phys_descent = 0;
21712 it->pixel_width = 0;
21713 it->nglyphs = 0;
21714 return;
21715 }
21716
21717 img = IMAGE_FROM_ID (it->f, it->image_id);
21718 xassert (img);
21719 /* Make sure X resources of the image is loaded. */
21720 prepare_image_for_display (it->f, img);
21721
21722 slice.x = slice.y = 0;
21723 slice.width = img->width;
21724 slice.height = img->height;
21725
21726 if (INTEGERP (it->slice.x))
21727 slice.x = XINT (it->slice.x);
21728 else if (FLOATP (it->slice.x))
21729 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21730
21731 if (INTEGERP (it->slice.y))
21732 slice.y = XINT (it->slice.y);
21733 else if (FLOATP (it->slice.y))
21734 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21735
21736 if (INTEGERP (it->slice.width))
21737 slice.width = XINT (it->slice.width);
21738 else if (FLOATP (it->slice.width))
21739 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21740
21741 if (INTEGERP (it->slice.height))
21742 slice.height = XINT (it->slice.height);
21743 else if (FLOATP (it->slice.height))
21744 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21745
21746 if (slice.x >= img->width)
21747 slice.x = img->width;
21748 if (slice.y >= img->height)
21749 slice.y = img->height;
21750 if (slice.x + slice.width >= img->width)
21751 slice.width = img->width - slice.x;
21752 if (slice.y + slice.height > img->height)
21753 slice.height = img->height - slice.y;
21754
21755 if (slice.width == 0 || slice.height == 0)
21756 return;
21757
21758 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21759
21760 it->descent = slice.height - glyph_ascent;
21761 if (slice.y == 0)
21762 it->descent += img->vmargin;
21763 if (slice.y + slice.height == img->height)
21764 it->descent += img->vmargin;
21765 it->phys_descent = it->descent;
21766
21767 it->pixel_width = slice.width;
21768 if (slice.x == 0)
21769 it->pixel_width += img->hmargin;
21770 if (slice.x + slice.width == img->width)
21771 it->pixel_width += img->hmargin;
21772
21773 /* It's quite possible for images to have an ascent greater than
21774 their height, so don't get confused in that case. */
21775 if (it->descent < 0)
21776 it->descent = 0;
21777
21778 it->nglyphs = 1;
21779
21780 if (face->box != FACE_NO_BOX)
21781 {
21782 if (face->box_line_width > 0)
21783 {
21784 if (slice.y == 0)
21785 it->ascent += face->box_line_width;
21786 if (slice.y + slice.height == img->height)
21787 it->descent += face->box_line_width;
21788 }
21789
21790 if (it->start_of_box_run_p && slice.x == 0)
21791 it->pixel_width += eabs (face->box_line_width);
21792 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21793 it->pixel_width += eabs (face->box_line_width);
21794 }
21795
21796 take_vertical_position_into_account (it);
21797
21798 /* Automatically crop wide image glyphs at right edge so we can
21799 draw the cursor on same display row. */
21800 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21801 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21802 {
21803 it->pixel_width -= crop;
21804 slice.width -= crop;
21805 }
21806
21807 if (it->glyph_row)
21808 {
21809 struct glyph *glyph;
21810 enum glyph_row_area area = it->area;
21811
21812 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21813 if (glyph < it->glyph_row->glyphs[area + 1])
21814 {
21815 glyph->charpos = CHARPOS (it->position);
21816 glyph->object = it->object;
21817 glyph->pixel_width = it->pixel_width;
21818 glyph->ascent = glyph_ascent;
21819 glyph->descent = it->descent;
21820 glyph->voffset = it->voffset;
21821 glyph->type = IMAGE_GLYPH;
21822 glyph->avoid_cursor_p = it->avoid_cursor_p;
21823 glyph->multibyte_p = it->multibyte_p;
21824 glyph->left_box_line_p = it->start_of_box_run_p;
21825 glyph->right_box_line_p = it->end_of_box_run_p;
21826 glyph->overlaps_vertically_p = 0;
21827 glyph->padding_p = 0;
21828 glyph->glyph_not_available_p = 0;
21829 glyph->face_id = it->face_id;
21830 glyph->u.img_id = img->id;
21831 glyph->slice = slice;
21832 glyph->font_type = FONT_TYPE_UNKNOWN;
21833 if (it->bidi_p)
21834 {
21835 glyph->resolved_level = it->bidi_it.resolved_level;
21836 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21837 abort ();
21838 glyph->bidi_type = it->bidi_it.type;
21839 }
21840 ++it->glyph_row->used[area];
21841 }
21842 else
21843 IT_EXPAND_MATRIX_WIDTH (it, area);
21844 }
21845 }
21846
21847
21848 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21849 of the glyph, WIDTH and HEIGHT are the width and height of the
21850 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
21851
21852 static void
21853 append_stretch_glyph (it, object, width, height, ascent)
21854 struct it *it;
21855 Lisp_Object object;
21856 int width, height;
21857 int ascent;
21858 {
21859 struct glyph *glyph;
21860 enum glyph_row_area area = it->area;
21861
21862 xassert (ascent >= 0 && ascent <= height);
21863
21864 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21865 if (glyph < it->glyph_row->glyphs[area + 1])
21866 {
21867 /* If the glyph row is reversed, we need to prepend the glyph
21868 rather than append it. */
21869 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21870 {
21871 struct glyph *g;
21872
21873 /* Make room for the additional glyph. */
21874 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21875 g[1] = *g;
21876 glyph = it->glyph_row->glyphs[area];
21877 }
21878 glyph->charpos = CHARPOS (it->position);
21879 glyph->object = object;
21880 glyph->pixel_width = width;
21881 glyph->ascent = ascent;
21882 glyph->descent = height - ascent;
21883 glyph->voffset = it->voffset;
21884 glyph->type = STRETCH_GLYPH;
21885 glyph->avoid_cursor_p = it->avoid_cursor_p;
21886 glyph->multibyte_p = it->multibyte_p;
21887 glyph->left_box_line_p = it->start_of_box_run_p;
21888 glyph->right_box_line_p = it->end_of_box_run_p;
21889 glyph->overlaps_vertically_p = 0;
21890 glyph->padding_p = 0;
21891 glyph->glyph_not_available_p = 0;
21892 glyph->face_id = it->face_id;
21893 glyph->u.stretch.ascent = ascent;
21894 glyph->u.stretch.height = height;
21895 glyph->slice = null_glyph_slice;
21896 glyph->font_type = FONT_TYPE_UNKNOWN;
21897 if (it->bidi_p)
21898 {
21899 glyph->resolved_level = it->bidi_it.resolved_level;
21900 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21901 abort ();
21902 glyph->bidi_type = it->bidi_it.type;
21903 }
21904 else
21905 {
21906 glyph->resolved_level = 0;
21907 glyph->bidi_type = UNKNOWN_BT;
21908 }
21909 ++it->glyph_row->used[area];
21910 }
21911 else
21912 IT_EXPAND_MATRIX_WIDTH (it, area);
21913 }
21914
21915
21916 /* Produce a stretch glyph for iterator IT. IT->object is the value
21917 of the glyph property displayed. The value must be a list
21918 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
21919 being recognized:
21920
21921 1. `:width WIDTH' specifies that the space should be WIDTH *
21922 canonical char width wide. WIDTH may be an integer or floating
21923 point number.
21924
21925 2. `:relative-width FACTOR' specifies that the width of the stretch
21926 should be computed from the width of the first character having the
21927 `glyph' property, and should be FACTOR times that width.
21928
21929 3. `:align-to HPOS' specifies that the space should be wide enough
21930 to reach HPOS, a value in canonical character units.
21931
21932 Exactly one of the above pairs must be present.
21933
21934 4. `:height HEIGHT' specifies that the height of the stretch produced
21935 should be HEIGHT, measured in canonical character units.
21936
21937 5. `:relative-height FACTOR' specifies that the height of the
21938 stretch should be FACTOR times the height of the characters having
21939 the glyph property.
21940
21941 Either none or exactly one of 4 or 5 must be present.
21942
21943 6. `:ascent ASCENT' specifies that ASCENT percent of the height
21944 of the stretch should be used for the ascent of the stretch.
21945 ASCENT must be in the range 0 <= ASCENT <= 100. */
21946
21947 static void
21948 produce_stretch_glyph (it)
21949 struct it *it;
21950 {
21951 /* (space :width WIDTH :height HEIGHT ...) */
21952 Lisp_Object prop, plist;
21953 int width = 0, height = 0, align_to = -1;
21954 int zero_width_ok_p = 0, zero_height_ok_p = 0;
21955 int ascent = 0;
21956 double tem;
21957 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21958 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
21959
21960 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21961
21962 /* List should start with `space'. */
21963 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
21964 plist = XCDR (it->object);
21965
21966 /* Compute the width of the stretch. */
21967 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
21968 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
21969 {
21970 /* Absolute width `:width WIDTH' specified and valid. */
21971 zero_width_ok_p = 1;
21972 width = (int)tem;
21973 }
21974 else if (prop = Fplist_get (plist, QCrelative_width),
21975 NUMVAL (prop) > 0)
21976 {
21977 /* Relative width `:relative-width FACTOR' specified and valid.
21978 Compute the width of the characters having the `glyph'
21979 property. */
21980 struct it it2;
21981 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
21982
21983 it2 = *it;
21984 if (it->multibyte_p)
21985 {
21986 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
21987 - IT_BYTEPOS (*it));
21988 it2.c = STRING_CHAR_AND_LENGTH (p, it2.len);
21989 }
21990 else
21991 it2.c = *p, it2.len = 1;
21992
21993 it2.glyph_row = NULL;
21994 it2.what = IT_CHARACTER;
21995 x_produce_glyphs (&it2);
21996 width = NUMVAL (prop) * it2.pixel_width;
21997 }
21998 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
21999 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
22000 {
22001 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
22002 align_to = (align_to < 0
22003 ? 0
22004 : align_to - window_box_left_offset (it->w, TEXT_AREA));
22005 else if (align_to < 0)
22006 align_to = window_box_left_offset (it->w, TEXT_AREA);
22007 width = max (0, (int)tem + align_to - it->current_x);
22008 zero_width_ok_p = 1;
22009 }
22010 else
22011 /* Nothing specified -> width defaults to canonical char width. */
22012 width = FRAME_COLUMN_WIDTH (it->f);
22013
22014 if (width <= 0 && (width < 0 || !zero_width_ok_p))
22015 width = 1;
22016
22017 /* Compute height. */
22018 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
22019 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22020 {
22021 height = (int)tem;
22022 zero_height_ok_p = 1;
22023 }
22024 else if (prop = Fplist_get (plist, QCrelative_height),
22025 NUMVAL (prop) > 0)
22026 height = FONT_HEIGHT (font) * NUMVAL (prop);
22027 else
22028 height = FONT_HEIGHT (font);
22029
22030 if (height <= 0 && (height < 0 || !zero_height_ok_p))
22031 height = 1;
22032
22033 /* Compute percentage of height used for ascent. If
22034 `:ascent ASCENT' is present and valid, use that. Otherwise,
22035 derive the ascent from the font in use. */
22036 if (prop = Fplist_get (plist, QCascent),
22037 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
22038 ascent = height * NUMVAL (prop) / 100.0;
22039 else if (!NILP (prop)
22040 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22041 ascent = min (max (0, (int)tem), height);
22042 else
22043 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
22044
22045 if (width > 0 && it->line_wrap != TRUNCATE
22046 && it->current_x + width > it->last_visible_x)
22047 width = it->last_visible_x - it->current_x - 1;
22048
22049 if (width > 0 && height > 0 && it->glyph_row)
22050 {
22051 Lisp_Object object = it->stack[it->sp - 1].string;
22052 if (!STRINGP (object))
22053 object = it->w->buffer;
22054 append_stretch_glyph (it, object, width, height, ascent);
22055 }
22056
22057 it->pixel_width = width;
22058 it->ascent = it->phys_ascent = ascent;
22059 it->descent = it->phys_descent = height - it->ascent;
22060 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
22061
22062 take_vertical_position_into_account (it);
22063 }
22064
22065 /* Calculate line-height and line-spacing properties.
22066 An integer value specifies explicit pixel value.
22067 A float value specifies relative value to current face height.
22068 A cons (float . face-name) specifies relative value to
22069 height of specified face font.
22070
22071 Returns height in pixels, or nil. */
22072
22073
22074 static Lisp_Object
22075 calc_line_height_property (it, val, font, boff, override)
22076 struct it *it;
22077 Lisp_Object val;
22078 struct font *font;
22079 int boff, override;
22080 {
22081 Lisp_Object face_name = Qnil;
22082 int ascent, descent, height;
22083
22084 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22085 return val;
22086
22087 if (CONSP (val))
22088 {
22089 face_name = XCAR (val);
22090 val = XCDR (val);
22091 if (!NUMBERP (val))
22092 val = make_number (1);
22093 if (NILP (face_name))
22094 {
22095 height = it->ascent + it->descent;
22096 goto scale;
22097 }
22098 }
22099
22100 if (NILP (face_name))
22101 {
22102 font = FRAME_FONT (it->f);
22103 boff = FRAME_BASELINE_OFFSET (it->f);
22104 }
22105 else if (EQ (face_name, Qt))
22106 {
22107 override = 0;
22108 }
22109 else
22110 {
22111 int face_id;
22112 struct face *face;
22113
22114 face_id = lookup_named_face (it->f, face_name, 0);
22115 if (face_id < 0)
22116 return make_number (-1);
22117
22118 face = FACE_FROM_ID (it->f, face_id);
22119 font = face->font;
22120 if (font == NULL)
22121 return make_number (-1);
22122 boff = font->baseline_offset;
22123 if (font->vertical_centering)
22124 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22125 }
22126
22127 ascent = FONT_BASE (font) + boff;
22128 descent = FONT_DESCENT (font) - boff;
22129
22130 if (override)
22131 {
22132 it->override_ascent = ascent;
22133 it->override_descent = descent;
22134 it->override_boff = boff;
22135 }
22136
22137 height = ascent + descent;
22138
22139 scale:
22140 if (FLOATP (val))
22141 height = (int)(XFLOAT_DATA (val) * height);
22142 else if (INTEGERP (val))
22143 height *= XINT (val);
22144
22145 return make_number (height);
22146 }
22147
22148
22149 /* RIF:
22150 Produce glyphs/get display metrics for the display element IT is
22151 loaded with. See the description of struct it in dispextern.h
22152 for an overview of struct it. */
22153
22154 void
22155 x_produce_glyphs (it)
22156 struct it *it;
22157 {
22158 int extra_line_spacing = it->extra_line_spacing;
22159
22160 it->glyph_not_available_p = 0;
22161
22162 if (it->what == IT_CHARACTER)
22163 {
22164 XChar2b char2b;
22165 struct font *font;
22166 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22167 struct font_metrics *pcm;
22168 int font_not_found_p;
22169 int boff; /* baseline offset */
22170 /* We may change it->multibyte_p upon unibyte<->multibyte
22171 conversion. So, save the current value now and restore it
22172 later.
22173
22174 Note: It seems that we don't have to record multibyte_p in
22175 struct glyph because the character code itself tells whether
22176 or not the character is multibyte. Thus, in the future, we
22177 must consider eliminating the field `multibyte_p' in the
22178 struct glyph. */
22179 int saved_multibyte_p = it->multibyte_p;
22180
22181 /* Maybe translate single-byte characters to multibyte, or the
22182 other way. */
22183 it->char_to_display = it->c;
22184 if (!ASCII_BYTE_P (it->c)
22185 && ! it->multibyte_p)
22186 {
22187 if (SINGLE_BYTE_CHAR_P (it->c)
22188 && unibyte_display_via_language_environment)
22189 {
22190 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
22191
22192 /* get_next_display_element assures that this decoding
22193 never fails. */
22194 it->char_to_display = DECODE_CHAR (unibyte, it->c);
22195 it->multibyte_p = 1;
22196 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
22197 -1, Qnil);
22198 face = FACE_FROM_ID (it->f, it->face_id);
22199 }
22200 }
22201
22202 /* Get font to use. Encode IT->char_to_display. */
22203 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
22204 &char2b, it->multibyte_p, 0);
22205 font = face->font;
22206
22207 font_not_found_p = font == NULL;
22208 if (font_not_found_p)
22209 {
22210 /* When no suitable font found, display an empty box based
22211 on the metrics of the font of the default face (or what
22212 remapped). */
22213 struct face *no_font_face
22214 = FACE_FROM_ID (it->f,
22215 NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
22216 : lookup_basic_face (it->f, DEFAULT_FACE_ID));
22217 font = no_font_face->font;
22218 boff = font->baseline_offset;
22219 }
22220 else
22221 {
22222 boff = font->baseline_offset;
22223 if (font->vertical_centering)
22224 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22225 }
22226
22227 if (it->char_to_display >= ' '
22228 && (!it->multibyte_p || it->char_to_display < 128))
22229 {
22230 /* Either unibyte or ASCII. */
22231 int stretched_p;
22232
22233 it->nglyphs = 1;
22234
22235 pcm = get_per_char_metric (it->f, font, &char2b);
22236
22237 if (it->override_ascent >= 0)
22238 {
22239 it->ascent = it->override_ascent;
22240 it->descent = it->override_descent;
22241 boff = it->override_boff;
22242 }
22243 else
22244 {
22245 it->ascent = FONT_BASE (font) + boff;
22246 it->descent = FONT_DESCENT (font) - boff;
22247 }
22248
22249 if (pcm)
22250 {
22251 it->phys_ascent = pcm->ascent + boff;
22252 it->phys_descent = pcm->descent - boff;
22253 it->pixel_width = pcm->width;
22254 }
22255 else
22256 {
22257 it->glyph_not_available_p = 1;
22258 it->phys_ascent = it->ascent;
22259 it->phys_descent = it->descent;
22260 it->pixel_width = FONT_WIDTH (font);
22261 }
22262
22263 if (it->constrain_row_ascent_descent_p)
22264 {
22265 if (it->descent > it->max_descent)
22266 {
22267 it->ascent += it->descent - it->max_descent;
22268 it->descent = it->max_descent;
22269 }
22270 if (it->ascent > it->max_ascent)
22271 {
22272 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22273 it->ascent = it->max_ascent;
22274 }
22275 it->phys_ascent = min (it->phys_ascent, it->ascent);
22276 it->phys_descent = min (it->phys_descent, it->descent);
22277 extra_line_spacing = 0;
22278 }
22279
22280 /* If this is a space inside a region of text with
22281 `space-width' property, change its width. */
22282 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22283 if (stretched_p)
22284 it->pixel_width *= XFLOATINT (it->space_width);
22285
22286 /* If face has a box, add the box thickness to the character
22287 height. If character has a box line to the left and/or
22288 right, add the box line width to the character's width. */
22289 if (face->box != FACE_NO_BOX)
22290 {
22291 int thick = face->box_line_width;
22292
22293 if (thick > 0)
22294 {
22295 it->ascent += thick;
22296 it->descent += thick;
22297 }
22298 else
22299 thick = -thick;
22300
22301 if (it->start_of_box_run_p)
22302 it->pixel_width += thick;
22303 if (it->end_of_box_run_p)
22304 it->pixel_width += thick;
22305 }
22306
22307 /* If face has an overline, add the height of the overline
22308 (1 pixel) and a 1 pixel margin to the character height. */
22309 if (face->overline_p)
22310 it->ascent += overline_margin;
22311
22312 if (it->constrain_row_ascent_descent_p)
22313 {
22314 if (it->ascent > it->max_ascent)
22315 it->ascent = it->max_ascent;
22316 if (it->descent > it->max_descent)
22317 it->descent = it->max_descent;
22318 }
22319
22320 take_vertical_position_into_account (it);
22321
22322 /* If we have to actually produce glyphs, do it. */
22323 if (it->glyph_row)
22324 {
22325 if (stretched_p)
22326 {
22327 /* Translate a space with a `space-width' property
22328 into a stretch glyph. */
22329 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22330 / FONT_HEIGHT (font));
22331 append_stretch_glyph (it, it->object, it->pixel_width,
22332 it->ascent + it->descent, ascent);
22333 }
22334 else
22335 append_glyph (it);
22336
22337 /* If characters with lbearing or rbearing are displayed
22338 in this line, record that fact in a flag of the
22339 glyph row. This is used to optimize X output code. */
22340 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22341 it->glyph_row->contains_overlapping_glyphs_p = 1;
22342 }
22343 if (! stretched_p && it->pixel_width == 0)
22344 /* We assure that all visible glyphs have at least 1-pixel
22345 width. */
22346 it->pixel_width = 1;
22347 }
22348 else if (it->char_to_display == '\n')
22349 {
22350 /* A newline has no width, but we need the height of the
22351 line. But if previous part of the line sets a height,
22352 don't increase that height */
22353
22354 Lisp_Object height;
22355 Lisp_Object total_height = Qnil;
22356
22357 it->override_ascent = -1;
22358 it->pixel_width = 0;
22359 it->nglyphs = 0;
22360
22361 height = get_it_property(it, Qline_height);
22362 /* Split (line-height total-height) list */
22363 if (CONSP (height)
22364 && CONSP (XCDR (height))
22365 && NILP (XCDR (XCDR (height))))
22366 {
22367 total_height = XCAR (XCDR (height));
22368 height = XCAR (height);
22369 }
22370 height = calc_line_height_property(it, height, font, boff, 1);
22371
22372 if (it->override_ascent >= 0)
22373 {
22374 it->ascent = it->override_ascent;
22375 it->descent = it->override_descent;
22376 boff = it->override_boff;
22377 }
22378 else
22379 {
22380 it->ascent = FONT_BASE (font) + boff;
22381 it->descent = FONT_DESCENT (font) - boff;
22382 }
22383
22384 if (EQ (height, Qt))
22385 {
22386 if (it->descent > it->max_descent)
22387 {
22388 it->ascent += it->descent - it->max_descent;
22389 it->descent = it->max_descent;
22390 }
22391 if (it->ascent > it->max_ascent)
22392 {
22393 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22394 it->ascent = it->max_ascent;
22395 }
22396 it->phys_ascent = min (it->phys_ascent, it->ascent);
22397 it->phys_descent = min (it->phys_descent, it->descent);
22398 it->constrain_row_ascent_descent_p = 1;
22399 extra_line_spacing = 0;
22400 }
22401 else
22402 {
22403 Lisp_Object spacing;
22404
22405 it->phys_ascent = it->ascent;
22406 it->phys_descent = it->descent;
22407
22408 if ((it->max_ascent > 0 || it->max_descent > 0)
22409 && face->box != FACE_NO_BOX
22410 && face->box_line_width > 0)
22411 {
22412 it->ascent += face->box_line_width;
22413 it->descent += face->box_line_width;
22414 }
22415 if (!NILP (height)
22416 && XINT (height) > it->ascent + it->descent)
22417 it->ascent = XINT (height) - it->descent;
22418
22419 if (!NILP (total_height))
22420 spacing = calc_line_height_property(it, total_height, font, boff, 0);
22421 else
22422 {
22423 spacing = get_it_property(it, Qline_spacing);
22424 spacing = calc_line_height_property(it, spacing, font, boff, 0);
22425 }
22426 if (INTEGERP (spacing))
22427 {
22428 extra_line_spacing = XINT (spacing);
22429 if (!NILP (total_height))
22430 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22431 }
22432 }
22433 }
22434 else if (it->char_to_display == '\t')
22435 {
22436 if (font->space_width > 0)
22437 {
22438 int tab_width = it->tab_width * font->space_width;
22439 int x = it->current_x + it->continuation_lines_width;
22440 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22441
22442 /* If the distance from the current position to the next tab
22443 stop is less than a space character width, use the
22444 tab stop after that. */
22445 if (next_tab_x - x < font->space_width)
22446 next_tab_x += tab_width;
22447
22448 it->pixel_width = next_tab_x - x;
22449 it->nglyphs = 1;
22450 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22451 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22452
22453 if (it->glyph_row)
22454 {
22455 append_stretch_glyph (it, it->object, it->pixel_width,
22456 it->ascent + it->descent, it->ascent);
22457 }
22458 }
22459 else
22460 {
22461 it->pixel_width = 0;
22462 it->nglyphs = 1;
22463 }
22464 }
22465 else
22466 {
22467 /* A multi-byte character. Assume that the display width of the
22468 character is the width of the character multiplied by the
22469 width of the font. */
22470
22471 /* If we found a font, this font should give us the right
22472 metrics. If we didn't find a font, use the frame's
22473 default font and calculate the width of the character by
22474 multiplying the width of font by the width of the
22475 character. */
22476
22477 pcm = get_per_char_metric (it->f, font, &char2b);
22478
22479 if (font_not_found_p || !pcm)
22480 {
22481 int char_width = CHAR_WIDTH (it->char_to_display);
22482
22483 if (char_width == 0)
22484 /* This is a non spacing character. But, as we are
22485 going to display an empty box, the box must occupy
22486 at least one column. */
22487 char_width = 1;
22488 it->glyph_not_available_p = 1;
22489 it->pixel_width = font->space_width * char_width;
22490 it->phys_ascent = FONT_BASE (font) + boff;
22491 it->phys_descent = FONT_DESCENT (font) - boff;
22492 }
22493 else
22494 {
22495 it->pixel_width = pcm->width;
22496 it->phys_ascent = pcm->ascent + boff;
22497 it->phys_descent = pcm->descent - boff;
22498 if (it->glyph_row
22499 && (pcm->lbearing < 0
22500 || pcm->rbearing > pcm->width))
22501 it->glyph_row->contains_overlapping_glyphs_p = 1;
22502 }
22503 it->nglyphs = 1;
22504 it->ascent = FONT_BASE (font) + boff;
22505 it->descent = FONT_DESCENT (font) - boff;
22506 if (face->box != FACE_NO_BOX)
22507 {
22508 int thick = face->box_line_width;
22509
22510 if (thick > 0)
22511 {
22512 it->ascent += thick;
22513 it->descent += thick;
22514 }
22515 else
22516 thick = - thick;
22517
22518 if (it->start_of_box_run_p)
22519 it->pixel_width += thick;
22520 if (it->end_of_box_run_p)
22521 it->pixel_width += thick;
22522 }
22523
22524 /* If face has an overline, add the height of the overline
22525 (1 pixel) and a 1 pixel margin to the character height. */
22526 if (face->overline_p)
22527 it->ascent += overline_margin;
22528
22529 take_vertical_position_into_account (it);
22530
22531 if (it->ascent < 0)
22532 it->ascent = 0;
22533 if (it->descent < 0)
22534 it->descent = 0;
22535
22536 if (it->glyph_row)
22537 append_glyph (it);
22538 if (it->pixel_width == 0)
22539 /* We assure that all visible glyphs have at least 1-pixel
22540 width. */
22541 it->pixel_width = 1;
22542 }
22543 it->multibyte_p = saved_multibyte_p;
22544 }
22545 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22546 {
22547 /* A static composition.
22548
22549 Note: A composition is represented as one glyph in the
22550 glyph matrix. There are no padding glyphs.
22551
22552 Important note: pixel_width, ascent, and descent are the
22553 values of what is drawn by draw_glyphs (i.e. the values of
22554 the overall glyphs composed). */
22555 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22556 int boff; /* baseline offset */
22557 struct composition *cmp = composition_table[it->cmp_it.id];
22558 int glyph_len = cmp->glyph_len;
22559 struct font *font = face->font;
22560
22561 it->nglyphs = 1;
22562
22563 /* If we have not yet calculated pixel size data of glyphs of
22564 the composition for the current face font, calculate them
22565 now. Theoretically, we have to check all fonts for the
22566 glyphs, but that requires much time and memory space. So,
22567 here we check only the font of the first glyph. This may
22568 lead to incorrect display, but it's very rare, and C-l
22569 (recenter-top-bottom) can correct the display anyway. */
22570 if (! cmp->font || cmp->font != font)
22571 {
22572 /* Ascent and descent of the font of the first character
22573 of this composition (adjusted by baseline offset).
22574 Ascent and descent of overall glyphs should not be less
22575 than these, respectively. */
22576 int font_ascent, font_descent, font_height;
22577 /* Bounding box of the overall glyphs. */
22578 int leftmost, rightmost, lowest, highest;
22579 int lbearing, rbearing;
22580 int i, width, ascent, descent;
22581 int left_padded = 0, right_padded = 0;
22582 int c;
22583 XChar2b char2b;
22584 struct font_metrics *pcm;
22585 int font_not_found_p;
22586 int pos;
22587
22588 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22589 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22590 break;
22591 if (glyph_len < cmp->glyph_len)
22592 right_padded = 1;
22593 for (i = 0; i < glyph_len; i++)
22594 {
22595 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22596 break;
22597 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22598 }
22599 if (i > 0)
22600 left_padded = 1;
22601
22602 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22603 : IT_CHARPOS (*it));
22604 /* If no suitable font is found, use the default font. */
22605 font_not_found_p = font == NULL;
22606 if (font_not_found_p)
22607 {
22608 face = face->ascii_face;
22609 font = face->font;
22610 }
22611 boff = font->baseline_offset;
22612 if (font->vertical_centering)
22613 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22614 font_ascent = FONT_BASE (font) + boff;
22615 font_descent = FONT_DESCENT (font) - boff;
22616 font_height = FONT_HEIGHT (font);
22617
22618 cmp->font = (void *) font;
22619
22620 pcm = NULL;
22621 if (! font_not_found_p)
22622 {
22623 get_char_face_and_encoding (it->f, c, it->face_id,
22624 &char2b, it->multibyte_p, 0);
22625 pcm = get_per_char_metric (it->f, font, &char2b);
22626 }
22627
22628 /* Initialize the bounding box. */
22629 if (pcm)
22630 {
22631 width = pcm->width;
22632 ascent = pcm->ascent;
22633 descent = pcm->descent;
22634 lbearing = pcm->lbearing;
22635 rbearing = pcm->rbearing;
22636 }
22637 else
22638 {
22639 width = FONT_WIDTH (font);
22640 ascent = FONT_BASE (font);
22641 descent = FONT_DESCENT (font);
22642 lbearing = 0;
22643 rbearing = width;
22644 }
22645
22646 rightmost = width;
22647 leftmost = 0;
22648 lowest = - descent + boff;
22649 highest = ascent + boff;
22650
22651 if (! font_not_found_p
22652 && font->default_ascent
22653 && CHAR_TABLE_P (Vuse_default_ascent)
22654 && !NILP (Faref (Vuse_default_ascent,
22655 make_number (it->char_to_display))))
22656 highest = font->default_ascent + boff;
22657
22658 /* Draw the first glyph at the normal position. It may be
22659 shifted to right later if some other glyphs are drawn
22660 at the left. */
22661 cmp->offsets[i * 2] = 0;
22662 cmp->offsets[i * 2 + 1] = boff;
22663 cmp->lbearing = lbearing;
22664 cmp->rbearing = rbearing;
22665
22666 /* Set cmp->offsets for the remaining glyphs. */
22667 for (i++; i < glyph_len; i++)
22668 {
22669 int left, right, btm, top;
22670 int ch = COMPOSITION_GLYPH (cmp, i);
22671 int face_id;
22672 struct face *this_face;
22673 int this_boff;
22674
22675 if (ch == '\t')
22676 ch = ' ';
22677 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22678 this_face = FACE_FROM_ID (it->f, face_id);
22679 font = this_face->font;
22680
22681 if (font == NULL)
22682 pcm = NULL;
22683 else
22684 {
22685 this_boff = font->baseline_offset;
22686 if (font->vertical_centering)
22687 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22688 get_char_face_and_encoding (it->f, ch, face_id,
22689 &char2b, it->multibyte_p, 0);
22690 pcm = get_per_char_metric (it->f, font, &char2b);
22691 }
22692 if (! pcm)
22693 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22694 else
22695 {
22696 width = pcm->width;
22697 ascent = pcm->ascent;
22698 descent = pcm->descent;
22699 lbearing = pcm->lbearing;
22700 rbearing = pcm->rbearing;
22701 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22702 {
22703 /* Relative composition with or without
22704 alternate chars. */
22705 left = (leftmost + rightmost - width) / 2;
22706 btm = - descent + boff;
22707 if (font->relative_compose
22708 && (! CHAR_TABLE_P (Vignore_relative_composition)
22709 || NILP (Faref (Vignore_relative_composition,
22710 make_number (ch)))))
22711 {
22712
22713 if (- descent >= font->relative_compose)
22714 /* One extra pixel between two glyphs. */
22715 btm = highest + 1;
22716 else if (ascent <= 0)
22717 /* One extra pixel between two glyphs. */
22718 btm = lowest - 1 - ascent - descent;
22719 }
22720 }
22721 else
22722 {
22723 /* A composition rule is specified by an integer
22724 value that encodes global and new reference
22725 points (GREF and NREF). GREF and NREF are
22726 specified by numbers as below:
22727
22728 0---1---2 -- ascent
22729 | |
22730 | |
22731 | |
22732 9--10--11 -- center
22733 | |
22734 ---3---4---5--- baseline
22735 | |
22736 6---7---8 -- descent
22737 */
22738 int rule = COMPOSITION_RULE (cmp, i);
22739 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
22740
22741 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
22742 grefx = gref % 3, nrefx = nref % 3;
22743 grefy = gref / 3, nrefy = nref / 3;
22744 if (xoff)
22745 xoff = font_height * (xoff - 128) / 256;
22746 if (yoff)
22747 yoff = font_height * (yoff - 128) / 256;
22748
22749 left = (leftmost
22750 + grefx * (rightmost - leftmost) / 2
22751 - nrefx * width / 2
22752 + xoff);
22753
22754 btm = ((grefy == 0 ? highest
22755 : grefy == 1 ? 0
22756 : grefy == 2 ? lowest
22757 : (highest + lowest) / 2)
22758 - (nrefy == 0 ? ascent + descent
22759 : nrefy == 1 ? descent - boff
22760 : nrefy == 2 ? 0
22761 : (ascent + descent) / 2)
22762 + yoff);
22763 }
22764
22765 cmp->offsets[i * 2] = left;
22766 cmp->offsets[i * 2 + 1] = btm + descent;
22767
22768 /* Update the bounding box of the overall glyphs. */
22769 if (width > 0)
22770 {
22771 right = left + width;
22772 if (left < leftmost)
22773 leftmost = left;
22774 if (right > rightmost)
22775 rightmost = right;
22776 }
22777 top = btm + descent + ascent;
22778 if (top > highest)
22779 highest = top;
22780 if (btm < lowest)
22781 lowest = btm;
22782
22783 if (cmp->lbearing > left + lbearing)
22784 cmp->lbearing = left + lbearing;
22785 if (cmp->rbearing < left + rbearing)
22786 cmp->rbearing = left + rbearing;
22787 }
22788 }
22789
22790 /* If there are glyphs whose x-offsets are negative,
22791 shift all glyphs to the right and make all x-offsets
22792 non-negative. */
22793 if (leftmost < 0)
22794 {
22795 for (i = 0; i < cmp->glyph_len; i++)
22796 cmp->offsets[i * 2] -= leftmost;
22797 rightmost -= leftmost;
22798 cmp->lbearing -= leftmost;
22799 cmp->rbearing -= leftmost;
22800 }
22801
22802 if (left_padded && cmp->lbearing < 0)
22803 {
22804 for (i = 0; i < cmp->glyph_len; i++)
22805 cmp->offsets[i * 2] -= cmp->lbearing;
22806 rightmost -= cmp->lbearing;
22807 cmp->rbearing -= cmp->lbearing;
22808 cmp->lbearing = 0;
22809 }
22810 if (right_padded && rightmost < cmp->rbearing)
22811 {
22812 rightmost = cmp->rbearing;
22813 }
22814
22815 cmp->pixel_width = rightmost;
22816 cmp->ascent = highest;
22817 cmp->descent = - lowest;
22818 if (cmp->ascent < font_ascent)
22819 cmp->ascent = font_ascent;
22820 if (cmp->descent < font_descent)
22821 cmp->descent = font_descent;
22822 }
22823
22824 if (it->glyph_row
22825 && (cmp->lbearing < 0
22826 || cmp->rbearing > cmp->pixel_width))
22827 it->glyph_row->contains_overlapping_glyphs_p = 1;
22828
22829 it->pixel_width = cmp->pixel_width;
22830 it->ascent = it->phys_ascent = cmp->ascent;
22831 it->descent = it->phys_descent = cmp->descent;
22832 if (face->box != FACE_NO_BOX)
22833 {
22834 int thick = face->box_line_width;
22835
22836 if (thick > 0)
22837 {
22838 it->ascent += thick;
22839 it->descent += thick;
22840 }
22841 else
22842 thick = - thick;
22843
22844 if (it->start_of_box_run_p)
22845 it->pixel_width += thick;
22846 if (it->end_of_box_run_p)
22847 it->pixel_width += thick;
22848 }
22849
22850 /* If face has an overline, add the height of the overline
22851 (1 pixel) and a 1 pixel margin to the character height. */
22852 if (face->overline_p)
22853 it->ascent += overline_margin;
22854
22855 take_vertical_position_into_account (it);
22856 if (it->ascent < 0)
22857 it->ascent = 0;
22858 if (it->descent < 0)
22859 it->descent = 0;
22860
22861 if (it->glyph_row)
22862 append_composite_glyph (it);
22863 }
22864 else if (it->what == IT_COMPOSITION)
22865 {
22866 /* A dynamic (automatic) composition. */
22867 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22868 Lisp_Object gstring;
22869 struct font_metrics metrics;
22870
22871 gstring = composition_gstring_from_id (it->cmp_it.id);
22872 it->pixel_width
22873 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
22874 &metrics);
22875 if (it->glyph_row
22876 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
22877 it->glyph_row->contains_overlapping_glyphs_p = 1;
22878 it->ascent = it->phys_ascent = metrics.ascent;
22879 it->descent = it->phys_descent = metrics.descent;
22880 if (face->box != FACE_NO_BOX)
22881 {
22882 int thick = face->box_line_width;
22883
22884 if (thick > 0)
22885 {
22886 it->ascent += thick;
22887 it->descent += thick;
22888 }
22889 else
22890 thick = - thick;
22891
22892 if (it->start_of_box_run_p)
22893 it->pixel_width += thick;
22894 if (it->end_of_box_run_p)
22895 it->pixel_width += thick;
22896 }
22897 /* If face has an overline, add the height of the overline
22898 (1 pixel) and a 1 pixel margin to the character height. */
22899 if (face->overline_p)
22900 it->ascent += overline_margin;
22901 take_vertical_position_into_account (it);
22902 if (it->ascent < 0)
22903 it->ascent = 0;
22904 if (it->descent < 0)
22905 it->descent = 0;
22906
22907 if (it->glyph_row)
22908 append_composite_glyph (it);
22909 }
22910 else if (it->what == IT_IMAGE)
22911 produce_image_glyph (it);
22912 else if (it->what == IT_STRETCH)
22913 produce_stretch_glyph (it);
22914
22915 /* Accumulate dimensions. Note: can't assume that it->descent > 0
22916 because this isn't true for images with `:ascent 100'. */
22917 xassert (it->ascent >= 0 && it->descent >= 0);
22918 if (it->area == TEXT_AREA)
22919 it->current_x += it->pixel_width;
22920
22921 if (extra_line_spacing > 0)
22922 {
22923 it->descent += extra_line_spacing;
22924 if (extra_line_spacing > it->max_extra_line_spacing)
22925 it->max_extra_line_spacing = extra_line_spacing;
22926 }
22927
22928 it->max_ascent = max (it->max_ascent, it->ascent);
22929 it->max_descent = max (it->max_descent, it->descent);
22930 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
22931 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
22932 }
22933
22934 /* EXPORT for RIF:
22935 Output LEN glyphs starting at START at the nominal cursor position.
22936 Advance the nominal cursor over the text. The global variable
22937 updated_window contains the window being updated, updated_row is
22938 the glyph row being updated, and updated_area is the area of that
22939 row being updated. */
22940
22941 void
22942 x_write_glyphs (start, len)
22943 struct glyph *start;
22944 int len;
22945 {
22946 int x, hpos;
22947
22948 xassert (updated_window && updated_row);
22949 BLOCK_INPUT;
22950
22951 /* Write glyphs. */
22952
22953 hpos = start - updated_row->glyphs[updated_area];
22954 x = draw_glyphs (updated_window, output_cursor.x,
22955 updated_row, updated_area,
22956 hpos, hpos + len,
22957 DRAW_NORMAL_TEXT, 0);
22958
22959 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
22960 if (updated_area == TEXT_AREA
22961 && updated_window->phys_cursor_on_p
22962 && updated_window->phys_cursor.vpos == output_cursor.vpos
22963 && updated_window->phys_cursor.hpos >= hpos
22964 && updated_window->phys_cursor.hpos < hpos + len)
22965 updated_window->phys_cursor_on_p = 0;
22966
22967 UNBLOCK_INPUT;
22968
22969 /* Advance the output cursor. */
22970 output_cursor.hpos += len;
22971 output_cursor.x = x;
22972 }
22973
22974
22975 /* EXPORT for RIF:
22976 Insert LEN glyphs from START at the nominal cursor position. */
22977
22978 void
22979 x_insert_glyphs (start, len)
22980 struct glyph *start;
22981 int len;
22982 {
22983 struct frame *f;
22984 struct window *w;
22985 int line_height, shift_by_width, shifted_region_width;
22986 struct glyph_row *row;
22987 struct glyph *glyph;
22988 int frame_x, frame_y;
22989 EMACS_INT hpos;
22990
22991 xassert (updated_window && updated_row);
22992 BLOCK_INPUT;
22993 w = updated_window;
22994 f = XFRAME (WINDOW_FRAME (w));
22995
22996 /* Get the height of the line we are in. */
22997 row = updated_row;
22998 line_height = row->height;
22999
23000 /* Get the width of the glyphs to insert. */
23001 shift_by_width = 0;
23002 for (glyph = start; glyph < start + len; ++glyph)
23003 shift_by_width += glyph->pixel_width;
23004
23005 /* Get the width of the region to shift right. */
23006 shifted_region_width = (window_box_width (w, updated_area)
23007 - output_cursor.x
23008 - shift_by_width);
23009
23010 /* Shift right. */
23011 frame_x = window_box_left (w, updated_area) + output_cursor.x;
23012 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
23013
23014 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
23015 line_height, shift_by_width);
23016
23017 /* Write the glyphs. */
23018 hpos = start - row->glyphs[updated_area];
23019 draw_glyphs (w, output_cursor.x, row, updated_area,
23020 hpos, hpos + len,
23021 DRAW_NORMAL_TEXT, 0);
23022
23023 /* Advance the output cursor. */
23024 output_cursor.hpos += len;
23025 output_cursor.x += shift_by_width;
23026 UNBLOCK_INPUT;
23027 }
23028
23029
23030 /* EXPORT for RIF:
23031 Erase the current text line from the nominal cursor position
23032 (inclusive) to pixel column TO_X (exclusive). The idea is that
23033 everything from TO_X onward is already erased.
23034
23035 TO_X is a pixel position relative to updated_area of
23036 updated_window. TO_X == -1 means clear to the end of this area. */
23037
23038 void
23039 x_clear_end_of_line (to_x)
23040 int to_x;
23041 {
23042 struct frame *f;
23043 struct window *w = updated_window;
23044 int max_x, min_y, max_y;
23045 int from_x, from_y, to_y;
23046
23047 xassert (updated_window && updated_row);
23048 f = XFRAME (w->frame);
23049
23050 if (updated_row->full_width_p)
23051 max_x = WINDOW_TOTAL_WIDTH (w);
23052 else
23053 max_x = window_box_width (w, updated_area);
23054 max_y = window_text_bottom_y (w);
23055
23056 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
23057 of window. For TO_X > 0, truncate to end of drawing area. */
23058 if (to_x == 0)
23059 return;
23060 else if (to_x < 0)
23061 to_x = max_x;
23062 else
23063 to_x = min (to_x, max_x);
23064
23065 to_y = min (max_y, output_cursor.y + updated_row->height);
23066
23067 /* Notice if the cursor will be cleared by this operation. */
23068 if (!updated_row->full_width_p)
23069 notice_overwritten_cursor (w, updated_area,
23070 output_cursor.x, -1,
23071 updated_row->y,
23072 MATRIX_ROW_BOTTOM_Y (updated_row));
23073
23074 from_x = output_cursor.x;
23075
23076 /* Translate to frame coordinates. */
23077 if (updated_row->full_width_p)
23078 {
23079 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
23080 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
23081 }
23082 else
23083 {
23084 int area_left = window_box_left (w, updated_area);
23085 from_x += area_left;
23086 to_x += area_left;
23087 }
23088
23089 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23090 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23091 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23092
23093 /* Prevent inadvertently clearing to end of the X window. */
23094 if (to_x > from_x && to_y > from_y)
23095 {
23096 BLOCK_INPUT;
23097 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23098 to_x - from_x, to_y - from_y);
23099 UNBLOCK_INPUT;
23100 }
23101 }
23102
23103 #endif /* HAVE_WINDOW_SYSTEM */
23104
23105
23106 \f
23107 /***********************************************************************
23108 Cursor types
23109 ***********************************************************************/
23110
23111 /* Value is the internal representation of the specified cursor type
23112 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23113 of the bar cursor. */
23114
23115 static enum text_cursor_kinds
23116 get_specified_cursor_type (arg, width)
23117 Lisp_Object arg;
23118 int *width;
23119 {
23120 enum text_cursor_kinds type;
23121
23122 if (NILP (arg))
23123 return NO_CURSOR;
23124
23125 if (EQ (arg, Qbox))
23126 return FILLED_BOX_CURSOR;
23127
23128 if (EQ (arg, Qhollow))
23129 return HOLLOW_BOX_CURSOR;
23130
23131 if (EQ (arg, Qbar))
23132 {
23133 *width = 2;
23134 return BAR_CURSOR;
23135 }
23136
23137 if (CONSP (arg)
23138 && EQ (XCAR (arg), Qbar)
23139 && INTEGERP (XCDR (arg))
23140 && XINT (XCDR (arg)) >= 0)
23141 {
23142 *width = XINT (XCDR (arg));
23143 return BAR_CURSOR;
23144 }
23145
23146 if (EQ (arg, Qhbar))
23147 {
23148 *width = 2;
23149 return HBAR_CURSOR;
23150 }
23151
23152 if (CONSP (arg)
23153 && EQ (XCAR (arg), Qhbar)
23154 && INTEGERP (XCDR (arg))
23155 && XINT (XCDR (arg)) >= 0)
23156 {
23157 *width = XINT (XCDR (arg));
23158 return HBAR_CURSOR;
23159 }
23160
23161 /* Treat anything unknown as "hollow box cursor".
23162 It was bad to signal an error; people have trouble fixing
23163 .Xdefaults with Emacs, when it has something bad in it. */
23164 type = HOLLOW_BOX_CURSOR;
23165
23166 return type;
23167 }
23168
23169 /* Set the default cursor types for specified frame. */
23170 void
23171 set_frame_cursor_types (f, arg)
23172 struct frame *f;
23173 Lisp_Object arg;
23174 {
23175 int width;
23176 Lisp_Object tem;
23177
23178 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23179 FRAME_CURSOR_WIDTH (f) = width;
23180
23181 /* By default, set up the blink-off state depending on the on-state. */
23182
23183 tem = Fassoc (arg, Vblink_cursor_alist);
23184 if (!NILP (tem))
23185 {
23186 FRAME_BLINK_OFF_CURSOR (f)
23187 = get_specified_cursor_type (XCDR (tem), &width);
23188 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23189 }
23190 else
23191 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23192 }
23193
23194
23195 /* Return the cursor we want to be displayed in window W. Return
23196 width of bar/hbar cursor through WIDTH arg. Return with
23197 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23198 (i.e. if the `system caret' should track this cursor).
23199
23200 In a mini-buffer window, we want the cursor only to appear if we
23201 are reading input from this window. For the selected window, we
23202 want the cursor type given by the frame parameter or buffer local
23203 setting of cursor-type. If explicitly marked off, draw no cursor.
23204 In all other cases, we want a hollow box cursor. */
23205
23206 static enum text_cursor_kinds
23207 get_window_cursor_type (w, glyph, width, active_cursor)
23208 struct window *w;
23209 struct glyph *glyph;
23210 int *width;
23211 int *active_cursor;
23212 {
23213 struct frame *f = XFRAME (w->frame);
23214 struct buffer *b = XBUFFER (w->buffer);
23215 int cursor_type = DEFAULT_CURSOR;
23216 Lisp_Object alt_cursor;
23217 int non_selected = 0;
23218
23219 *active_cursor = 1;
23220
23221 /* Echo area */
23222 if (cursor_in_echo_area
23223 && FRAME_HAS_MINIBUF_P (f)
23224 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23225 {
23226 if (w == XWINDOW (echo_area_window))
23227 {
23228 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
23229 {
23230 *width = FRAME_CURSOR_WIDTH (f);
23231 return FRAME_DESIRED_CURSOR (f);
23232 }
23233 else
23234 return get_specified_cursor_type (b->cursor_type, width);
23235 }
23236
23237 *active_cursor = 0;
23238 non_selected = 1;
23239 }
23240
23241 /* Detect a nonselected window or nonselected frame. */
23242 else if (w != XWINDOW (f->selected_window)
23243 #ifdef HAVE_WINDOW_SYSTEM
23244 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
23245 #endif
23246 )
23247 {
23248 *active_cursor = 0;
23249
23250 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23251 return NO_CURSOR;
23252
23253 non_selected = 1;
23254 }
23255
23256 /* Never display a cursor in a window in which cursor-type is nil. */
23257 if (NILP (b->cursor_type))
23258 return NO_CURSOR;
23259
23260 /* Get the normal cursor type for this window. */
23261 if (EQ (b->cursor_type, Qt))
23262 {
23263 cursor_type = FRAME_DESIRED_CURSOR (f);
23264 *width = FRAME_CURSOR_WIDTH (f);
23265 }
23266 else
23267 cursor_type = get_specified_cursor_type (b->cursor_type, width);
23268
23269 /* Use cursor-in-non-selected-windows instead
23270 for non-selected window or frame. */
23271 if (non_selected)
23272 {
23273 alt_cursor = b->cursor_in_non_selected_windows;
23274 if (!EQ (Qt, alt_cursor))
23275 return get_specified_cursor_type (alt_cursor, width);
23276 /* t means modify the normal cursor type. */
23277 if (cursor_type == FILLED_BOX_CURSOR)
23278 cursor_type = HOLLOW_BOX_CURSOR;
23279 else if (cursor_type == BAR_CURSOR && *width > 1)
23280 --*width;
23281 return cursor_type;
23282 }
23283
23284 /* Use normal cursor if not blinked off. */
23285 if (!w->cursor_off_p)
23286 {
23287 #ifdef HAVE_WINDOW_SYSTEM
23288 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23289 {
23290 if (cursor_type == FILLED_BOX_CURSOR)
23291 {
23292 /* Using a block cursor on large images can be very annoying.
23293 So use a hollow cursor for "large" images.
23294 If image is not transparent (no mask), also use hollow cursor. */
23295 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23296 if (img != NULL && IMAGEP (img->spec))
23297 {
23298 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23299 where N = size of default frame font size.
23300 This should cover most of the "tiny" icons people may use. */
23301 if (!img->mask
23302 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23303 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23304 cursor_type = HOLLOW_BOX_CURSOR;
23305 }
23306 }
23307 else if (cursor_type != NO_CURSOR)
23308 {
23309 /* Display current only supports BOX and HOLLOW cursors for images.
23310 So for now, unconditionally use a HOLLOW cursor when cursor is
23311 not a solid box cursor. */
23312 cursor_type = HOLLOW_BOX_CURSOR;
23313 }
23314 }
23315 #endif
23316 return cursor_type;
23317 }
23318
23319 /* Cursor is blinked off, so determine how to "toggle" it. */
23320
23321 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23322 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
23323 return get_specified_cursor_type (XCDR (alt_cursor), width);
23324
23325 /* Then see if frame has specified a specific blink off cursor type. */
23326 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23327 {
23328 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23329 return FRAME_BLINK_OFF_CURSOR (f);
23330 }
23331
23332 #if 0
23333 /* Some people liked having a permanently visible blinking cursor,
23334 while others had very strong opinions against it. So it was
23335 decided to remove it. KFS 2003-09-03 */
23336
23337 /* Finally perform built-in cursor blinking:
23338 filled box <-> hollow box
23339 wide [h]bar <-> narrow [h]bar
23340 narrow [h]bar <-> no cursor
23341 other type <-> no cursor */
23342
23343 if (cursor_type == FILLED_BOX_CURSOR)
23344 return HOLLOW_BOX_CURSOR;
23345
23346 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23347 {
23348 *width = 1;
23349 return cursor_type;
23350 }
23351 #endif
23352
23353 return NO_CURSOR;
23354 }
23355
23356
23357 #ifdef HAVE_WINDOW_SYSTEM
23358
23359 /* Notice when the text cursor of window W has been completely
23360 overwritten by a drawing operation that outputs glyphs in AREA
23361 starting at X0 and ending at X1 in the line starting at Y0 and
23362 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23363 the rest of the line after X0 has been written. Y coordinates
23364 are window-relative. */
23365
23366 static void
23367 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
23368 struct window *w;
23369 enum glyph_row_area area;
23370 int x0, y0, x1, y1;
23371 {
23372 int cx0, cx1, cy0, cy1;
23373 struct glyph_row *row;
23374
23375 if (!w->phys_cursor_on_p)
23376 return;
23377 if (area != TEXT_AREA)
23378 return;
23379
23380 if (w->phys_cursor.vpos < 0
23381 || w->phys_cursor.vpos >= w->current_matrix->nrows
23382 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23383 !(row->enabled_p && row->displays_text_p)))
23384 return;
23385
23386 if (row->cursor_in_fringe_p)
23387 {
23388 row->cursor_in_fringe_p = 0;
23389 draw_fringe_bitmap (w, row, row->reversed_p);
23390 w->phys_cursor_on_p = 0;
23391 return;
23392 }
23393
23394 cx0 = w->phys_cursor.x;
23395 cx1 = cx0 + w->phys_cursor_width;
23396 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23397 return;
23398
23399 /* The cursor image will be completely removed from the
23400 screen if the output area intersects the cursor area in
23401 y-direction. When we draw in [y0 y1[, and some part of
23402 the cursor is at y < y0, that part must have been drawn
23403 before. When scrolling, the cursor is erased before
23404 actually scrolling, so we don't come here. When not
23405 scrolling, the rows above the old cursor row must have
23406 changed, and in this case these rows must have written
23407 over the cursor image.
23408
23409 Likewise if part of the cursor is below y1, with the
23410 exception of the cursor being in the first blank row at
23411 the buffer and window end because update_text_area
23412 doesn't draw that row. (Except when it does, but
23413 that's handled in update_text_area.) */
23414
23415 cy0 = w->phys_cursor.y;
23416 cy1 = cy0 + w->phys_cursor_height;
23417 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23418 return;
23419
23420 w->phys_cursor_on_p = 0;
23421 }
23422
23423 #endif /* HAVE_WINDOW_SYSTEM */
23424
23425 \f
23426 /************************************************************************
23427 Mouse Face
23428 ************************************************************************/
23429
23430 #ifdef HAVE_WINDOW_SYSTEM
23431
23432 /* EXPORT for RIF:
23433 Fix the display of area AREA of overlapping row ROW in window W
23434 with respect to the overlapping part OVERLAPS. */
23435
23436 void
23437 x_fix_overlapping_area (w, row, area, overlaps)
23438 struct window *w;
23439 struct glyph_row *row;
23440 enum glyph_row_area area;
23441 int overlaps;
23442 {
23443 int i, x;
23444
23445 BLOCK_INPUT;
23446
23447 x = 0;
23448 for (i = 0; i < row->used[area];)
23449 {
23450 if (row->glyphs[area][i].overlaps_vertically_p)
23451 {
23452 int start = i, start_x = x;
23453
23454 do
23455 {
23456 x += row->glyphs[area][i].pixel_width;
23457 ++i;
23458 }
23459 while (i < row->used[area]
23460 && row->glyphs[area][i].overlaps_vertically_p);
23461
23462 draw_glyphs (w, start_x, row, area,
23463 start, i,
23464 DRAW_NORMAL_TEXT, overlaps);
23465 }
23466 else
23467 {
23468 x += row->glyphs[area][i].pixel_width;
23469 ++i;
23470 }
23471 }
23472
23473 UNBLOCK_INPUT;
23474 }
23475
23476
23477 /* EXPORT:
23478 Draw the cursor glyph of window W in glyph row ROW. See the
23479 comment of draw_glyphs for the meaning of HL. */
23480
23481 void
23482 draw_phys_cursor_glyph (w, row, hl)
23483 struct window *w;
23484 struct glyph_row *row;
23485 enum draw_glyphs_face hl;
23486 {
23487 /* If cursor hpos is out of bounds, don't draw garbage. This can
23488 happen in mini-buffer windows when switching between echo area
23489 glyphs and mini-buffer. */
23490 if ((row->reversed_p
23491 ? (w->phys_cursor.hpos >= 0)
23492 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23493 {
23494 int on_p = w->phys_cursor_on_p;
23495 int x1;
23496 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23497 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23498 hl, 0);
23499 w->phys_cursor_on_p = on_p;
23500
23501 if (hl == DRAW_CURSOR)
23502 w->phys_cursor_width = x1 - w->phys_cursor.x;
23503 /* When we erase the cursor, and ROW is overlapped by other
23504 rows, make sure that these overlapping parts of other rows
23505 are redrawn. */
23506 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23507 {
23508 w->phys_cursor_width = x1 - w->phys_cursor.x;
23509
23510 if (row > w->current_matrix->rows
23511 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23512 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23513 OVERLAPS_ERASED_CURSOR);
23514
23515 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23516 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23517 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23518 OVERLAPS_ERASED_CURSOR);
23519 }
23520 }
23521 }
23522
23523
23524 /* EXPORT:
23525 Erase the image of a cursor of window W from the screen. */
23526
23527 void
23528 erase_phys_cursor (w)
23529 struct window *w;
23530 {
23531 struct frame *f = XFRAME (w->frame);
23532 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23533 int hpos = w->phys_cursor.hpos;
23534 int vpos = w->phys_cursor.vpos;
23535 int mouse_face_here_p = 0;
23536 struct glyph_matrix *active_glyphs = w->current_matrix;
23537 struct glyph_row *cursor_row;
23538 struct glyph *cursor_glyph;
23539 enum draw_glyphs_face hl;
23540
23541 /* No cursor displayed or row invalidated => nothing to do on the
23542 screen. */
23543 if (w->phys_cursor_type == NO_CURSOR)
23544 goto mark_cursor_off;
23545
23546 /* VPOS >= active_glyphs->nrows means that window has been resized.
23547 Don't bother to erase the cursor. */
23548 if (vpos >= active_glyphs->nrows)
23549 goto mark_cursor_off;
23550
23551 /* If row containing cursor is marked invalid, there is nothing we
23552 can do. */
23553 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23554 if (!cursor_row->enabled_p)
23555 goto mark_cursor_off;
23556
23557 /* If line spacing is > 0, old cursor may only be partially visible in
23558 window after split-window. So adjust visible height. */
23559 cursor_row->visible_height = min (cursor_row->visible_height,
23560 window_text_bottom_y (w) - cursor_row->y);
23561
23562 /* If row is completely invisible, don't attempt to delete a cursor which
23563 isn't there. This can happen if cursor is at top of a window, and
23564 we switch to a buffer with a header line in that window. */
23565 if (cursor_row->visible_height <= 0)
23566 goto mark_cursor_off;
23567
23568 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23569 if (cursor_row->cursor_in_fringe_p)
23570 {
23571 cursor_row->cursor_in_fringe_p = 0;
23572 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23573 goto mark_cursor_off;
23574 }
23575
23576 /* This can happen when the new row is shorter than the old one.
23577 In this case, either draw_glyphs or clear_end_of_line
23578 should have cleared the cursor. Note that we wouldn't be
23579 able to erase the cursor in this case because we don't have a
23580 cursor glyph at hand. */
23581 if ((cursor_row->reversed_p
23582 ? (w->phys_cursor.hpos < 0)
23583 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23584 goto mark_cursor_off;
23585
23586 /* If the cursor is in the mouse face area, redisplay that when
23587 we clear the cursor. */
23588 if (! NILP (dpyinfo->mouse_face_window)
23589 && w == XWINDOW (dpyinfo->mouse_face_window)
23590 && (vpos > dpyinfo->mouse_face_beg_row
23591 || (vpos == dpyinfo->mouse_face_beg_row
23592 && hpos >= dpyinfo->mouse_face_beg_col))
23593 && (vpos < dpyinfo->mouse_face_end_row
23594 || (vpos == dpyinfo->mouse_face_end_row
23595 && hpos < dpyinfo->mouse_face_end_col))
23596 /* Don't redraw the cursor's spot in mouse face if it is at the
23597 end of a line (on a newline). The cursor appears there, but
23598 mouse highlighting does not. */
23599 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23600 mouse_face_here_p = 1;
23601
23602 /* Maybe clear the display under the cursor. */
23603 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23604 {
23605 int x, y, left_x;
23606 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23607 int width;
23608
23609 cursor_glyph = get_phys_cursor_glyph (w);
23610 if (cursor_glyph == NULL)
23611 goto mark_cursor_off;
23612
23613 width = cursor_glyph->pixel_width;
23614 left_x = window_box_left_offset (w, TEXT_AREA);
23615 x = w->phys_cursor.x;
23616 if (x < left_x)
23617 width -= left_x - x;
23618 width = min (width, window_box_width (w, TEXT_AREA) - x);
23619 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23620 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23621
23622 if (width > 0)
23623 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23624 }
23625
23626 /* Erase the cursor by redrawing the character underneath it. */
23627 if (mouse_face_here_p)
23628 hl = DRAW_MOUSE_FACE;
23629 else
23630 hl = DRAW_NORMAL_TEXT;
23631 draw_phys_cursor_glyph (w, cursor_row, hl);
23632
23633 mark_cursor_off:
23634 w->phys_cursor_on_p = 0;
23635 w->phys_cursor_type = NO_CURSOR;
23636 }
23637
23638
23639 /* EXPORT:
23640 Display or clear cursor of window W. If ON is zero, clear the
23641 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23642 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23643
23644 void
23645 display_and_set_cursor (w, on, hpos, vpos, x, y)
23646 struct window *w;
23647 int on, hpos, vpos, x, y;
23648 {
23649 struct frame *f = XFRAME (w->frame);
23650 int new_cursor_type;
23651 int new_cursor_width;
23652 int active_cursor;
23653 struct glyph_row *glyph_row;
23654 struct glyph *glyph;
23655
23656 /* This is pointless on invisible frames, and dangerous on garbaged
23657 windows and frames; in the latter case, the frame or window may
23658 be in the midst of changing its size, and x and y may be off the
23659 window. */
23660 if (! FRAME_VISIBLE_P (f)
23661 || FRAME_GARBAGED_P (f)
23662 || vpos >= w->current_matrix->nrows
23663 || hpos >= w->current_matrix->matrix_w)
23664 return;
23665
23666 /* If cursor is off and we want it off, return quickly. */
23667 if (!on && !w->phys_cursor_on_p)
23668 return;
23669
23670 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23671 /* If cursor row is not enabled, we don't really know where to
23672 display the cursor. */
23673 if (!glyph_row->enabled_p)
23674 {
23675 w->phys_cursor_on_p = 0;
23676 return;
23677 }
23678
23679 glyph = NULL;
23680 if (!glyph_row->exact_window_width_line_p
23681 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23682 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23683
23684 xassert (interrupt_input_blocked);
23685
23686 /* Set new_cursor_type to the cursor we want to be displayed. */
23687 new_cursor_type = get_window_cursor_type (w, glyph,
23688 &new_cursor_width, &active_cursor);
23689
23690 /* If cursor is currently being shown and we don't want it to be or
23691 it is in the wrong place, or the cursor type is not what we want,
23692 erase it. */
23693 if (w->phys_cursor_on_p
23694 && (!on
23695 || w->phys_cursor.x != x
23696 || w->phys_cursor.y != y
23697 || new_cursor_type != w->phys_cursor_type
23698 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23699 && new_cursor_width != w->phys_cursor_width)))
23700 erase_phys_cursor (w);
23701
23702 /* Don't check phys_cursor_on_p here because that flag is only set
23703 to zero in some cases where we know that the cursor has been
23704 completely erased, to avoid the extra work of erasing the cursor
23705 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23706 still not be visible, or it has only been partly erased. */
23707 if (on)
23708 {
23709 w->phys_cursor_ascent = glyph_row->ascent;
23710 w->phys_cursor_height = glyph_row->height;
23711
23712 /* Set phys_cursor_.* before x_draw_.* is called because some
23713 of them may need the information. */
23714 w->phys_cursor.x = x;
23715 w->phys_cursor.y = glyph_row->y;
23716 w->phys_cursor.hpos = hpos;
23717 w->phys_cursor.vpos = vpos;
23718 }
23719
23720 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23721 new_cursor_type, new_cursor_width,
23722 on, active_cursor);
23723 }
23724
23725
23726 /* Switch the display of W's cursor on or off, according to the value
23727 of ON. */
23728
23729 void
23730 update_window_cursor (w, on)
23731 struct window *w;
23732 int on;
23733 {
23734 /* Don't update cursor in windows whose frame is in the process
23735 of being deleted. */
23736 if (w->current_matrix)
23737 {
23738 BLOCK_INPUT;
23739 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23740 w->phys_cursor.x, w->phys_cursor.y);
23741 UNBLOCK_INPUT;
23742 }
23743 }
23744
23745
23746 /* Call update_window_cursor with parameter ON_P on all leaf windows
23747 in the window tree rooted at W. */
23748
23749 static void
23750 update_cursor_in_window_tree (w, on_p)
23751 struct window *w;
23752 int on_p;
23753 {
23754 while (w)
23755 {
23756 if (!NILP (w->hchild))
23757 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
23758 else if (!NILP (w->vchild))
23759 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
23760 else
23761 update_window_cursor (w, on_p);
23762
23763 w = NILP (w->next) ? 0 : XWINDOW (w->next);
23764 }
23765 }
23766
23767
23768 /* EXPORT:
23769 Display the cursor on window W, or clear it, according to ON_P.
23770 Don't change the cursor's position. */
23771
23772 void
23773 x_update_cursor (f, on_p)
23774 struct frame *f;
23775 int on_p;
23776 {
23777 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
23778 }
23779
23780
23781 /* EXPORT:
23782 Clear the cursor of window W to background color, and mark the
23783 cursor as not shown. This is used when the text where the cursor
23784 is about to be rewritten. */
23785
23786 void
23787 x_clear_cursor (w)
23788 struct window *w;
23789 {
23790 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
23791 update_window_cursor (w, 0);
23792 }
23793
23794
23795 /* EXPORT:
23796 Display the active region described by mouse_face_* according to DRAW. */
23797
23798 void
23799 show_mouse_face (dpyinfo, draw)
23800 Display_Info *dpyinfo;
23801 enum draw_glyphs_face draw;
23802 {
23803 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
23804 struct frame *f = XFRAME (WINDOW_FRAME (w));
23805
23806 if (/* If window is in the process of being destroyed, don't bother
23807 to do anything. */
23808 w->current_matrix != NULL
23809 /* Don't update mouse highlight if hidden */
23810 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
23811 /* Recognize when we are called to operate on rows that don't exist
23812 anymore. This can happen when a window is split. */
23813 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
23814 {
23815 int phys_cursor_on_p = w->phys_cursor_on_p;
23816 struct glyph_row *row, *first, *last;
23817
23818 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
23819 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
23820
23821 for (row = first; row <= last && row->enabled_p; ++row)
23822 {
23823 int start_hpos, end_hpos, start_x;
23824
23825 /* For all but the first row, the highlight starts at column 0. */
23826 if (row == first)
23827 {
23828 start_hpos = dpyinfo->mouse_face_beg_col;
23829 start_x = dpyinfo->mouse_face_beg_x;
23830 }
23831 else
23832 {
23833 start_hpos = 0;
23834 start_x = 0;
23835 }
23836
23837 if (row == last)
23838 end_hpos = dpyinfo->mouse_face_end_col;
23839 else
23840 {
23841 end_hpos = row->used[TEXT_AREA];
23842 if (draw == DRAW_NORMAL_TEXT)
23843 row->fill_line_p = 1; /* Clear to end of line */
23844 }
23845
23846 if (end_hpos > start_hpos)
23847 {
23848 draw_glyphs (w, start_x, row, TEXT_AREA,
23849 start_hpos, end_hpos,
23850 draw, 0);
23851
23852 row->mouse_face_p
23853 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
23854 }
23855 }
23856
23857 /* When we've written over the cursor, arrange for it to
23858 be displayed again. */
23859 if (phys_cursor_on_p && !w->phys_cursor_on_p)
23860 {
23861 BLOCK_INPUT;
23862 display_and_set_cursor (w, 1,
23863 w->phys_cursor.hpos, w->phys_cursor.vpos,
23864 w->phys_cursor.x, w->phys_cursor.y);
23865 UNBLOCK_INPUT;
23866 }
23867 }
23868
23869 /* Change the mouse cursor. */
23870 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
23871 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
23872 else if (draw == DRAW_MOUSE_FACE)
23873 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
23874 else
23875 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
23876 }
23877
23878 /* EXPORT:
23879 Clear out the mouse-highlighted active region.
23880 Redraw it un-highlighted first. Value is non-zero if mouse
23881 face was actually drawn unhighlighted. */
23882
23883 int
23884 clear_mouse_face (dpyinfo)
23885 Display_Info *dpyinfo;
23886 {
23887 int cleared = 0;
23888
23889 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
23890 {
23891 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
23892 cleared = 1;
23893 }
23894
23895 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23896 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23897 dpyinfo->mouse_face_window = Qnil;
23898 dpyinfo->mouse_face_overlay = Qnil;
23899 return cleared;
23900 }
23901
23902
23903 /* EXPORT:
23904 Non-zero if physical cursor of window W is within mouse face. */
23905
23906 int
23907 cursor_in_mouse_face_p (w)
23908 struct window *w;
23909 {
23910 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23911 int in_mouse_face = 0;
23912
23913 if (WINDOWP (dpyinfo->mouse_face_window)
23914 && XWINDOW (dpyinfo->mouse_face_window) == w)
23915 {
23916 int hpos = w->phys_cursor.hpos;
23917 int vpos = w->phys_cursor.vpos;
23918
23919 if (vpos >= dpyinfo->mouse_face_beg_row
23920 && vpos <= dpyinfo->mouse_face_end_row
23921 && (vpos > dpyinfo->mouse_face_beg_row
23922 || hpos >= dpyinfo->mouse_face_beg_col)
23923 && (vpos < dpyinfo->mouse_face_end_row
23924 || hpos < dpyinfo->mouse_face_end_col
23925 || dpyinfo->mouse_face_past_end))
23926 in_mouse_face = 1;
23927 }
23928
23929 return in_mouse_face;
23930 }
23931
23932
23933
23934 \f
23935 /* This function sets the mouse_face_* elements of DPYINFO, assuming
23936 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
23937 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
23938 for the overlay or run of text properties specifying the mouse
23939 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
23940 before-string and after-string that must also be highlighted.
23941 DISPLAY_STRING, if non-nil, is a display string that may cover some
23942 or all of the highlighted text. */
23943
23944 static void
23945 mouse_face_from_buffer_pos (Lisp_Object window,
23946 Display_Info *dpyinfo,
23947 EMACS_INT mouse_charpos,
23948 EMACS_INT start_charpos,
23949 EMACS_INT end_charpos,
23950 Lisp_Object before_string,
23951 Lisp_Object after_string,
23952 Lisp_Object display_string)
23953 {
23954 struct window *w = XWINDOW (window);
23955 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23956 struct glyph_row *row;
23957 struct glyph *glyph, *end;
23958 EMACS_INT ignore;
23959 int x;
23960
23961 xassert (NILP (display_string) || STRINGP (display_string));
23962 xassert (NILP (before_string) || STRINGP (before_string));
23963 xassert (NILP (after_string) || STRINGP (after_string));
23964
23965 /* Find the first highlighted glyph. */
23966 if (start_charpos < MATRIX_ROW_START_CHARPOS (first))
23967 {
23968 dpyinfo->mouse_face_beg_col = 0;
23969 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
23970 dpyinfo->mouse_face_beg_x = first->x;
23971 dpyinfo->mouse_face_beg_y = first->y;
23972 }
23973 else
23974 {
23975 row = row_containing_pos (w, start_charpos, first, NULL, 0);
23976 if (row == NULL)
23977 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23978
23979 /* If the before-string or display-string contains newlines,
23980 row_containing_pos skips to its last row. Move back. */
23981 if (!NILP (before_string) || !NILP (display_string))
23982 {
23983 struct glyph_row *prev;
23984 while ((prev = row - 1, prev >= first)
23985 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
23986 && prev->used[TEXT_AREA] > 0)
23987 {
23988 struct glyph *beg = prev->glyphs[TEXT_AREA];
23989 glyph = beg + prev->used[TEXT_AREA];
23990 while (--glyph >= beg && INTEGERP (glyph->object));
23991 if (glyph < beg
23992 || !(EQ (glyph->object, before_string)
23993 || EQ (glyph->object, display_string)))
23994 break;
23995 row = prev;
23996 }
23997 }
23998
23999 glyph = row->glyphs[TEXT_AREA];
24000 end = glyph + row->used[TEXT_AREA];
24001 x = row->x;
24002 dpyinfo->mouse_face_beg_y = row->y;
24003 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (row, w->current_matrix);
24004
24005 /* Skip truncation glyphs at the start of the glyph row. */
24006 if (row->displays_text_p)
24007 for (; glyph < end
24008 && INTEGERP (glyph->object)
24009 && glyph->charpos < 0;
24010 ++glyph)
24011 x += glyph->pixel_width;
24012
24013 /* Scan the glyph row, stopping before BEFORE_STRING or
24014 DISPLAY_STRING or START_CHARPOS. */
24015 for (; glyph < end
24016 && !INTEGERP (glyph->object)
24017 && !EQ (glyph->object, before_string)
24018 && !EQ (glyph->object, display_string)
24019 && !(BUFFERP (glyph->object)
24020 && glyph->charpos >= start_charpos);
24021 ++glyph)
24022 x += glyph->pixel_width;
24023
24024 dpyinfo->mouse_face_beg_x = x;
24025 dpyinfo->mouse_face_beg_col = glyph - row->glyphs[TEXT_AREA];
24026 }
24027
24028 /* Find the last highlighted glyph. */
24029 row = row_containing_pos (w, end_charpos, first, NULL, 0);
24030 if (row == NULL)
24031 {
24032 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24033 dpyinfo->mouse_face_past_end = 1;
24034 }
24035 else if (!NILP (after_string))
24036 {
24037 /* If the after-string has newlines, advance to its last row. */
24038 struct glyph_row *next;
24039 struct glyph_row *last
24040 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24041
24042 for (next = row + 1;
24043 next <= last
24044 && next->used[TEXT_AREA] > 0
24045 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
24046 ++next)
24047 row = next;
24048 }
24049
24050 glyph = row->glyphs[TEXT_AREA];
24051 end = glyph + row->used[TEXT_AREA];
24052 x = row->x;
24053 dpyinfo->mouse_face_end_y = row->y;
24054 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (row, w->current_matrix);
24055
24056 /* Skip truncation glyphs at the start of the row. */
24057 if (row->displays_text_p)
24058 for (; glyph < end
24059 && INTEGERP (glyph->object)
24060 && glyph->charpos < 0;
24061 ++glyph)
24062 x += glyph->pixel_width;
24063
24064 /* Scan the glyph row, stopping at END_CHARPOS or when we encounter
24065 AFTER_STRING. */
24066 for (; glyph < end
24067 && !INTEGERP (glyph->object)
24068 && !EQ (glyph->object, after_string)
24069 && !(BUFFERP (glyph->object) && glyph->charpos >= end_charpos);
24070 ++glyph)
24071 x += glyph->pixel_width;
24072
24073 /* If we found AFTER_STRING, consume it and stop. */
24074 if (EQ (glyph->object, after_string))
24075 {
24076 for (; EQ (glyph->object, after_string) && glyph < end; ++glyph)
24077 x += glyph->pixel_width;
24078 }
24079 else
24080 {
24081 /* If there's no after-string, we must check if we overshot,
24082 which might be the case if we stopped after a string glyph.
24083 That glyph may belong to a before-string or display-string
24084 associated with the end position, which must not be
24085 highlighted. */
24086 Lisp_Object prev_object;
24087 EMACS_INT pos;
24088
24089 while (glyph > row->glyphs[TEXT_AREA])
24090 {
24091 prev_object = (glyph - 1)->object;
24092 if (!STRINGP (prev_object) || EQ (prev_object, display_string))
24093 break;
24094
24095 pos = string_buffer_position (w, prev_object, end_charpos);
24096 if (pos && pos < end_charpos)
24097 break;
24098
24099 for (; glyph > row->glyphs[TEXT_AREA]
24100 && EQ ((glyph - 1)->object, prev_object);
24101 --glyph)
24102 x -= (glyph - 1)->pixel_width;
24103 }
24104 }
24105
24106 dpyinfo->mouse_face_end_x = x;
24107 dpyinfo->mouse_face_end_col = glyph - row->glyphs[TEXT_AREA];
24108 dpyinfo->mouse_face_window = window;
24109 dpyinfo->mouse_face_face_id
24110 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
24111 mouse_charpos + 1,
24112 !dpyinfo->mouse_face_hidden, -1);
24113 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24114 }
24115
24116
24117 /* Find the position of the glyph for position POS in OBJECT in
24118 window W's current matrix, and return in *X, *Y the pixel
24119 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24120
24121 RIGHT_P non-zero means return the position of the right edge of the
24122 glyph, RIGHT_P zero means return the left edge position.
24123
24124 If no glyph for POS exists in the matrix, return the position of
24125 the glyph with the next smaller position that is in the matrix, if
24126 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24127 exists in the matrix, return the position of the glyph with the
24128 next larger position in OBJECT.
24129
24130 Value is non-zero if a glyph was found. */
24131
24132 static int
24133 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
24134 struct window *w;
24135 EMACS_INT pos;
24136 Lisp_Object object;
24137 int *hpos, *vpos, *x, *y;
24138 int right_p;
24139 {
24140 int yb = window_text_bottom_y (w);
24141 struct glyph_row *r;
24142 struct glyph *best_glyph = NULL;
24143 struct glyph_row *best_row = NULL;
24144 int best_x = 0;
24145
24146 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24147 r->enabled_p && r->y < yb;
24148 ++r)
24149 {
24150 struct glyph *g = r->glyphs[TEXT_AREA];
24151 struct glyph *e = g + r->used[TEXT_AREA];
24152 int gx;
24153
24154 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24155 if (EQ (g->object, object))
24156 {
24157 if (g->charpos == pos)
24158 {
24159 best_glyph = g;
24160 best_x = gx;
24161 best_row = r;
24162 goto found;
24163 }
24164 else if (best_glyph == NULL
24165 || ((eabs (g->charpos - pos)
24166 < eabs (best_glyph->charpos - pos))
24167 && (right_p
24168 ? g->charpos < pos
24169 : g->charpos > pos)))
24170 {
24171 best_glyph = g;
24172 best_x = gx;
24173 best_row = r;
24174 }
24175 }
24176 }
24177
24178 found:
24179
24180 if (best_glyph)
24181 {
24182 *x = best_x;
24183 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24184
24185 if (right_p)
24186 {
24187 *x += best_glyph->pixel_width;
24188 ++*hpos;
24189 }
24190
24191 *y = best_row->y;
24192 *vpos = best_row - w->current_matrix->rows;
24193 }
24194
24195 return best_glyph != NULL;
24196 }
24197
24198
24199 /* See if position X, Y is within a hot-spot of an image. */
24200
24201 static int
24202 on_hot_spot_p (hot_spot, x, y)
24203 Lisp_Object hot_spot;
24204 int x, y;
24205 {
24206 if (!CONSP (hot_spot))
24207 return 0;
24208
24209 if (EQ (XCAR (hot_spot), Qrect))
24210 {
24211 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24212 Lisp_Object rect = XCDR (hot_spot);
24213 Lisp_Object tem;
24214 if (!CONSP (rect))
24215 return 0;
24216 if (!CONSP (XCAR (rect)))
24217 return 0;
24218 if (!CONSP (XCDR (rect)))
24219 return 0;
24220 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24221 return 0;
24222 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24223 return 0;
24224 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24225 return 0;
24226 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24227 return 0;
24228 return 1;
24229 }
24230 else if (EQ (XCAR (hot_spot), Qcircle))
24231 {
24232 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24233 Lisp_Object circ = XCDR (hot_spot);
24234 Lisp_Object lr, lx0, ly0;
24235 if (CONSP (circ)
24236 && CONSP (XCAR (circ))
24237 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24238 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24239 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24240 {
24241 double r = XFLOATINT (lr);
24242 double dx = XINT (lx0) - x;
24243 double dy = XINT (ly0) - y;
24244 return (dx * dx + dy * dy <= r * r);
24245 }
24246 }
24247 else if (EQ (XCAR (hot_spot), Qpoly))
24248 {
24249 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24250 if (VECTORP (XCDR (hot_spot)))
24251 {
24252 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24253 Lisp_Object *poly = v->contents;
24254 int n = v->size;
24255 int i;
24256 int inside = 0;
24257 Lisp_Object lx, ly;
24258 int x0, y0;
24259
24260 /* Need an even number of coordinates, and at least 3 edges. */
24261 if (n < 6 || n & 1)
24262 return 0;
24263
24264 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24265 If count is odd, we are inside polygon. Pixels on edges
24266 may or may not be included depending on actual geometry of the
24267 polygon. */
24268 if ((lx = poly[n-2], !INTEGERP (lx))
24269 || (ly = poly[n-1], !INTEGERP (lx)))
24270 return 0;
24271 x0 = XINT (lx), y0 = XINT (ly);
24272 for (i = 0; i < n; i += 2)
24273 {
24274 int x1 = x0, y1 = y0;
24275 if ((lx = poly[i], !INTEGERP (lx))
24276 || (ly = poly[i+1], !INTEGERP (ly)))
24277 return 0;
24278 x0 = XINT (lx), y0 = XINT (ly);
24279
24280 /* Does this segment cross the X line? */
24281 if (x0 >= x)
24282 {
24283 if (x1 >= x)
24284 continue;
24285 }
24286 else if (x1 < x)
24287 continue;
24288 if (y > y0 && y > y1)
24289 continue;
24290 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
24291 inside = !inside;
24292 }
24293 return inside;
24294 }
24295 }
24296 return 0;
24297 }
24298
24299 Lisp_Object
24300 find_hot_spot (map, x, y)
24301 Lisp_Object map;
24302 int x, y;
24303 {
24304 while (CONSP (map))
24305 {
24306 if (CONSP (XCAR (map))
24307 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
24308 return XCAR (map);
24309 map = XCDR (map);
24310 }
24311
24312 return Qnil;
24313 }
24314
24315 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
24316 3, 3, 0,
24317 doc: /* Lookup in image map MAP coordinates X and Y.
24318 An image map is an alist where each element has the format (AREA ID PLIST).
24319 An AREA is specified as either a rectangle, a circle, or a polygon:
24320 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
24321 pixel coordinates of the upper left and bottom right corners.
24322 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
24323 and the radius of the circle; r may be a float or integer.
24324 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
24325 vector describes one corner in the polygon.
24326 Returns the alist element for the first matching AREA in MAP. */)
24327 (map, x, y)
24328 Lisp_Object map;
24329 Lisp_Object x, y;
24330 {
24331 if (NILP (map))
24332 return Qnil;
24333
24334 CHECK_NUMBER (x);
24335 CHECK_NUMBER (y);
24336
24337 return find_hot_spot (map, XINT (x), XINT (y));
24338 }
24339
24340
24341 /* Display frame CURSOR, optionally using shape defined by POINTER. */
24342 static void
24343 define_frame_cursor1 (f, cursor, pointer)
24344 struct frame *f;
24345 Cursor cursor;
24346 Lisp_Object pointer;
24347 {
24348 /* Do not change cursor shape while dragging mouse. */
24349 if (!NILP (do_mouse_tracking))
24350 return;
24351
24352 if (!NILP (pointer))
24353 {
24354 if (EQ (pointer, Qarrow))
24355 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24356 else if (EQ (pointer, Qhand))
24357 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
24358 else if (EQ (pointer, Qtext))
24359 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24360 else if (EQ (pointer, intern ("hdrag")))
24361 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24362 #ifdef HAVE_X_WINDOWS
24363 else if (EQ (pointer, intern ("vdrag")))
24364 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
24365 #endif
24366 else if (EQ (pointer, intern ("hourglass")))
24367 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
24368 else if (EQ (pointer, Qmodeline))
24369 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
24370 else
24371 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24372 }
24373
24374 if (cursor != No_Cursor)
24375 FRAME_RIF (f)->define_frame_cursor (f, cursor);
24376 }
24377
24378 /* Take proper action when mouse has moved to the mode or header line
24379 or marginal area AREA of window W, x-position X and y-position Y.
24380 X is relative to the start of the text display area of W, so the
24381 width of bitmap areas and scroll bars must be subtracted to get a
24382 position relative to the start of the mode line. */
24383
24384 static void
24385 note_mode_line_or_margin_highlight (window, x, y, area)
24386 Lisp_Object window;
24387 int x, y;
24388 enum window_part area;
24389 {
24390 struct window *w = XWINDOW (window);
24391 struct frame *f = XFRAME (w->frame);
24392 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24393 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24394 Lisp_Object pointer = Qnil;
24395 int charpos, dx, dy, width, height;
24396 Lisp_Object string, object = Qnil;
24397 Lisp_Object pos, help;
24398
24399 Lisp_Object mouse_face;
24400 int original_x_pixel = x;
24401 struct glyph * glyph = NULL, * row_start_glyph = NULL;
24402 struct glyph_row *row;
24403
24404 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
24405 {
24406 int x0;
24407 struct glyph *end;
24408
24409 string = mode_line_string (w, area, &x, &y, &charpos,
24410 &object, &dx, &dy, &width, &height);
24411
24412 row = (area == ON_MODE_LINE
24413 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
24414 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
24415
24416 /* Find glyph */
24417 if (row->mode_line_p && row->enabled_p)
24418 {
24419 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
24420 end = glyph + row->used[TEXT_AREA];
24421
24422 for (x0 = original_x_pixel;
24423 glyph < end && x0 >= glyph->pixel_width;
24424 ++glyph)
24425 x0 -= glyph->pixel_width;
24426
24427 if (glyph >= end)
24428 glyph = NULL;
24429 }
24430 }
24431 else
24432 {
24433 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
24434 string = marginal_area_string (w, area, &x, &y, &charpos,
24435 &object, &dx, &dy, &width, &height);
24436 }
24437
24438 help = Qnil;
24439
24440 if (IMAGEP (object))
24441 {
24442 Lisp_Object image_map, hotspot;
24443 if ((image_map = Fplist_get (XCDR (object), QCmap),
24444 !NILP (image_map))
24445 && (hotspot = find_hot_spot (image_map, dx, dy),
24446 CONSP (hotspot))
24447 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24448 {
24449 Lisp_Object area_id, plist;
24450
24451 area_id = XCAR (hotspot);
24452 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24453 If so, we could look for mouse-enter, mouse-leave
24454 properties in PLIST (and do something...). */
24455 hotspot = XCDR (hotspot);
24456 if (CONSP (hotspot)
24457 && (plist = XCAR (hotspot), CONSP (plist)))
24458 {
24459 pointer = Fplist_get (plist, Qpointer);
24460 if (NILP (pointer))
24461 pointer = Qhand;
24462 help = Fplist_get (plist, Qhelp_echo);
24463 if (!NILP (help))
24464 {
24465 help_echo_string = help;
24466 /* Is this correct? ++kfs */
24467 XSETWINDOW (help_echo_window, w);
24468 help_echo_object = w->buffer;
24469 help_echo_pos = charpos;
24470 }
24471 }
24472 }
24473 if (NILP (pointer))
24474 pointer = Fplist_get (XCDR (object), QCpointer);
24475 }
24476
24477 if (STRINGP (string))
24478 {
24479 pos = make_number (charpos);
24480 /* If we're on a string with `help-echo' text property, arrange
24481 for the help to be displayed. This is done by setting the
24482 global variable help_echo_string to the help string. */
24483 if (NILP (help))
24484 {
24485 help = Fget_text_property (pos, Qhelp_echo, string);
24486 if (!NILP (help))
24487 {
24488 help_echo_string = help;
24489 XSETWINDOW (help_echo_window, w);
24490 help_echo_object = string;
24491 help_echo_pos = charpos;
24492 }
24493 }
24494
24495 if (NILP (pointer))
24496 pointer = Fget_text_property (pos, Qpointer, string);
24497
24498 /* Change the mouse pointer according to what is under X/Y. */
24499 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
24500 {
24501 Lisp_Object map;
24502 map = Fget_text_property (pos, Qlocal_map, string);
24503 if (!KEYMAPP (map))
24504 map = Fget_text_property (pos, Qkeymap, string);
24505 if (!KEYMAPP (map))
24506 cursor = dpyinfo->vertical_scroll_bar_cursor;
24507 }
24508
24509 /* Change the mouse face according to what is under X/Y. */
24510 mouse_face = Fget_text_property (pos, Qmouse_face, string);
24511 if (!NILP (mouse_face)
24512 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24513 && glyph)
24514 {
24515 Lisp_Object b, e;
24516
24517 struct glyph * tmp_glyph;
24518
24519 int gpos;
24520 int gseq_length;
24521 int total_pixel_width;
24522 EMACS_INT ignore;
24523
24524 int vpos, hpos;
24525
24526 b = Fprevious_single_property_change (make_number (charpos + 1),
24527 Qmouse_face, string, Qnil);
24528 if (NILP (b))
24529 b = make_number (0);
24530
24531 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
24532 if (NILP (e))
24533 e = make_number (SCHARS (string));
24534
24535 /* Calculate the position(glyph position: GPOS) of GLYPH in
24536 displayed string. GPOS is different from CHARPOS.
24537
24538 CHARPOS is the position of glyph in internal string
24539 object. A mode line string format has structures which
24540 is converted to a flatten by emacs lisp interpreter.
24541 The internal string is an element of the structures.
24542 The displayed string is the flatten string. */
24543 gpos = 0;
24544 if (glyph > row_start_glyph)
24545 {
24546 tmp_glyph = glyph - 1;
24547 while (tmp_glyph >= row_start_glyph
24548 && tmp_glyph->charpos >= XINT (b)
24549 && EQ (tmp_glyph->object, glyph->object))
24550 {
24551 tmp_glyph--;
24552 gpos++;
24553 }
24554 }
24555
24556 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
24557 displayed string holding GLYPH.
24558
24559 GSEQ_LENGTH is different from SCHARS (STRING).
24560 SCHARS (STRING) returns the length of the internal string. */
24561 for (tmp_glyph = glyph, gseq_length = gpos;
24562 tmp_glyph->charpos < XINT (e);
24563 tmp_glyph++, gseq_length++)
24564 {
24565 if (!EQ (tmp_glyph->object, glyph->object))
24566 break;
24567 }
24568
24569 total_pixel_width = 0;
24570 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
24571 total_pixel_width += tmp_glyph->pixel_width;
24572
24573 /* Pre calculation of re-rendering position */
24574 vpos = (x - gpos);
24575 hpos = (area == ON_MODE_LINE
24576 ? (w->current_matrix)->nrows - 1
24577 : 0);
24578
24579 /* If the re-rendering position is included in the last
24580 re-rendering area, we should do nothing. */
24581 if ( EQ (window, dpyinfo->mouse_face_window)
24582 && dpyinfo->mouse_face_beg_col <= vpos
24583 && vpos < dpyinfo->mouse_face_end_col
24584 && dpyinfo->mouse_face_beg_row == hpos )
24585 return;
24586
24587 if (clear_mouse_face (dpyinfo))
24588 cursor = No_Cursor;
24589
24590 dpyinfo->mouse_face_beg_col = vpos;
24591 dpyinfo->mouse_face_beg_row = hpos;
24592
24593 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
24594 dpyinfo->mouse_face_beg_y = 0;
24595
24596 dpyinfo->mouse_face_end_col = vpos + gseq_length;
24597 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
24598
24599 dpyinfo->mouse_face_end_x = 0;
24600 dpyinfo->mouse_face_end_y = 0;
24601
24602 dpyinfo->mouse_face_past_end = 0;
24603 dpyinfo->mouse_face_window = window;
24604
24605 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
24606 charpos,
24607 0, 0, 0, &ignore,
24608 glyph->face_id, 1);
24609 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24610
24611 if (NILP (pointer))
24612 pointer = Qhand;
24613 }
24614 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24615 clear_mouse_face (dpyinfo);
24616 }
24617 define_frame_cursor1 (f, cursor, pointer);
24618 }
24619
24620
24621 /* EXPORT:
24622 Take proper action when the mouse has moved to position X, Y on
24623 frame F as regards highlighting characters that have mouse-face
24624 properties. Also de-highlighting chars where the mouse was before.
24625 X and Y can be negative or out of range. */
24626
24627 void
24628 note_mouse_highlight (f, x, y)
24629 struct frame *f;
24630 int x, y;
24631 {
24632 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24633 enum window_part part;
24634 Lisp_Object window;
24635 struct window *w;
24636 Cursor cursor = No_Cursor;
24637 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
24638 struct buffer *b;
24639
24640 /* When a menu is active, don't highlight because this looks odd. */
24641 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
24642 if (popup_activated ())
24643 return;
24644 #endif
24645
24646 if (NILP (Vmouse_highlight)
24647 || !f->glyphs_initialized_p
24648 || f->pointer_invisible)
24649 return;
24650
24651 dpyinfo->mouse_face_mouse_x = x;
24652 dpyinfo->mouse_face_mouse_y = y;
24653 dpyinfo->mouse_face_mouse_frame = f;
24654
24655 if (dpyinfo->mouse_face_defer)
24656 return;
24657
24658 if (gc_in_progress)
24659 {
24660 dpyinfo->mouse_face_deferred_gc = 1;
24661 return;
24662 }
24663
24664 /* Which window is that in? */
24665 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
24666
24667 /* If we were displaying active text in another window, clear that.
24668 Also clear if we move out of text area in same window. */
24669 if (! EQ (window, dpyinfo->mouse_face_window)
24670 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
24671 && !NILP (dpyinfo->mouse_face_window)))
24672 clear_mouse_face (dpyinfo);
24673
24674 /* Not on a window -> return. */
24675 if (!WINDOWP (window))
24676 return;
24677
24678 /* Reset help_echo_string. It will get recomputed below. */
24679 help_echo_string = Qnil;
24680
24681 /* Convert to window-relative pixel coordinates. */
24682 w = XWINDOW (window);
24683 frame_to_window_pixel_xy (w, &x, &y);
24684
24685 /* Handle tool-bar window differently since it doesn't display a
24686 buffer. */
24687 if (EQ (window, f->tool_bar_window))
24688 {
24689 note_tool_bar_highlight (f, x, y);
24690 return;
24691 }
24692
24693 /* Mouse is on the mode, header line or margin? */
24694 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
24695 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
24696 {
24697 note_mode_line_or_margin_highlight (window, x, y, part);
24698 return;
24699 }
24700
24701 if (part == ON_VERTICAL_BORDER)
24702 {
24703 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24704 help_echo_string = build_string ("drag-mouse-1: resize");
24705 }
24706 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
24707 || part == ON_SCROLL_BAR)
24708 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24709 else
24710 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24711
24712 /* Are we in a window whose display is up to date?
24713 And verify the buffer's text has not changed. */
24714 b = XBUFFER (w->buffer);
24715 if (part == ON_TEXT
24716 && EQ (w->window_end_valid, w->buffer)
24717 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
24718 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
24719 {
24720 int hpos, vpos, i, dx, dy, area;
24721 EMACS_INT pos;
24722 struct glyph *glyph;
24723 Lisp_Object object;
24724 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
24725 Lisp_Object *overlay_vec = NULL;
24726 int noverlays;
24727 struct buffer *obuf;
24728 int obegv, ozv, same_region;
24729
24730 /* Find the glyph under X/Y. */
24731 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
24732
24733 /* Look for :pointer property on image. */
24734 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24735 {
24736 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24737 if (img != NULL && IMAGEP (img->spec))
24738 {
24739 Lisp_Object image_map, hotspot;
24740 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
24741 !NILP (image_map))
24742 && (hotspot = find_hot_spot (image_map,
24743 glyph->slice.x + dx,
24744 glyph->slice.y + dy),
24745 CONSP (hotspot))
24746 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24747 {
24748 Lisp_Object area_id, plist;
24749
24750 area_id = XCAR (hotspot);
24751 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24752 If so, we could look for mouse-enter, mouse-leave
24753 properties in PLIST (and do something...). */
24754 hotspot = XCDR (hotspot);
24755 if (CONSP (hotspot)
24756 && (plist = XCAR (hotspot), CONSP (plist)))
24757 {
24758 pointer = Fplist_get (plist, Qpointer);
24759 if (NILP (pointer))
24760 pointer = Qhand;
24761 help_echo_string = Fplist_get (plist, Qhelp_echo);
24762 if (!NILP (help_echo_string))
24763 {
24764 help_echo_window = window;
24765 help_echo_object = glyph->object;
24766 help_echo_pos = glyph->charpos;
24767 }
24768 }
24769 }
24770 if (NILP (pointer))
24771 pointer = Fplist_get (XCDR (img->spec), QCpointer);
24772 }
24773 }
24774
24775 /* Clear mouse face if X/Y not over text. */
24776 if (glyph == NULL
24777 || area != TEXT_AREA
24778 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
24779 {
24780 if (clear_mouse_face (dpyinfo))
24781 cursor = No_Cursor;
24782 if (NILP (pointer))
24783 {
24784 if (area != TEXT_AREA)
24785 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24786 else
24787 pointer = Vvoid_text_area_pointer;
24788 }
24789 goto set_cursor;
24790 }
24791
24792 pos = glyph->charpos;
24793 object = glyph->object;
24794 if (!STRINGP (object) && !BUFFERP (object))
24795 goto set_cursor;
24796
24797 /* If we get an out-of-range value, return now; avoid an error. */
24798 if (BUFFERP (object) && pos > BUF_Z (b))
24799 goto set_cursor;
24800
24801 /* Make the window's buffer temporarily current for
24802 overlays_at and compute_char_face. */
24803 obuf = current_buffer;
24804 current_buffer = b;
24805 obegv = BEGV;
24806 ozv = ZV;
24807 BEGV = BEG;
24808 ZV = Z;
24809
24810 /* Is this char mouse-active or does it have help-echo? */
24811 position = make_number (pos);
24812
24813 if (BUFFERP (object))
24814 {
24815 /* Put all the overlays we want in a vector in overlay_vec. */
24816 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
24817 /* Sort overlays into increasing priority order. */
24818 noverlays = sort_overlays (overlay_vec, noverlays, w);
24819 }
24820 else
24821 noverlays = 0;
24822
24823 same_region = (EQ (window, dpyinfo->mouse_face_window)
24824 && vpos >= dpyinfo->mouse_face_beg_row
24825 && vpos <= dpyinfo->mouse_face_end_row
24826 && (vpos > dpyinfo->mouse_face_beg_row
24827 || hpos >= dpyinfo->mouse_face_beg_col)
24828 && (vpos < dpyinfo->mouse_face_end_row
24829 || hpos < dpyinfo->mouse_face_end_col
24830 || dpyinfo->mouse_face_past_end));
24831
24832 if (same_region)
24833 cursor = No_Cursor;
24834
24835 /* Check mouse-face highlighting. */
24836 if (! same_region
24837 /* If there exists an overlay with mouse-face overlapping
24838 the one we are currently highlighting, we have to
24839 check if we enter the overlapping overlay, and then
24840 highlight only that. */
24841 || (OVERLAYP (dpyinfo->mouse_face_overlay)
24842 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
24843 {
24844 /* Find the highest priority overlay with a mouse-face. */
24845 overlay = Qnil;
24846 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
24847 {
24848 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
24849 if (!NILP (mouse_face))
24850 overlay = overlay_vec[i];
24851 }
24852
24853 /* If we're highlighting the same overlay as before, there's
24854 no need to do that again. */
24855 if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
24856 goto check_help_echo;
24857 dpyinfo->mouse_face_overlay = overlay;
24858
24859 /* Clear the display of the old active region, if any. */
24860 if (clear_mouse_face (dpyinfo))
24861 cursor = No_Cursor;
24862
24863 /* If no overlay applies, get a text property. */
24864 if (NILP (overlay))
24865 mouse_face = Fget_text_property (position, Qmouse_face, object);
24866
24867 /* Next, compute the bounds of the mouse highlighting and
24868 display it. */
24869 if (!NILP (mouse_face) && STRINGP (object))
24870 {
24871 /* The mouse-highlighting comes from a display string
24872 with a mouse-face. */
24873 Lisp_Object b, e;
24874 EMACS_INT ignore;
24875
24876 b = Fprevious_single_property_change
24877 (make_number (pos + 1), Qmouse_face, object, Qnil);
24878 e = Fnext_single_property_change
24879 (position, Qmouse_face, object, Qnil);
24880 if (NILP (b))
24881 b = make_number (0);
24882 if (NILP (e))
24883 e = make_number (SCHARS (object) - 1);
24884
24885 fast_find_string_pos (w, XINT (b), object,
24886 &dpyinfo->mouse_face_beg_col,
24887 &dpyinfo->mouse_face_beg_row,
24888 &dpyinfo->mouse_face_beg_x,
24889 &dpyinfo->mouse_face_beg_y, 0);
24890 fast_find_string_pos (w, XINT (e), object,
24891 &dpyinfo->mouse_face_end_col,
24892 &dpyinfo->mouse_face_end_row,
24893 &dpyinfo->mouse_face_end_x,
24894 &dpyinfo->mouse_face_end_y, 1);
24895 dpyinfo->mouse_face_past_end = 0;
24896 dpyinfo->mouse_face_window = window;
24897 dpyinfo->mouse_face_face_id
24898 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
24899 glyph->face_id, 1);
24900 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24901 cursor = No_Cursor;
24902 }
24903 else
24904 {
24905 /* The mouse-highlighting, if any, comes from an overlay
24906 or text property in the buffer. */
24907 Lisp_Object buffer, display_string;
24908
24909 if (STRINGP (object))
24910 {
24911 /* If we are on a display string with no mouse-face,
24912 check if the text under it has one. */
24913 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
24914 int start = MATRIX_ROW_START_CHARPOS (r);
24915 pos = string_buffer_position (w, object, start);
24916 if (pos > 0)
24917 {
24918 mouse_face = get_char_property_and_overlay
24919 (make_number (pos), Qmouse_face, w->buffer, &overlay);
24920 buffer = w->buffer;
24921 display_string = object;
24922 }
24923 }
24924 else
24925 {
24926 buffer = object;
24927 display_string = Qnil;
24928 }
24929
24930 if (!NILP (mouse_face))
24931 {
24932 Lisp_Object before, after;
24933 Lisp_Object before_string, after_string;
24934
24935 if (NILP (overlay))
24936 {
24937 /* Handle the text property case. */
24938 before = Fprevious_single_property_change
24939 (make_number (pos + 1), Qmouse_face, buffer,
24940 Fmarker_position (w->start));
24941 after = Fnext_single_property_change
24942 (make_number (pos), Qmouse_face, buffer,
24943 make_number (BUF_Z (XBUFFER (buffer))
24944 - XFASTINT (w->window_end_pos)));
24945 before_string = after_string = Qnil;
24946 }
24947 else
24948 {
24949 /* Handle the overlay case. */
24950 before = Foverlay_start (overlay);
24951 after = Foverlay_end (overlay);
24952 before_string = Foverlay_get (overlay, Qbefore_string);
24953 after_string = Foverlay_get (overlay, Qafter_string);
24954
24955 if (!STRINGP (before_string)) before_string = Qnil;
24956 if (!STRINGP (after_string)) after_string = Qnil;
24957 }
24958
24959 mouse_face_from_buffer_pos (window, dpyinfo, pos,
24960 XFASTINT (before),
24961 XFASTINT (after),
24962 before_string, after_string,
24963 display_string);
24964 cursor = No_Cursor;
24965 }
24966 }
24967 }
24968
24969 check_help_echo:
24970
24971 /* Look for a `help-echo' property. */
24972 if (NILP (help_echo_string)) {
24973 Lisp_Object help, overlay;
24974
24975 /* Check overlays first. */
24976 help = overlay = Qnil;
24977 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
24978 {
24979 overlay = overlay_vec[i];
24980 help = Foverlay_get (overlay, Qhelp_echo);
24981 }
24982
24983 if (!NILP (help))
24984 {
24985 help_echo_string = help;
24986 help_echo_window = window;
24987 help_echo_object = overlay;
24988 help_echo_pos = pos;
24989 }
24990 else
24991 {
24992 Lisp_Object object = glyph->object;
24993 int charpos = glyph->charpos;
24994
24995 /* Try text properties. */
24996 if (STRINGP (object)
24997 && charpos >= 0
24998 && charpos < SCHARS (object))
24999 {
25000 help = Fget_text_property (make_number (charpos),
25001 Qhelp_echo, object);
25002 if (NILP (help))
25003 {
25004 /* If the string itself doesn't specify a help-echo,
25005 see if the buffer text ``under'' it does. */
25006 struct glyph_row *r
25007 = MATRIX_ROW (w->current_matrix, vpos);
25008 int start = MATRIX_ROW_START_CHARPOS (r);
25009 EMACS_INT pos = string_buffer_position (w, object, start);
25010 if (pos > 0)
25011 {
25012 help = Fget_char_property (make_number (pos),
25013 Qhelp_echo, w->buffer);
25014 if (!NILP (help))
25015 {
25016 charpos = pos;
25017 object = w->buffer;
25018 }
25019 }
25020 }
25021 }
25022 else if (BUFFERP (object)
25023 && charpos >= BEGV
25024 && charpos < ZV)
25025 help = Fget_text_property (make_number (charpos), Qhelp_echo,
25026 object);
25027
25028 if (!NILP (help))
25029 {
25030 help_echo_string = help;
25031 help_echo_window = window;
25032 help_echo_object = object;
25033 help_echo_pos = charpos;
25034 }
25035 }
25036 }
25037
25038 /* Look for a `pointer' property. */
25039 if (NILP (pointer))
25040 {
25041 /* Check overlays first. */
25042 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
25043 pointer = Foverlay_get (overlay_vec[i], Qpointer);
25044
25045 if (NILP (pointer))
25046 {
25047 Lisp_Object object = glyph->object;
25048 int charpos = glyph->charpos;
25049
25050 /* Try text properties. */
25051 if (STRINGP (object)
25052 && charpos >= 0
25053 && charpos < SCHARS (object))
25054 {
25055 pointer = Fget_text_property (make_number (charpos),
25056 Qpointer, object);
25057 if (NILP (pointer))
25058 {
25059 /* If the string itself doesn't specify a pointer,
25060 see if the buffer text ``under'' it does. */
25061 struct glyph_row *r
25062 = MATRIX_ROW (w->current_matrix, vpos);
25063 int start = MATRIX_ROW_START_CHARPOS (r);
25064 EMACS_INT pos = string_buffer_position (w, object,
25065 start);
25066 if (pos > 0)
25067 pointer = Fget_char_property (make_number (pos),
25068 Qpointer, w->buffer);
25069 }
25070 }
25071 else if (BUFFERP (object)
25072 && charpos >= BEGV
25073 && charpos < ZV)
25074 pointer = Fget_text_property (make_number (charpos),
25075 Qpointer, object);
25076 }
25077 }
25078
25079 BEGV = obegv;
25080 ZV = ozv;
25081 current_buffer = obuf;
25082 }
25083
25084 set_cursor:
25085
25086 define_frame_cursor1 (f, cursor, pointer);
25087 }
25088
25089
25090 /* EXPORT for RIF:
25091 Clear any mouse-face on window W. This function is part of the
25092 redisplay interface, and is called from try_window_id and similar
25093 functions to ensure the mouse-highlight is off. */
25094
25095 void
25096 x_clear_window_mouse_face (w)
25097 struct window *w;
25098 {
25099 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
25100 Lisp_Object window;
25101
25102 BLOCK_INPUT;
25103 XSETWINDOW (window, w);
25104 if (EQ (window, dpyinfo->mouse_face_window))
25105 clear_mouse_face (dpyinfo);
25106 UNBLOCK_INPUT;
25107 }
25108
25109
25110 /* EXPORT:
25111 Just discard the mouse face information for frame F, if any.
25112 This is used when the size of F is changed. */
25113
25114 void
25115 cancel_mouse_face (f)
25116 struct frame *f;
25117 {
25118 Lisp_Object window;
25119 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
25120
25121 window = dpyinfo->mouse_face_window;
25122 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
25123 {
25124 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
25125 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
25126 dpyinfo->mouse_face_window = Qnil;
25127 }
25128 }
25129
25130
25131 #endif /* HAVE_WINDOW_SYSTEM */
25132
25133 \f
25134 /***********************************************************************
25135 Exposure Events
25136 ***********************************************************************/
25137
25138 #ifdef HAVE_WINDOW_SYSTEM
25139
25140 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25141 which intersects rectangle R. R is in window-relative coordinates. */
25142
25143 static void
25144 expose_area (w, row, r, area)
25145 struct window *w;
25146 struct glyph_row *row;
25147 XRectangle *r;
25148 enum glyph_row_area area;
25149 {
25150 struct glyph *first = row->glyphs[area];
25151 struct glyph *end = row->glyphs[area] + row->used[area];
25152 struct glyph *last;
25153 int first_x, start_x, x;
25154
25155 if (area == TEXT_AREA && row->fill_line_p)
25156 /* If row extends face to end of line write the whole line. */
25157 draw_glyphs (w, 0, row, area,
25158 0, row->used[area],
25159 DRAW_NORMAL_TEXT, 0);
25160 else
25161 {
25162 /* Set START_X to the window-relative start position for drawing glyphs of
25163 AREA. The first glyph of the text area can be partially visible.
25164 The first glyphs of other areas cannot. */
25165 start_x = window_box_left_offset (w, area);
25166 x = start_x;
25167 if (area == TEXT_AREA)
25168 x += row->x;
25169
25170 /* Find the first glyph that must be redrawn. */
25171 while (first < end
25172 && x + first->pixel_width < r->x)
25173 {
25174 x += first->pixel_width;
25175 ++first;
25176 }
25177
25178 /* Find the last one. */
25179 last = first;
25180 first_x = x;
25181 while (last < end
25182 && x < r->x + r->width)
25183 {
25184 x += last->pixel_width;
25185 ++last;
25186 }
25187
25188 /* Repaint. */
25189 if (last > first)
25190 draw_glyphs (w, first_x - start_x, row, area,
25191 first - row->glyphs[area], last - row->glyphs[area],
25192 DRAW_NORMAL_TEXT, 0);
25193 }
25194 }
25195
25196
25197 /* Redraw the parts of the glyph row ROW on window W intersecting
25198 rectangle R. R is in window-relative coordinates. Value is
25199 non-zero if mouse-face was overwritten. */
25200
25201 static int
25202 expose_line (w, row, r)
25203 struct window *w;
25204 struct glyph_row *row;
25205 XRectangle *r;
25206 {
25207 xassert (row->enabled_p);
25208
25209 if (row->mode_line_p || w->pseudo_window_p)
25210 draw_glyphs (w, 0, row, TEXT_AREA,
25211 0, row->used[TEXT_AREA],
25212 DRAW_NORMAL_TEXT, 0);
25213 else
25214 {
25215 if (row->used[LEFT_MARGIN_AREA])
25216 expose_area (w, row, r, LEFT_MARGIN_AREA);
25217 if (row->used[TEXT_AREA])
25218 expose_area (w, row, r, TEXT_AREA);
25219 if (row->used[RIGHT_MARGIN_AREA])
25220 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25221 draw_row_fringe_bitmaps (w, row);
25222 }
25223
25224 return row->mouse_face_p;
25225 }
25226
25227
25228 /* Redraw those parts of glyphs rows during expose event handling that
25229 overlap other rows. Redrawing of an exposed line writes over parts
25230 of lines overlapping that exposed line; this function fixes that.
25231
25232 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25233 row in W's current matrix that is exposed and overlaps other rows.
25234 LAST_OVERLAPPING_ROW is the last such row. */
25235
25236 static void
25237 expose_overlaps (w, first_overlapping_row, last_overlapping_row, r)
25238 struct window *w;
25239 struct glyph_row *first_overlapping_row;
25240 struct glyph_row *last_overlapping_row;
25241 XRectangle *r;
25242 {
25243 struct glyph_row *row;
25244
25245 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
25246 if (row->overlapping_p)
25247 {
25248 xassert (row->enabled_p && !row->mode_line_p);
25249
25250 row->clip = r;
25251 if (row->used[LEFT_MARGIN_AREA])
25252 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
25253
25254 if (row->used[TEXT_AREA])
25255 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
25256
25257 if (row->used[RIGHT_MARGIN_AREA])
25258 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
25259 row->clip = NULL;
25260 }
25261 }
25262
25263
25264 /* Return non-zero if W's cursor intersects rectangle R. */
25265
25266 static int
25267 phys_cursor_in_rect_p (w, r)
25268 struct window *w;
25269 XRectangle *r;
25270 {
25271 XRectangle cr, result;
25272 struct glyph *cursor_glyph;
25273 struct glyph_row *row;
25274
25275 if (w->phys_cursor.vpos >= 0
25276 && w->phys_cursor.vpos < w->current_matrix->nrows
25277 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
25278 row->enabled_p)
25279 && row->cursor_in_fringe_p)
25280 {
25281 /* Cursor is in the fringe. */
25282 cr.x = window_box_right_offset (w,
25283 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
25284 ? RIGHT_MARGIN_AREA
25285 : TEXT_AREA));
25286 cr.y = row->y;
25287 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
25288 cr.height = row->height;
25289 return x_intersect_rectangles (&cr, r, &result);
25290 }
25291
25292 cursor_glyph = get_phys_cursor_glyph (w);
25293 if (cursor_glyph)
25294 {
25295 /* r is relative to W's box, but w->phys_cursor.x is relative
25296 to left edge of W's TEXT area. Adjust it. */
25297 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
25298 cr.y = w->phys_cursor.y;
25299 cr.width = cursor_glyph->pixel_width;
25300 cr.height = w->phys_cursor_height;
25301 /* ++KFS: W32 version used W32-specific IntersectRect here, but
25302 I assume the effect is the same -- and this is portable. */
25303 return x_intersect_rectangles (&cr, r, &result);
25304 }
25305 /* If we don't understand the format, pretend we're not in the hot-spot. */
25306 return 0;
25307 }
25308
25309
25310 /* EXPORT:
25311 Draw a vertical window border to the right of window W if W doesn't
25312 have vertical scroll bars. */
25313
25314 void
25315 x_draw_vertical_border (w)
25316 struct window *w;
25317 {
25318 struct frame *f = XFRAME (WINDOW_FRAME (w));
25319
25320 /* We could do better, if we knew what type of scroll-bar the adjacent
25321 windows (on either side) have... But we don't :-(
25322 However, I think this works ok. ++KFS 2003-04-25 */
25323
25324 /* Redraw borders between horizontally adjacent windows. Don't
25325 do it for frames with vertical scroll bars because either the
25326 right scroll bar of a window, or the left scroll bar of its
25327 neighbor will suffice as a border. */
25328 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
25329 return;
25330
25331 if (!WINDOW_RIGHTMOST_P (w)
25332 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
25333 {
25334 int x0, x1, y0, y1;
25335
25336 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25337 y1 -= 1;
25338
25339 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25340 x1 -= 1;
25341
25342 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
25343 }
25344 else if (!WINDOW_LEFTMOST_P (w)
25345 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
25346 {
25347 int x0, x1, y0, y1;
25348
25349 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25350 y1 -= 1;
25351
25352 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25353 x0 -= 1;
25354
25355 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
25356 }
25357 }
25358
25359
25360 /* Redraw the part of window W intersection rectangle FR. Pixel
25361 coordinates in FR are frame-relative. Call this function with
25362 input blocked. Value is non-zero if the exposure overwrites
25363 mouse-face. */
25364
25365 static int
25366 expose_window (w, fr)
25367 struct window *w;
25368 XRectangle *fr;
25369 {
25370 struct frame *f = XFRAME (w->frame);
25371 XRectangle wr, r;
25372 int mouse_face_overwritten_p = 0;
25373
25374 /* If window is not yet fully initialized, do nothing. This can
25375 happen when toolkit scroll bars are used and a window is split.
25376 Reconfiguring the scroll bar will generate an expose for a newly
25377 created window. */
25378 if (w->current_matrix == NULL)
25379 return 0;
25380
25381 /* When we're currently updating the window, display and current
25382 matrix usually don't agree. Arrange for a thorough display
25383 later. */
25384 if (w == updated_window)
25385 {
25386 SET_FRAME_GARBAGED (f);
25387 return 0;
25388 }
25389
25390 /* Frame-relative pixel rectangle of W. */
25391 wr.x = WINDOW_LEFT_EDGE_X (w);
25392 wr.y = WINDOW_TOP_EDGE_Y (w);
25393 wr.width = WINDOW_TOTAL_WIDTH (w);
25394 wr.height = WINDOW_TOTAL_HEIGHT (w);
25395
25396 if (x_intersect_rectangles (fr, &wr, &r))
25397 {
25398 int yb = window_text_bottom_y (w);
25399 struct glyph_row *row;
25400 int cursor_cleared_p;
25401 struct glyph_row *first_overlapping_row, *last_overlapping_row;
25402
25403 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
25404 r.x, r.y, r.width, r.height));
25405
25406 /* Convert to window coordinates. */
25407 r.x -= WINDOW_LEFT_EDGE_X (w);
25408 r.y -= WINDOW_TOP_EDGE_Y (w);
25409
25410 /* Turn off the cursor. */
25411 if (!w->pseudo_window_p
25412 && phys_cursor_in_rect_p (w, &r))
25413 {
25414 x_clear_cursor (w);
25415 cursor_cleared_p = 1;
25416 }
25417 else
25418 cursor_cleared_p = 0;
25419
25420 /* Update lines intersecting rectangle R. */
25421 first_overlapping_row = last_overlapping_row = NULL;
25422 for (row = w->current_matrix->rows;
25423 row->enabled_p;
25424 ++row)
25425 {
25426 int y0 = row->y;
25427 int y1 = MATRIX_ROW_BOTTOM_Y (row);
25428
25429 if ((y0 >= r.y && y0 < r.y + r.height)
25430 || (y1 > r.y && y1 < r.y + r.height)
25431 || (r.y >= y0 && r.y < y1)
25432 || (r.y + r.height > y0 && r.y + r.height < y1))
25433 {
25434 /* A header line may be overlapping, but there is no need
25435 to fix overlapping areas for them. KFS 2005-02-12 */
25436 if (row->overlapping_p && !row->mode_line_p)
25437 {
25438 if (first_overlapping_row == NULL)
25439 first_overlapping_row = row;
25440 last_overlapping_row = row;
25441 }
25442
25443 row->clip = fr;
25444 if (expose_line (w, row, &r))
25445 mouse_face_overwritten_p = 1;
25446 row->clip = NULL;
25447 }
25448 else if (row->overlapping_p)
25449 {
25450 /* We must redraw a row overlapping the exposed area. */
25451 if (y0 < r.y
25452 ? y0 + row->phys_height > r.y
25453 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
25454 {
25455 if (first_overlapping_row == NULL)
25456 first_overlapping_row = row;
25457 last_overlapping_row = row;
25458 }
25459 }
25460
25461 if (y1 >= yb)
25462 break;
25463 }
25464
25465 /* Display the mode line if there is one. */
25466 if (WINDOW_WANTS_MODELINE_P (w)
25467 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
25468 row->enabled_p)
25469 && row->y < r.y + r.height)
25470 {
25471 if (expose_line (w, row, &r))
25472 mouse_face_overwritten_p = 1;
25473 }
25474
25475 if (!w->pseudo_window_p)
25476 {
25477 /* Fix the display of overlapping rows. */
25478 if (first_overlapping_row)
25479 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
25480 fr);
25481
25482 /* Draw border between windows. */
25483 x_draw_vertical_border (w);
25484
25485 /* Turn the cursor on again. */
25486 if (cursor_cleared_p)
25487 update_window_cursor (w, 1);
25488 }
25489 }
25490
25491 return mouse_face_overwritten_p;
25492 }
25493
25494
25495
25496 /* Redraw (parts) of all windows in the window tree rooted at W that
25497 intersect R. R contains frame pixel coordinates. Value is
25498 non-zero if the exposure overwrites mouse-face. */
25499
25500 static int
25501 expose_window_tree (w, r)
25502 struct window *w;
25503 XRectangle *r;
25504 {
25505 struct frame *f = XFRAME (w->frame);
25506 int mouse_face_overwritten_p = 0;
25507
25508 while (w && !FRAME_GARBAGED_P (f))
25509 {
25510 if (!NILP (w->hchild))
25511 mouse_face_overwritten_p
25512 |= expose_window_tree (XWINDOW (w->hchild), r);
25513 else if (!NILP (w->vchild))
25514 mouse_face_overwritten_p
25515 |= expose_window_tree (XWINDOW (w->vchild), r);
25516 else
25517 mouse_face_overwritten_p |= expose_window (w, r);
25518
25519 w = NILP (w->next) ? NULL : XWINDOW (w->next);
25520 }
25521
25522 return mouse_face_overwritten_p;
25523 }
25524
25525
25526 /* EXPORT:
25527 Redisplay an exposed area of frame F. X and Y are the upper-left
25528 corner of the exposed rectangle. W and H are width and height of
25529 the exposed area. All are pixel values. W or H zero means redraw
25530 the entire frame. */
25531
25532 void
25533 expose_frame (f, x, y, w, h)
25534 struct frame *f;
25535 int x, y, w, h;
25536 {
25537 XRectangle r;
25538 int mouse_face_overwritten_p = 0;
25539
25540 TRACE ((stderr, "expose_frame "));
25541
25542 /* No need to redraw if frame will be redrawn soon. */
25543 if (FRAME_GARBAGED_P (f))
25544 {
25545 TRACE ((stderr, " garbaged\n"));
25546 return;
25547 }
25548
25549 /* If basic faces haven't been realized yet, there is no point in
25550 trying to redraw anything. This can happen when we get an expose
25551 event while Emacs is starting, e.g. by moving another window. */
25552 if (FRAME_FACE_CACHE (f) == NULL
25553 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
25554 {
25555 TRACE ((stderr, " no faces\n"));
25556 return;
25557 }
25558
25559 if (w == 0 || h == 0)
25560 {
25561 r.x = r.y = 0;
25562 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
25563 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
25564 }
25565 else
25566 {
25567 r.x = x;
25568 r.y = y;
25569 r.width = w;
25570 r.height = h;
25571 }
25572
25573 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
25574 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
25575
25576 if (WINDOWP (f->tool_bar_window))
25577 mouse_face_overwritten_p
25578 |= expose_window (XWINDOW (f->tool_bar_window), &r);
25579
25580 #ifdef HAVE_X_WINDOWS
25581 #ifndef MSDOS
25582 #ifndef USE_X_TOOLKIT
25583 if (WINDOWP (f->menu_bar_window))
25584 mouse_face_overwritten_p
25585 |= expose_window (XWINDOW (f->menu_bar_window), &r);
25586 #endif /* not USE_X_TOOLKIT */
25587 #endif
25588 #endif
25589
25590 /* Some window managers support a focus-follows-mouse style with
25591 delayed raising of frames. Imagine a partially obscured frame,
25592 and moving the mouse into partially obscured mouse-face on that
25593 frame. The visible part of the mouse-face will be highlighted,
25594 then the WM raises the obscured frame. With at least one WM, KDE
25595 2.1, Emacs is not getting any event for the raising of the frame
25596 (even tried with SubstructureRedirectMask), only Expose events.
25597 These expose events will draw text normally, i.e. not
25598 highlighted. Which means we must redo the highlight here.
25599 Subsume it under ``we love X''. --gerd 2001-08-15 */
25600 /* Included in Windows version because Windows most likely does not
25601 do the right thing if any third party tool offers
25602 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
25603 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
25604 {
25605 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
25606 if (f == dpyinfo->mouse_face_mouse_frame)
25607 {
25608 int x = dpyinfo->mouse_face_mouse_x;
25609 int y = dpyinfo->mouse_face_mouse_y;
25610 clear_mouse_face (dpyinfo);
25611 note_mouse_highlight (f, x, y);
25612 }
25613 }
25614 }
25615
25616
25617 /* EXPORT:
25618 Determine the intersection of two rectangles R1 and R2. Return
25619 the intersection in *RESULT. Value is non-zero if RESULT is not
25620 empty. */
25621
25622 int
25623 x_intersect_rectangles (r1, r2, result)
25624 XRectangle *r1, *r2, *result;
25625 {
25626 XRectangle *left, *right;
25627 XRectangle *upper, *lower;
25628 int intersection_p = 0;
25629
25630 /* Rearrange so that R1 is the left-most rectangle. */
25631 if (r1->x < r2->x)
25632 left = r1, right = r2;
25633 else
25634 left = r2, right = r1;
25635
25636 /* X0 of the intersection is right.x0, if this is inside R1,
25637 otherwise there is no intersection. */
25638 if (right->x <= left->x + left->width)
25639 {
25640 result->x = right->x;
25641
25642 /* The right end of the intersection is the minimum of the
25643 the right ends of left and right. */
25644 result->width = (min (left->x + left->width, right->x + right->width)
25645 - result->x);
25646
25647 /* Same game for Y. */
25648 if (r1->y < r2->y)
25649 upper = r1, lower = r2;
25650 else
25651 upper = r2, lower = r1;
25652
25653 /* The upper end of the intersection is lower.y0, if this is inside
25654 of upper. Otherwise, there is no intersection. */
25655 if (lower->y <= upper->y + upper->height)
25656 {
25657 result->y = lower->y;
25658
25659 /* The lower end of the intersection is the minimum of the lower
25660 ends of upper and lower. */
25661 result->height = (min (lower->y + lower->height,
25662 upper->y + upper->height)
25663 - result->y);
25664 intersection_p = 1;
25665 }
25666 }
25667
25668 return intersection_p;
25669 }
25670
25671 #endif /* HAVE_WINDOW_SYSTEM */
25672
25673 \f
25674 /***********************************************************************
25675 Initialization
25676 ***********************************************************************/
25677
25678 void
25679 syms_of_xdisp ()
25680 {
25681 Vwith_echo_area_save_vector = Qnil;
25682 staticpro (&Vwith_echo_area_save_vector);
25683
25684 Vmessage_stack = Qnil;
25685 staticpro (&Vmessage_stack);
25686
25687 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
25688 staticpro (&Qinhibit_redisplay);
25689
25690 message_dolog_marker1 = Fmake_marker ();
25691 staticpro (&message_dolog_marker1);
25692 message_dolog_marker2 = Fmake_marker ();
25693 staticpro (&message_dolog_marker2);
25694 message_dolog_marker3 = Fmake_marker ();
25695 staticpro (&message_dolog_marker3);
25696
25697 #if GLYPH_DEBUG
25698 defsubr (&Sdump_frame_glyph_matrix);
25699 defsubr (&Sdump_glyph_matrix);
25700 defsubr (&Sdump_glyph_row);
25701 defsubr (&Sdump_tool_bar_row);
25702 defsubr (&Strace_redisplay);
25703 defsubr (&Strace_to_stderr);
25704 #endif
25705 #ifdef HAVE_WINDOW_SYSTEM
25706 defsubr (&Stool_bar_lines_needed);
25707 defsubr (&Slookup_image_map);
25708 #endif
25709 defsubr (&Sformat_mode_line);
25710 defsubr (&Sinvisible_p);
25711
25712 staticpro (&Qmenu_bar_update_hook);
25713 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
25714
25715 staticpro (&Qoverriding_terminal_local_map);
25716 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
25717
25718 staticpro (&Qoverriding_local_map);
25719 Qoverriding_local_map = intern_c_string ("overriding-local-map");
25720
25721 staticpro (&Qwindow_scroll_functions);
25722 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
25723
25724 staticpro (&Qwindow_text_change_functions);
25725 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
25726
25727 staticpro (&Qredisplay_end_trigger_functions);
25728 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
25729
25730 staticpro (&Qinhibit_point_motion_hooks);
25731 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
25732
25733 Qeval = intern_c_string ("eval");
25734 staticpro (&Qeval);
25735
25736 QCdata = intern_c_string (":data");
25737 staticpro (&QCdata);
25738 Qdisplay = intern_c_string ("display");
25739 staticpro (&Qdisplay);
25740 Qspace_width = intern_c_string ("space-width");
25741 staticpro (&Qspace_width);
25742 Qraise = intern_c_string ("raise");
25743 staticpro (&Qraise);
25744 Qslice = intern_c_string ("slice");
25745 staticpro (&Qslice);
25746 Qspace = intern_c_string ("space");
25747 staticpro (&Qspace);
25748 Qmargin = intern_c_string ("margin");
25749 staticpro (&Qmargin);
25750 Qpointer = intern_c_string ("pointer");
25751 staticpro (&Qpointer);
25752 Qleft_margin = intern_c_string ("left-margin");
25753 staticpro (&Qleft_margin);
25754 Qright_margin = intern_c_string ("right-margin");
25755 staticpro (&Qright_margin);
25756 Qcenter = intern_c_string ("center");
25757 staticpro (&Qcenter);
25758 Qline_height = intern_c_string ("line-height");
25759 staticpro (&Qline_height);
25760 QCalign_to = intern_c_string (":align-to");
25761 staticpro (&QCalign_to);
25762 QCrelative_width = intern_c_string (":relative-width");
25763 staticpro (&QCrelative_width);
25764 QCrelative_height = intern_c_string (":relative-height");
25765 staticpro (&QCrelative_height);
25766 QCeval = intern_c_string (":eval");
25767 staticpro (&QCeval);
25768 QCpropertize = intern_c_string (":propertize");
25769 staticpro (&QCpropertize);
25770 QCfile = intern_c_string (":file");
25771 staticpro (&QCfile);
25772 Qfontified = intern_c_string ("fontified");
25773 staticpro (&Qfontified);
25774 Qfontification_functions = intern_c_string ("fontification-functions");
25775 staticpro (&Qfontification_functions);
25776 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
25777 staticpro (&Qtrailing_whitespace);
25778 Qescape_glyph = intern_c_string ("escape-glyph");
25779 staticpro (&Qescape_glyph);
25780 Qnobreak_space = intern_c_string ("nobreak-space");
25781 staticpro (&Qnobreak_space);
25782 Qimage = intern_c_string ("image");
25783 staticpro (&Qimage);
25784 QCmap = intern_c_string (":map");
25785 staticpro (&QCmap);
25786 QCpointer = intern_c_string (":pointer");
25787 staticpro (&QCpointer);
25788 Qrect = intern_c_string ("rect");
25789 staticpro (&Qrect);
25790 Qcircle = intern_c_string ("circle");
25791 staticpro (&Qcircle);
25792 Qpoly = intern_c_string ("poly");
25793 staticpro (&Qpoly);
25794 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
25795 staticpro (&Qmessage_truncate_lines);
25796 Qgrow_only = intern_c_string ("grow-only");
25797 staticpro (&Qgrow_only);
25798 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
25799 staticpro (&Qinhibit_menubar_update);
25800 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
25801 staticpro (&Qinhibit_eval_during_redisplay);
25802 Qposition = intern_c_string ("position");
25803 staticpro (&Qposition);
25804 Qbuffer_position = intern_c_string ("buffer-position");
25805 staticpro (&Qbuffer_position);
25806 Qobject = intern_c_string ("object");
25807 staticpro (&Qobject);
25808 Qbar = intern_c_string ("bar");
25809 staticpro (&Qbar);
25810 Qhbar = intern_c_string ("hbar");
25811 staticpro (&Qhbar);
25812 Qbox = intern_c_string ("box");
25813 staticpro (&Qbox);
25814 Qhollow = intern_c_string ("hollow");
25815 staticpro (&Qhollow);
25816 Qhand = intern_c_string ("hand");
25817 staticpro (&Qhand);
25818 Qarrow = intern_c_string ("arrow");
25819 staticpro (&Qarrow);
25820 Qtext = intern_c_string ("text");
25821 staticpro (&Qtext);
25822 Qrisky_local_variable = intern_c_string ("risky-local-variable");
25823 staticpro (&Qrisky_local_variable);
25824 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
25825 staticpro (&Qinhibit_free_realized_faces);
25826
25827 list_of_error = Fcons (Fcons (intern_c_string ("error"),
25828 Fcons (intern_c_string ("void-variable"), Qnil)),
25829 Qnil);
25830 staticpro (&list_of_error);
25831
25832 Qlast_arrow_position = intern_c_string ("last-arrow-position");
25833 staticpro (&Qlast_arrow_position);
25834 Qlast_arrow_string = intern_c_string ("last-arrow-string");
25835 staticpro (&Qlast_arrow_string);
25836
25837 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
25838 staticpro (&Qoverlay_arrow_string);
25839 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
25840 staticpro (&Qoverlay_arrow_bitmap);
25841
25842 echo_buffer[0] = echo_buffer[1] = Qnil;
25843 staticpro (&echo_buffer[0]);
25844 staticpro (&echo_buffer[1]);
25845
25846 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
25847 staticpro (&echo_area_buffer[0]);
25848 staticpro (&echo_area_buffer[1]);
25849
25850 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
25851 staticpro (&Vmessages_buffer_name);
25852
25853 mode_line_proptrans_alist = Qnil;
25854 staticpro (&mode_line_proptrans_alist);
25855 mode_line_string_list = Qnil;
25856 staticpro (&mode_line_string_list);
25857 mode_line_string_face = Qnil;
25858 staticpro (&mode_line_string_face);
25859 mode_line_string_face_prop = Qnil;
25860 staticpro (&mode_line_string_face_prop);
25861 Vmode_line_unwind_vector = Qnil;
25862 staticpro (&Vmode_line_unwind_vector);
25863
25864 help_echo_string = Qnil;
25865 staticpro (&help_echo_string);
25866 help_echo_object = Qnil;
25867 staticpro (&help_echo_object);
25868 help_echo_window = Qnil;
25869 staticpro (&help_echo_window);
25870 previous_help_echo_string = Qnil;
25871 staticpro (&previous_help_echo_string);
25872 help_echo_pos = -1;
25873
25874 Qright_to_left = intern_c_string ("right-to-left");
25875 staticpro (&Qright_to_left);
25876 Qleft_to_right = intern_c_string ("left-to-right");
25877 staticpro (&Qleft_to_right);
25878
25879 #ifdef HAVE_WINDOW_SYSTEM
25880 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
25881 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
25882 For example, if a block cursor is over a tab, it will be drawn as
25883 wide as that tab on the display. */);
25884 x_stretch_cursor_p = 0;
25885 #endif
25886
25887 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
25888 doc: /* *Non-nil means highlight trailing whitespace.
25889 The face used for trailing whitespace is `trailing-whitespace'. */);
25890 Vshow_trailing_whitespace = Qnil;
25891
25892 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
25893 doc: /* *Control highlighting of nobreak space and soft hyphen.
25894 A value of t means highlight the character itself (for nobreak space,
25895 use face `nobreak-space').
25896 A value of nil means no highlighting.
25897 Other values mean display the escape glyph followed by an ordinary
25898 space or ordinary hyphen. */);
25899 Vnobreak_char_display = Qt;
25900
25901 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
25902 doc: /* *The pointer shape to show in void text areas.
25903 A value of nil means to show the text pointer. Other options are `arrow',
25904 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
25905 Vvoid_text_area_pointer = Qarrow;
25906
25907 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
25908 doc: /* Non-nil means don't actually do any redisplay.
25909 This is used for internal purposes. */);
25910 Vinhibit_redisplay = Qnil;
25911
25912 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
25913 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
25914 Vglobal_mode_string = Qnil;
25915
25916 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
25917 doc: /* Marker for where to display an arrow on top of the buffer text.
25918 This must be the beginning of a line in order to work.
25919 See also `overlay-arrow-string'. */);
25920 Voverlay_arrow_position = Qnil;
25921
25922 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
25923 doc: /* String to display as an arrow in non-window frames.
25924 See also `overlay-arrow-position'. */);
25925 Voverlay_arrow_string = make_pure_c_string ("=>");
25926
25927 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
25928 doc: /* List of variables (symbols) which hold markers for overlay arrows.
25929 The symbols on this list are examined during redisplay to determine
25930 where to display overlay arrows. */);
25931 Voverlay_arrow_variable_list
25932 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
25933
25934 DEFVAR_INT ("scroll-step", &scroll_step,
25935 doc: /* *The number of lines to try scrolling a window by when point moves out.
25936 If that fails to bring point back on frame, point is centered instead.
25937 If this is zero, point is always centered after it moves off frame.
25938 If you want scrolling to always be a line at a time, you should set
25939 `scroll-conservatively' to a large value rather than set this to 1. */);
25940
25941 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
25942 doc: /* *Scroll up to this many lines, to bring point back on screen.
25943 If point moves off-screen, redisplay will scroll by up to
25944 `scroll-conservatively' lines in order to bring point just barely
25945 onto the screen again. If that cannot be done, then redisplay
25946 recenters point as usual.
25947
25948 A value of zero means always recenter point if it moves off screen. */);
25949 scroll_conservatively = 0;
25950
25951 DEFVAR_INT ("scroll-margin", &scroll_margin,
25952 doc: /* *Number of lines of margin at the top and bottom of a window.
25953 Recenter the window whenever point gets within this many lines
25954 of the top or bottom of the window. */);
25955 scroll_margin = 0;
25956
25957 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
25958 doc: /* Pixels per inch value for non-window system displays.
25959 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
25960 Vdisplay_pixels_per_inch = make_float (72.0);
25961
25962 #if GLYPH_DEBUG
25963 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
25964 #endif
25965
25966 DEFVAR_LISP ("truncate-partial-width-windows",
25967 &Vtruncate_partial_width_windows,
25968 doc: /* Non-nil means truncate lines in windows narrower than the frame.
25969 For an integer value, truncate lines in each window narrower than the
25970 full frame width, provided the window width is less than that integer;
25971 otherwise, respect the value of `truncate-lines'.
25972
25973 For any other non-nil value, truncate lines in all windows that do
25974 not span the full frame width.
25975
25976 A value of nil means to respect the value of `truncate-lines'.
25977
25978 If `word-wrap' is enabled, you might want to reduce this. */);
25979 Vtruncate_partial_width_windows = make_number (50);
25980
25981 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
25982 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
25983 Any other value means to use the appropriate face, `mode-line',
25984 `header-line', or `menu' respectively. */);
25985 mode_line_inverse_video = 1;
25986
25987 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
25988 doc: /* *Maximum buffer size for which line number should be displayed.
25989 If the buffer is bigger than this, the line number does not appear
25990 in the mode line. A value of nil means no limit. */);
25991 Vline_number_display_limit = Qnil;
25992
25993 DEFVAR_INT ("line-number-display-limit-width",
25994 &line_number_display_limit_width,
25995 doc: /* *Maximum line width (in characters) for line number display.
25996 If the average length of the lines near point is bigger than this, then the
25997 line number may be omitted from the mode line. */);
25998 line_number_display_limit_width = 200;
25999
26000 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
26001 doc: /* *Non-nil means highlight region even in nonselected windows. */);
26002 highlight_nonselected_windows = 0;
26003
26004 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
26005 doc: /* Non-nil if more than one frame is visible on this display.
26006 Minibuffer-only frames don't count, but iconified frames do.
26007 This variable is not guaranteed to be accurate except while processing
26008 `frame-title-format' and `icon-title-format'. */);
26009
26010 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
26011 doc: /* Template for displaying the title bar of visible frames.
26012 \(Assuming the window manager supports this feature.)
26013
26014 This variable has the same structure as `mode-line-format', except that
26015 the %c and %l constructs are ignored. It is used only on frames for
26016 which no explicit name has been set \(see `modify-frame-parameters'). */);
26017
26018 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
26019 doc: /* Template for displaying the title bar of an iconified frame.
26020 \(Assuming the window manager supports this feature.)
26021 This variable has the same structure as `mode-line-format' (which see),
26022 and is used only on frames for which no explicit name has been set
26023 \(see `modify-frame-parameters'). */);
26024 Vicon_title_format
26025 = Vframe_title_format
26026 = pure_cons (intern_c_string ("multiple-frames"),
26027 pure_cons (make_pure_c_string ("%b"),
26028 pure_cons (pure_cons (empty_unibyte_string,
26029 pure_cons (intern_c_string ("invocation-name"),
26030 pure_cons (make_pure_c_string ("@"),
26031 pure_cons (intern_c_string ("system-name"),
26032 Qnil)))),
26033 Qnil)));
26034
26035 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
26036 doc: /* Maximum number of lines to keep in the message log buffer.
26037 If nil, disable message logging. If t, log messages but don't truncate
26038 the buffer when it becomes large. */);
26039 Vmessage_log_max = make_number (100);
26040
26041 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
26042 doc: /* Functions called before redisplay, if window sizes have changed.
26043 The value should be a list of functions that take one argument.
26044 Just before redisplay, for each frame, if any of its windows have changed
26045 size since the last redisplay, or have been split or deleted,
26046 all the functions in the list are called, with the frame as argument. */);
26047 Vwindow_size_change_functions = Qnil;
26048
26049 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
26050 doc: /* List of functions to call before redisplaying a window with scrolling.
26051 Each function is called with two arguments, the window and its new
26052 display-start position. Note that these functions are also called by
26053 `set-window-buffer'. Also note that the value of `window-end' is not
26054 valid when these functions are called. */);
26055 Vwindow_scroll_functions = Qnil;
26056
26057 DEFVAR_LISP ("window-text-change-functions",
26058 &Vwindow_text_change_functions,
26059 doc: /* Functions to call in redisplay when text in the window might change. */);
26060 Vwindow_text_change_functions = Qnil;
26061
26062 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
26063 doc: /* Functions called when redisplay of a window reaches the end trigger.
26064 Each function is called with two arguments, the window and the end trigger value.
26065 See `set-window-redisplay-end-trigger'. */);
26066 Vredisplay_end_trigger_functions = Qnil;
26067
26068 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
26069 doc: /* *Non-nil means autoselect window with mouse pointer.
26070 If nil, do not autoselect windows.
26071 A positive number means delay autoselection by that many seconds: a
26072 window is autoselected only after the mouse has remained in that
26073 window for the duration of the delay.
26074 A negative number has a similar effect, but causes windows to be
26075 autoselected only after the mouse has stopped moving. \(Because of
26076 the way Emacs compares mouse events, you will occasionally wait twice
26077 that time before the window gets selected.\)
26078 Any other value means to autoselect window instantaneously when the
26079 mouse pointer enters it.
26080
26081 Autoselection selects the minibuffer only if it is active, and never
26082 unselects the minibuffer if it is active.
26083
26084 When customizing this variable make sure that the actual value of
26085 `focus-follows-mouse' matches the behavior of your window manager. */);
26086 Vmouse_autoselect_window = Qnil;
26087
26088 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
26089 doc: /* *Non-nil means automatically resize tool-bars.
26090 This dynamically changes the tool-bar's height to the minimum height
26091 that is needed to make all tool-bar items visible.
26092 If value is `grow-only', the tool-bar's height is only increased
26093 automatically; to decrease the tool-bar height, use \\[recenter]. */);
26094 Vauto_resize_tool_bars = Qt;
26095
26096 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
26097 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
26098 auto_raise_tool_bar_buttons_p = 1;
26099
26100 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
26101 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
26102 make_cursor_line_fully_visible_p = 1;
26103
26104 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
26105 doc: /* *Border below tool-bar in pixels.
26106 If an integer, use it as the height of the border.
26107 If it is one of `internal-border-width' or `border-width', use the
26108 value of the corresponding frame parameter.
26109 Otherwise, no border is added below the tool-bar. */);
26110 Vtool_bar_border = Qinternal_border_width;
26111
26112 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
26113 doc: /* *Margin around tool-bar buttons in pixels.
26114 If an integer, use that for both horizontal and vertical margins.
26115 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
26116 HORZ specifying the horizontal margin, and VERT specifying the
26117 vertical margin. */);
26118 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
26119
26120 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
26121 doc: /* *Relief thickness of tool-bar buttons. */);
26122 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
26123
26124 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
26125 doc: /* List of functions to call to fontify regions of text.
26126 Each function is called with one argument POS. Functions must
26127 fontify a region starting at POS in the current buffer, and give
26128 fontified regions the property `fontified'. */);
26129 Vfontification_functions = Qnil;
26130 Fmake_variable_buffer_local (Qfontification_functions);
26131
26132 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26133 &unibyte_display_via_language_environment,
26134 doc: /* *Non-nil means display unibyte text according to language environment.
26135 Specifically, this means that raw bytes in the range 160-255 decimal
26136 are displayed by converting them to the equivalent multibyte characters
26137 according to the current language environment. As a result, they are
26138 displayed according to the current fontset.
26139
26140 Note that this variable affects only how these bytes are displayed,
26141 but does not change the fact they are interpreted as raw bytes. */);
26142 unibyte_display_via_language_environment = 0;
26143
26144 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
26145 doc: /* *Maximum height for resizing mini-windows.
26146 If a float, it specifies a fraction of the mini-window frame's height.
26147 If an integer, it specifies a number of lines. */);
26148 Vmax_mini_window_height = make_float (0.25);
26149
26150 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
26151 doc: /* *How to resize mini-windows.
26152 A value of nil means don't automatically resize mini-windows.
26153 A value of t means resize them to fit the text displayed in them.
26154 A value of `grow-only', the default, means let mini-windows grow
26155 only, until their display becomes empty, at which point the windows
26156 go back to their normal size. */);
26157 Vresize_mini_windows = Qgrow_only;
26158
26159 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
26160 doc: /* Alist specifying how to blink the cursor off.
26161 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26162 `cursor-type' frame-parameter or variable equals ON-STATE,
26163 comparing using `equal', Emacs uses OFF-STATE to specify
26164 how to blink it off. ON-STATE and OFF-STATE are values for
26165 the `cursor-type' frame parameter.
26166
26167 If a frame's ON-STATE has no entry in this list,
26168 the frame's other specifications determine how to blink the cursor off. */);
26169 Vblink_cursor_alist = Qnil;
26170
26171 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
26172 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
26173 automatic_hscrolling_p = 1;
26174 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26175 staticpro (&Qauto_hscroll_mode);
26176
26177 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
26178 doc: /* *How many columns away from the window edge point is allowed to get
26179 before automatic hscrolling will horizontally scroll the window. */);
26180 hscroll_margin = 5;
26181
26182 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
26183 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26184 When point is less than `hscroll-margin' columns from the window
26185 edge, automatic hscrolling will scroll the window by the amount of columns
26186 determined by this variable. If its value is a positive integer, scroll that
26187 many columns. If it's a positive floating-point number, it specifies the
26188 fraction of the window's width to scroll. If it's nil or zero, point will be
26189 centered horizontally after the scroll. Any other value, including negative
26190 numbers, are treated as if the value were zero.
26191
26192 Automatic hscrolling always moves point outside the scroll margin, so if
26193 point was more than scroll step columns inside the margin, the window will
26194 scroll more than the value given by the scroll step.
26195
26196 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26197 and `scroll-right' overrides this variable's effect. */);
26198 Vhscroll_step = make_number (0);
26199
26200 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
26201 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26202 Bind this around calls to `message' to let it take effect. */);
26203 message_truncate_lines = 0;
26204
26205 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
26206 doc: /* Normal hook run to update the menu bar definitions.
26207 Redisplay runs this hook before it redisplays the menu bar.
26208 This is used to update submenus such as Buffers,
26209 whose contents depend on various data. */);
26210 Vmenu_bar_update_hook = Qnil;
26211
26212 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
26213 doc: /* Frame for which we are updating a menu.
26214 The enable predicate for a menu binding should check this variable. */);
26215 Vmenu_updating_frame = Qnil;
26216
26217 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
26218 doc: /* Non-nil means don't update menu bars. Internal use only. */);
26219 inhibit_menubar_update = 0;
26220
26221 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
26222 doc: /* Prefix prepended to all continuation lines at display time.
26223 The value may be a string, an image, or a stretch-glyph; it is
26224 interpreted in the same way as the value of a `display' text property.
26225
26226 This variable is overridden by any `wrap-prefix' text or overlay
26227 property.
26228
26229 To add a prefix to non-continuation lines, use `line-prefix'. */);
26230 Vwrap_prefix = Qnil;
26231 staticpro (&Qwrap_prefix);
26232 Qwrap_prefix = intern_c_string ("wrap-prefix");
26233 Fmake_variable_buffer_local (Qwrap_prefix);
26234
26235 DEFVAR_LISP ("line-prefix", &Vline_prefix,
26236 doc: /* Prefix prepended to all non-continuation lines at display time.
26237 The value may be a string, an image, or a stretch-glyph; it is
26238 interpreted in the same way as the value of a `display' text property.
26239
26240 This variable is overridden by any `line-prefix' text or overlay
26241 property.
26242
26243 To add a prefix to continuation lines, use `wrap-prefix'. */);
26244 Vline_prefix = Qnil;
26245 staticpro (&Qline_prefix);
26246 Qline_prefix = intern_c_string ("line-prefix");
26247 Fmake_variable_buffer_local (Qline_prefix);
26248
26249 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
26250 doc: /* Non-nil means don't eval Lisp during redisplay. */);
26251 inhibit_eval_during_redisplay = 0;
26252
26253 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
26254 doc: /* Non-nil means don't free realized faces. Internal use only. */);
26255 inhibit_free_realized_faces = 0;
26256
26257 #if GLYPH_DEBUG
26258 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
26259 doc: /* Inhibit try_window_id display optimization. */);
26260 inhibit_try_window_id = 0;
26261
26262 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
26263 doc: /* Inhibit try_window_reusing display optimization. */);
26264 inhibit_try_window_reusing = 0;
26265
26266 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
26267 doc: /* Inhibit try_cursor_movement display optimization. */);
26268 inhibit_try_cursor_movement = 0;
26269 #endif /* GLYPH_DEBUG */
26270
26271 DEFVAR_INT ("overline-margin", &overline_margin,
26272 doc: /* *Space between overline and text, in pixels.
26273 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
26274 margin to the caracter height. */);
26275 overline_margin = 2;
26276
26277 DEFVAR_INT ("underline-minimum-offset",
26278 &underline_minimum_offset,
26279 doc: /* Minimum distance between baseline and underline.
26280 This can improve legibility of underlined text at small font sizes,
26281 particularly when using variable `x-use-underline-position-properties'
26282 with fonts that specify an UNDERLINE_POSITION relatively close to the
26283 baseline. The default value is 1. */);
26284 underline_minimum_offset = 1;
26285
26286 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
26287 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
26288 display_hourglass_p = 1;
26289
26290 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
26291 doc: /* *Seconds to wait before displaying an hourglass pointer.
26292 Value must be an integer or float. */);
26293 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
26294
26295 hourglass_atimer = NULL;
26296 hourglass_shown_p = 0;
26297 }
26298
26299
26300 /* Initialize this module when Emacs starts. */
26301
26302 void
26303 init_xdisp ()
26304 {
26305 Lisp_Object root_window;
26306 struct window *mini_w;
26307
26308 current_header_line_height = current_mode_line_height = -1;
26309
26310 CHARPOS (this_line_start_pos) = 0;
26311
26312 mini_w = XWINDOW (minibuf_window);
26313 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
26314
26315 if (!noninteractive)
26316 {
26317 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
26318 int i;
26319
26320 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
26321 set_window_height (root_window,
26322 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
26323 0);
26324 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
26325 set_window_height (minibuf_window, 1, 0);
26326
26327 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
26328 mini_w->total_cols = make_number (FRAME_COLS (f));
26329
26330 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
26331 scratch_glyph_row.glyphs[TEXT_AREA + 1]
26332 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
26333
26334 /* The default ellipsis glyphs `...'. */
26335 for (i = 0; i < 3; ++i)
26336 default_invis_vector[i] = make_number ('.');
26337 }
26338
26339 {
26340 /* Allocate the buffer for frame titles.
26341 Also used for `format-mode-line'. */
26342 int size = 100;
26343 mode_line_noprop_buf = (char *) xmalloc (size);
26344 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
26345 mode_line_noprop_ptr = mode_line_noprop_buf;
26346 mode_line_target = MODE_LINE_DISPLAY;
26347 }
26348
26349 help_echo_showing_p = 0;
26350 }
26351
26352 /* Since w32 does not support atimers, it defines its own implementation of
26353 the following three functions in w32fns.c. */
26354 #ifndef WINDOWSNT
26355
26356 /* Platform-independent portion of hourglass implementation. */
26357
26358 /* Return non-zero if houglass timer has been started or hourglass is shown. */
26359 int
26360 hourglass_started ()
26361 {
26362 return hourglass_shown_p || hourglass_atimer != NULL;
26363 }
26364
26365 /* Cancel a currently active hourglass timer, and start a new one. */
26366 void
26367 start_hourglass ()
26368 {
26369 #if defined (HAVE_WINDOW_SYSTEM)
26370 EMACS_TIME delay;
26371 int secs, usecs = 0;
26372
26373 cancel_hourglass ();
26374
26375 if (INTEGERP (Vhourglass_delay)
26376 && XINT (Vhourglass_delay) > 0)
26377 secs = XFASTINT (Vhourglass_delay);
26378 else if (FLOATP (Vhourglass_delay)
26379 && XFLOAT_DATA (Vhourglass_delay) > 0)
26380 {
26381 Lisp_Object tem;
26382 tem = Ftruncate (Vhourglass_delay, Qnil);
26383 secs = XFASTINT (tem);
26384 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
26385 }
26386 else
26387 secs = DEFAULT_HOURGLASS_DELAY;
26388
26389 EMACS_SET_SECS_USECS (delay, secs, usecs);
26390 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
26391 show_hourglass, NULL);
26392 #endif
26393 }
26394
26395
26396 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
26397 shown. */
26398 void
26399 cancel_hourglass ()
26400 {
26401 #if defined (HAVE_WINDOW_SYSTEM)
26402 if (hourglass_atimer)
26403 {
26404 cancel_atimer (hourglass_atimer);
26405 hourglass_atimer = NULL;
26406 }
26407
26408 if (hourglass_shown_p)
26409 hide_hourglass ();
26410 #endif
26411 }
26412 #endif /* ! WINDOWSNT */
26413
26414 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
26415 (do not change this comment) */