*** empty log message ***
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
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. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
125
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
131
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
138
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
146
147
148 Frame matrices.
149
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
156
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
168
169 #include <config.h>
170 #include <stdio.h>
171
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "character.h"
180 #include "charset.h"
181 #include "indent.h"
182 #include "commands.h"
183 #include "keymap.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "coding.h"
189 #include "process.h"
190 #include "region-cache.h"
191 #include "fontset.h"
192 #include "blockinput.h"
193
194 #ifdef HAVE_X_WINDOWS
195 #include "xterm.h"
196 #endif
197 #ifdef WINDOWSNT
198 #include "w32term.h"
199 #endif
200 #ifdef MAC_OS
201 #include "macterm.h"
202
203 Cursor No_Cursor;
204 #endif
205
206 #ifndef FRAME_X_OUTPUT
207 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
208 #endif
209
210 #define INFINITY 10000000
211
212 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
213 || defined (USE_GTK)
214 extern void set_frame_menubar P_ ((struct frame *f, int, int));
215 extern int pending_menu_activation;
216 #endif
217
218 extern int interrupt_input;
219 extern int command_loop_level;
220
221 extern int minibuffer_auto_raise;
222 extern Lisp_Object Vminibuffer_list;
223
224 extern Lisp_Object Qface;
225 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226
227 extern Lisp_Object Voverriding_local_map;
228 extern Lisp_Object Voverriding_local_map_menu_flag;
229 extern Lisp_Object Qmenu_item;
230 extern Lisp_Object Qwhen;
231 extern Lisp_Object Qhelp_echo;
232
233 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
234 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
235 Lisp_Object Qredisplay_end_trigger_functions;
236 Lisp_Object Qinhibit_point_motion_hooks;
237 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
238 Lisp_Object Qfontified;
239 Lisp_Object Qgrow_only;
240 Lisp_Object Qinhibit_eval_during_redisplay;
241 Lisp_Object Qbuffer_position, Qposition, Qobject;
242
243 /* Cursor shapes */
244 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245
246 Lisp_Object Qrisky_local_variable;
247
248 /* Holds the list (error). */
249 Lisp_Object list_of_error;
250
251 /* Functions called to fontify regions of text. */
252
253 Lisp_Object Vfontification_functions;
254 Lisp_Object Qfontification_functions;
255
256 /* Non-zero means automatically select any window when the mouse
257 cursor moves into it. */
258 int mouse_autoselect_window;
259
260 /* Non-zero means draw tool bar buttons raised when the mouse moves
261 over them. */
262
263 int auto_raise_tool_bar_buttons_p;
264
265 /* Margin around tool bar buttons in pixels. */
266
267 Lisp_Object Vtool_bar_button_margin;
268
269 /* Thickness of shadow to draw around tool bar buttons. */
270
271 EMACS_INT tool_bar_button_relief;
272
273 /* Non-zero means automatically resize tool-bars so that all tool-bar
274 items are visible, and no blank lines remain. */
275
276 int auto_resize_tool_bars_p;
277
278 /* Non-zero means draw block and hollow cursor as wide as the glyph
279 under it. For example, if a block cursor is over a tab, it will be
280 drawn as wide as that tab on the display. */
281
282 int x_stretch_cursor_p;
283
284 /* Non-nil means don't actually do any redisplay. */
285
286 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
287
288 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
289
290 int inhibit_eval_during_redisplay;
291
292 /* Names of text properties relevant for redisplay. */
293
294 Lisp_Object Qdisplay, Qrelative_width, Qalign_to;
295 extern Lisp_Object Qface, Qinvisible, Qwidth;
296
297 /* Symbols used in text property values. */
298
299 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
300 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
301 Lisp_Object Qmargin;
302 extern Lisp_Object Qheight;
303 extern Lisp_Object QCwidth, QCheight, QCascent;
304
305 /* Non-nil means highlight trailing whitespace. */
306
307 Lisp_Object Vshow_trailing_whitespace;
308
309 /* Name of the face used to highlight trailing whitespace. */
310
311 Lisp_Object Qtrailing_whitespace;
312
313 /* The symbol `image' which is the car of the lists used to represent
314 images in Lisp. */
315
316 Lisp_Object Qimage;
317
318 /* Non-zero means print newline to stdout before next mini-buffer
319 message. */
320
321 int noninteractive_need_newline;
322
323 /* Non-zero means print newline to message log before next message. */
324
325 static int message_log_need_newline;
326
327 /* Three markers that message_dolog uses.
328 It could allocate them itself, but that causes trouble
329 in handling memory-full errors. */
330 static Lisp_Object message_dolog_marker1;
331 static Lisp_Object message_dolog_marker2;
332 static Lisp_Object message_dolog_marker3;
333 \f
334 /* The buffer position of the first character appearing entirely or
335 partially on the line of the selected window which contains the
336 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
337 redisplay optimization in redisplay_internal. */
338
339 static struct text_pos this_line_start_pos;
340
341 /* Number of characters past the end of the line above, including the
342 terminating newline. */
343
344 static struct text_pos this_line_end_pos;
345
346 /* The vertical positions and the height of this line. */
347
348 static int this_line_vpos;
349 static int this_line_y;
350 static int this_line_pixel_height;
351
352 /* X position at which this display line starts. Usually zero;
353 negative if first character is partially visible. */
354
355 static int this_line_start_x;
356
357 /* Buffer that this_line_.* variables are referring to. */
358
359 static struct buffer *this_line_buffer;
360
361 /* Nonzero means truncate lines in all windows less wide than the
362 frame. */
363
364 int truncate_partial_width_windows;
365
366 /* A flag to control how to display unibyte 8-bit character. */
367
368 int unibyte_display_via_language_environment;
369
370 /* Nonzero means we have more than one non-mini-buffer-only frame.
371 Not guaranteed to be accurate except while parsing
372 frame-title-format. */
373
374 int multiple_frames;
375
376 Lisp_Object Vglobal_mode_string;
377
378 /* Marker for where to display an arrow on top of the buffer text. */
379
380 Lisp_Object Voverlay_arrow_position;
381
382 /* String to display for the arrow. Only used on terminal frames. */
383
384 Lisp_Object Voverlay_arrow_string;
385
386 /* Values of those variables at last redisplay. However, if
387 Voverlay_arrow_position is a marker, last_arrow_position is its
388 numerical position. */
389
390 static Lisp_Object last_arrow_position, last_arrow_string;
391
392 /* Like mode-line-format, but for the title bar on a visible frame. */
393
394 Lisp_Object Vframe_title_format;
395
396 /* Like mode-line-format, but for the title bar on an iconified frame. */
397
398 Lisp_Object Vicon_title_format;
399
400 /* List of functions to call when a window's size changes. These
401 functions get one arg, a frame on which one or more windows' sizes
402 have changed. */
403
404 static Lisp_Object Vwindow_size_change_functions;
405
406 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
407
408 /* Nonzero if overlay arrow has been displayed once in this window. */
409
410 static int overlay_arrow_seen;
411
412 /* Nonzero means highlight the region even in nonselected windows. */
413
414 int highlight_nonselected_windows;
415
416 /* If cursor motion alone moves point off frame, try scrolling this
417 many lines up or down if that will bring it back. */
418
419 static EMACS_INT scroll_step;
420
421 /* Nonzero means scroll just far enough to bring point back on the
422 screen, when appropriate. */
423
424 static EMACS_INT scroll_conservatively;
425
426 /* Recenter the window whenever point gets within this many lines of
427 the top or bottom of the window. This value is translated into a
428 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
429 that there is really a fixed pixel height scroll margin. */
430
431 EMACS_INT scroll_margin;
432
433 /* Number of windows showing the buffer of the selected window (or
434 another buffer with the same base buffer). keyboard.c refers to
435 this. */
436
437 int buffer_shared;
438
439 /* Vector containing glyphs for an ellipsis `...'. */
440
441 static Lisp_Object default_invis_vector[3];
442
443 /* Zero means display the mode-line/header-line/menu-bar in the default face
444 (this slightly odd definition is for compatibility with previous versions
445 of emacs), non-zero means display them using their respective faces.
446
447 This variable is deprecated. */
448
449 int mode_line_inverse_video;
450
451 /* Prompt to display in front of the mini-buffer contents. */
452
453 Lisp_Object minibuf_prompt;
454
455 /* Width of current mini-buffer prompt. Only set after display_line
456 of the line that contains the prompt. */
457
458 int minibuf_prompt_width;
459
460 /* This is the window where the echo area message was displayed. It
461 is always a mini-buffer window, but it may not be the same window
462 currently active as a mini-buffer. */
463
464 Lisp_Object echo_area_window;
465
466 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
467 pushes the current message and the value of
468 message_enable_multibyte on the stack, the function restore_message
469 pops the stack and displays MESSAGE again. */
470
471 Lisp_Object Vmessage_stack;
472
473 /* Nonzero means multibyte characters were enabled when the echo area
474 message was specified. */
475
476 int message_enable_multibyte;
477
478 /* Nonzero if we should redraw the mode lines on the next redisplay. */
479
480 int update_mode_lines;
481
482 /* Nonzero if window sizes or contents have changed since last
483 redisplay that finished. */
484
485 int windows_or_buffers_changed;
486
487 /* Nonzero means a frame's cursor type has been changed. */
488
489 int cursor_type_changed;
490
491 /* Nonzero after display_mode_line if %l was used and it displayed a
492 line number. */
493
494 int line_number_displayed;
495
496 /* Maximum buffer size for which to display line numbers. */
497
498 Lisp_Object Vline_number_display_limit;
499
500 /* Line width to consider when repositioning for line number display. */
501
502 static EMACS_INT line_number_display_limit_width;
503
504 /* Number of lines to keep in the message log buffer. t means
505 infinite. nil means don't log at all. */
506
507 Lisp_Object Vmessage_log_max;
508
509 /* The name of the *Messages* buffer, a string. */
510
511 static Lisp_Object Vmessages_buffer_name;
512
513 /* Current, index 0, and last displayed echo area message. Either
514 buffers from echo_buffers, or nil to indicate no message. */
515
516 Lisp_Object echo_area_buffer[2];
517
518 /* The buffers referenced from echo_area_buffer. */
519
520 static Lisp_Object echo_buffer[2];
521
522 /* A vector saved used in with_area_buffer to reduce consing. */
523
524 static Lisp_Object Vwith_echo_area_save_vector;
525
526 /* Non-zero means display_echo_area should display the last echo area
527 message again. Set by redisplay_preserve_echo_area. */
528
529 static int display_last_displayed_message_p;
530
531 /* Nonzero if echo area is being used by print; zero if being used by
532 message. */
533
534 int message_buf_print;
535
536 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
537
538 Lisp_Object Qinhibit_menubar_update;
539 int inhibit_menubar_update;
540
541 /* Maximum height for resizing mini-windows. Either a float
542 specifying a fraction of the available height, or an integer
543 specifying a number of lines. */
544
545 Lisp_Object Vmax_mini_window_height;
546
547 /* Non-zero means messages should be displayed with truncated
548 lines instead of being continued. */
549
550 int message_truncate_lines;
551 Lisp_Object Qmessage_truncate_lines;
552
553 /* Set to 1 in clear_message to make redisplay_internal aware
554 of an emptied echo area. */
555
556 static int message_cleared_p;
557
558 /* Non-zero means we want a hollow cursor in windows that are not
559 selected. Zero means there's no cursor in such windows. */
560
561 Lisp_Object Vcursor_in_non_selected_windows;
562 Lisp_Object Qcursor_in_non_selected_windows;
563
564 /* How to blink the default frame cursor off. */
565 Lisp_Object Vblink_cursor_alist;
566
567 /* A scratch glyph row with contents used for generating truncation
568 glyphs. Also used in direct_output_for_insert. */
569
570 #define MAX_SCRATCH_GLYPHS 100
571 struct glyph_row scratch_glyph_row;
572 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
573
574 /* Ascent and height of the last line processed by move_it_to. */
575
576 static int last_max_ascent, last_height;
577
578 /* Non-zero if there's a help-echo in the echo area. */
579
580 int help_echo_showing_p;
581
582 /* If >= 0, computed, exact values of mode-line and header-line height
583 to use in the macros CURRENT_MODE_LINE_HEIGHT and
584 CURRENT_HEADER_LINE_HEIGHT. */
585
586 int current_mode_line_height, current_header_line_height;
587
588 /* The maximum distance to look ahead for text properties. Values
589 that are too small let us call compute_char_face and similar
590 functions too often which is expensive. Values that are too large
591 let us call compute_char_face and alike too often because we
592 might not be interested in text properties that far away. */
593
594 #define TEXT_PROP_DISTANCE_LIMIT 100
595
596 #if GLYPH_DEBUG
597
598 /* Variables to turn off display optimizations from Lisp. */
599
600 int inhibit_try_window_id, inhibit_try_window_reusing;
601 int inhibit_try_cursor_movement;
602
603 /* Non-zero means print traces of redisplay if compiled with
604 GLYPH_DEBUG != 0. */
605
606 int trace_redisplay_p;
607
608 #endif /* GLYPH_DEBUG */
609
610 #ifdef DEBUG_TRACE_MOVE
611 /* Non-zero means trace with TRACE_MOVE to stderr. */
612 int trace_move;
613
614 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
615 #else
616 #define TRACE_MOVE(x) (void) 0
617 #endif
618
619 /* Non-zero means automatically scroll windows horizontally to make
620 point visible. */
621
622 int automatic_hscrolling_p;
623
624 /* How close to the margin can point get before the window is scrolled
625 horizontally. */
626 EMACS_INT hscroll_margin;
627
628 /* How much to scroll horizontally when point is inside the above margin. */
629 Lisp_Object Vhscroll_step;
630
631 /* A list of symbols, one for each supported image type. */
632
633 Lisp_Object Vimage_types;
634
635 /* The variable `resize-mini-windows'. If nil, don't resize
636 mini-windows. If t, always resize them to fit the text they
637 display. If `grow-only', let mini-windows grow only until they
638 become empty. */
639
640 Lisp_Object Vresize_mini_windows;
641
642 /* Buffer being redisplayed -- for redisplay_window_error. */
643
644 struct buffer *displayed_buffer;
645
646 /* Value returned from text property handlers (see below). */
647
648 enum prop_handled
649 {
650 HANDLED_NORMALLY,
651 HANDLED_RECOMPUTE_PROPS,
652 HANDLED_OVERLAY_STRING_CONSUMED,
653 HANDLED_RETURN
654 };
655
656 /* A description of text properties that redisplay is interested
657 in. */
658
659 struct props
660 {
661 /* The name of the property. */
662 Lisp_Object *name;
663
664 /* A unique index for the property. */
665 enum prop_idx idx;
666
667 /* A handler function called to set up iterator IT from the property
668 at IT's current position. Value is used to steer handle_stop. */
669 enum prop_handled (*handler) P_ ((struct it *it));
670 };
671
672 static enum prop_handled handle_face_prop P_ ((struct it *));
673 static enum prop_handled handle_invisible_prop P_ ((struct it *));
674 static enum prop_handled handle_display_prop P_ ((struct it *));
675 static enum prop_handled handle_composition_prop P_ ((struct it *));
676 static enum prop_handled handle_overlay_change P_ ((struct it *));
677 static enum prop_handled handle_fontified_prop P_ ((struct it *));
678 static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
679
680 /* Properties handled by iterators. */
681
682 static struct props it_props[] =
683 {
684 {&Qauto_composed, AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
685 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
686 /* Handle `face' before `display' because some sub-properties of
687 `display' need to know the face. */
688 {&Qface, FACE_PROP_IDX, handle_face_prop},
689 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
690 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
691 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
692 {NULL, 0, NULL}
693 };
694
695 /* Value is the position described by X. If X is a marker, value is
696 the marker_position of X. Otherwise, value is X. */
697
698 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
699
700 /* Enumeration returned by some move_it_.* functions internally. */
701
702 enum move_it_result
703 {
704 /* Not used. Undefined value. */
705 MOVE_UNDEFINED,
706
707 /* Move ended at the requested buffer position or ZV. */
708 MOVE_POS_MATCH_OR_ZV,
709
710 /* Move ended at the requested X pixel position. */
711 MOVE_X_REACHED,
712
713 /* Move within a line ended at the end of a line that must be
714 continued. */
715 MOVE_LINE_CONTINUED,
716
717 /* Move within a line ended at the end of a line that would
718 be displayed truncated. */
719 MOVE_LINE_TRUNCATED,
720
721 /* Move within a line ended at a line end. */
722 MOVE_NEWLINE_OR_CR
723 };
724
725 /* This counter is used to clear the face cache every once in a while
726 in redisplay_internal. It is incremented for each redisplay.
727 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
728 cleared. */
729
730 #define CLEAR_FACE_CACHE_COUNT 500
731 static int clear_face_cache_count;
732
733 /* Record the previous terminal frame we displayed. */
734
735 static struct frame *previous_terminal_frame;
736
737 /* Non-zero while redisplay_internal is in progress. */
738
739 int redisplaying_p;
740
741 /* Non-zero means don't free realized faces. Bound while freeing
742 realized faces is dangerous because glyph matrices might still
743 reference them. */
744
745 int inhibit_free_realized_faces;
746 Lisp_Object Qinhibit_free_realized_faces;
747
748 /* If a string, XTread_socket generates an event to display that string.
749 (The display is done in read_char.) */
750
751 Lisp_Object help_echo_string;
752 Lisp_Object help_echo_window;
753 Lisp_Object help_echo_object;
754 int help_echo_pos;
755
756 /* Temporary variable for XTread_socket. */
757
758 Lisp_Object previous_help_echo_string;
759
760
761 \f
762 /* Function prototypes. */
763
764 static void setup_for_ellipsis P_ ((struct it *));
765 static void mark_window_display_accurate_1 P_ ((struct window *, int));
766 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
767 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
768 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
769 static int redisplay_mode_lines P_ ((Lisp_Object, int));
770 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
771
772 #if 0
773 static int invisible_text_between_p P_ ((struct it *, int, int));
774 #endif
775
776 static int next_element_from_ellipsis P_ ((struct it *));
777 static void pint2str P_ ((char *, int, int));
778 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
779 struct text_pos));
780 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
781 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
782 static void store_frame_title_char P_ ((char));
783 static int store_frame_title P_ ((const unsigned char *, int, int));
784 static void x_consider_frame_title P_ ((Lisp_Object));
785 static void handle_stop P_ ((struct it *));
786 static int tool_bar_lines_needed P_ ((struct frame *));
787 static int single_display_prop_intangible_p P_ ((Lisp_Object));
788 static void ensure_echo_area_buffers P_ ((void));
789 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
790 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
791 static int with_echo_area_buffer P_ ((struct window *, int,
792 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
793 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
794 static void clear_garbaged_frames P_ ((void));
795 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
796 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
797 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
798 static int display_echo_area P_ ((struct window *));
799 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
800 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
801 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
802 static int string_char_and_length P_ ((const unsigned char *, int, int *));
803 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
804 struct text_pos));
805 static int compute_window_start_on_continuation_line P_ ((struct window *));
806 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
807 static void insert_left_trunc_glyphs P_ ((struct it *));
808 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
809 static void extend_face_to_end_of_line P_ ((struct it *));
810 static int append_space P_ ((struct it *, int));
811 static int make_cursor_line_fully_visible P_ ((struct window *));
812 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
813 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
814 static int trailing_whitespace_p P_ ((int));
815 static int message_log_check_duplicate P_ ((int, int, int, int));
816 static void push_it P_ ((struct it *));
817 static void pop_it P_ ((struct it *));
818 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
819 static void redisplay_internal P_ ((int));
820 static int echo_area_display P_ ((int));
821 static void redisplay_windows P_ ((Lisp_Object));
822 static void redisplay_window P_ ((Lisp_Object, int));
823 static Lisp_Object redisplay_window_error ();
824 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
825 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
826 static void update_menu_bar P_ ((struct frame *, int));
827 static int try_window_reusing_current_matrix P_ ((struct window *));
828 static int try_window_id P_ ((struct window *));
829 static int display_line P_ ((struct it *));
830 static int display_mode_lines P_ ((struct window *));
831 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
832 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
833 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
834 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
835 static void display_menu_bar P_ ((struct window *));
836 static int display_count_lines P_ ((int, int, int, int, int *));
837 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
838 int, int, struct it *, int, int, int, int));
839 static void compute_line_metrics P_ ((struct it *));
840 static void run_redisplay_end_trigger_hook P_ ((struct it *));
841 static int get_overlay_strings P_ ((struct it *, int));
842 static void next_overlay_string P_ ((struct it *));
843 static void reseat P_ ((struct it *, struct text_pos, int));
844 static void reseat_1 P_ ((struct it *, struct text_pos, int));
845 static void back_to_previous_visible_line_start P_ ((struct it *));
846 static void reseat_at_previous_visible_line_start P_ ((struct it *));
847 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
848 static int next_element_from_display_vector P_ ((struct it *));
849 static int next_element_from_string P_ ((struct it *));
850 static int next_element_from_c_string P_ ((struct it *));
851 static int next_element_from_buffer P_ ((struct it *));
852 static int next_element_from_composition P_ ((struct it *));
853 static int next_element_from_image P_ ((struct it *));
854 static int next_element_from_stretch P_ ((struct it *));
855 static void load_overlay_strings P_ ((struct it *, int));
856 static int init_from_display_pos P_ ((struct it *, struct window *,
857 struct display_pos *));
858 static void reseat_to_string P_ ((struct it *, unsigned char *,
859 Lisp_Object, int, int, int, int));
860 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
861 int, int, int));
862 void move_it_vertically_backward P_ ((struct it *, int));
863 static void init_to_row_start P_ ((struct it *, struct window *,
864 struct glyph_row *));
865 static int init_to_row_end P_ ((struct it *, struct window *,
866 struct glyph_row *));
867 static void back_to_previous_line_start P_ ((struct it *));
868 static int forward_to_next_line_start P_ ((struct it *, int *));
869 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
870 Lisp_Object, int));
871 static struct text_pos string_pos P_ ((int, Lisp_Object));
872 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
873 static int number_of_chars P_ ((unsigned char *, int));
874 static void compute_stop_pos P_ ((struct it *));
875 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
876 Lisp_Object));
877 static int face_before_or_after_it_pos P_ ((struct it *, int));
878 static int next_overlay_change P_ ((int));
879 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
880 Lisp_Object, struct text_pos *,
881 int));
882 static int underlying_face_id P_ ((struct it *));
883 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
884 struct window *));
885
886 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
887 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
888
889 #ifdef HAVE_WINDOW_SYSTEM
890
891 static void update_tool_bar P_ ((struct frame *, int));
892 static void build_desired_tool_bar_string P_ ((struct frame *f));
893 static int redisplay_tool_bar P_ ((struct frame *));
894 static void display_tool_bar_line P_ ((struct it *));
895 static void notice_overwritten_cursor P_ ((struct window *,
896 enum glyph_row_area,
897 int, int, int, int));
898
899
900
901 #endif /* HAVE_WINDOW_SYSTEM */
902
903 \f
904 /***********************************************************************
905 Window display dimensions
906 ***********************************************************************/
907
908 /* Return the bottom boundary y-position for text lines in window W.
909 This is the first y position at which a line cannot start.
910 It is relative to the top of the window.
911
912 This is the height of W minus the height of a mode line, if any. */
913
914 INLINE int
915 window_text_bottom_y (w)
916 struct window *w;
917 {
918 int height = WINDOW_TOTAL_HEIGHT (w);
919
920 if (WINDOW_WANTS_MODELINE_P (w))
921 height -= CURRENT_MODE_LINE_HEIGHT (w);
922 return height;
923 }
924
925 /* Return the pixel width of display area AREA of window W. AREA < 0
926 means return the total width of W, not including fringes to
927 the left and right of the window. */
928
929 INLINE int
930 window_box_width (w, area)
931 struct window *w;
932 int area;
933 {
934 int cols = XFASTINT (w->total_cols);
935 int pixels = 0;
936
937 if (!w->pseudo_window_p)
938 {
939 cols -= WINDOW_SCROLL_BAR_COLS (w);
940
941 if (area == TEXT_AREA)
942 {
943 if (INTEGERP (w->left_margin_cols))
944 cols -= XFASTINT (w->left_margin_cols);
945 if (INTEGERP (w->right_margin_cols))
946 cols -= XFASTINT (w->right_margin_cols);
947 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
948 }
949 else if (area == LEFT_MARGIN_AREA)
950 {
951 cols = (INTEGERP (w->left_margin_cols)
952 ? XFASTINT (w->left_margin_cols) : 0);
953 pixels = 0;
954 }
955 else if (area == RIGHT_MARGIN_AREA)
956 {
957 cols = (INTEGERP (w->right_margin_cols)
958 ? XFASTINT (w->right_margin_cols) : 0);
959 pixels = 0;
960 }
961 }
962
963 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
964 }
965
966
967 /* Return the pixel height of the display area of window W, not
968 including mode lines of W, if any. */
969
970 INLINE int
971 window_box_height (w)
972 struct window *w;
973 {
974 struct frame *f = XFRAME (w->frame);
975 int height = WINDOW_TOTAL_HEIGHT (w);
976
977 xassert (height >= 0);
978
979 /* Note: the code below that determines the mode-line/header-line
980 height is essentially the same as that contained in the macro
981 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
982 the appropriate glyph row has its `mode_line_p' flag set,
983 and if it doesn't, uses estimate_mode_line_height instead. */
984
985 if (WINDOW_WANTS_MODELINE_P (w))
986 {
987 struct glyph_row *ml_row
988 = (w->current_matrix && w->current_matrix->rows
989 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
990 : 0);
991 if (ml_row && ml_row->mode_line_p)
992 height -= ml_row->height;
993 else
994 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
995 }
996
997 if (WINDOW_WANTS_HEADER_LINE_P (w))
998 {
999 struct glyph_row *hl_row
1000 = (w->current_matrix && w->current_matrix->rows
1001 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1002 : 0);
1003 if (hl_row && hl_row->mode_line_p)
1004 height -= hl_row->height;
1005 else
1006 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1007 }
1008
1009 /* With a very small font and a mode-line that's taller than
1010 default, we might end up with a negative height. */
1011 return max (0, height);
1012 }
1013
1014 /* Return the window-relative coordinate of the left edge of display
1015 area AREA of window W. AREA < 0 means return the left edge of the
1016 whole window, to the right of the left fringe of W. */
1017
1018 INLINE int
1019 window_box_left_offset (w, area)
1020 struct window *w;
1021 int area;
1022 {
1023 int x;
1024
1025 if (w->pseudo_window_p)
1026 return 0;
1027
1028 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1029
1030 if (area == TEXT_AREA)
1031 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1032 + window_box_width (w, LEFT_MARGIN_AREA));
1033 else if (area == RIGHT_MARGIN_AREA)
1034 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1035 + window_box_width (w, LEFT_MARGIN_AREA)
1036 + window_box_width (w, TEXT_AREA)
1037 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1038 ? 0
1039 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1040 else if (area == LEFT_MARGIN_AREA
1041 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1042 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1043
1044 return x;
1045 }
1046
1047
1048 /* Return the window-relative coordinate of the right edge of display
1049 area AREA of window W. AREA < 0 means return the left edge of the
1050 whole window, to the left of the right fringe of W. */
1051
1052 INLINE int
1053 window_box_right_offset (w, area)
1054 struct window *w;
1055 int area;
1056 {
1057 return window_box_left_offset (w, area) + window_box_width (w, area);
1058 }
1059
1060 /* Return the frame-relative coordinate of the left edge of display
1061 area AREA of window W. AREA < 0 means return the left edge of the
1062 whole window, to the right of the left fringe of W. */
1063
1064 INLINE int
1065 window_box_left (w, area)
1066 struct window *w;
1067 int area;
1068 {
1069 struct frame *f = XFRAME (w->frame);
1070 int x;
1071
1072 if (w->pseudo_window_p)
1073 return FRAME_INTERNAL_BORDER_WIDTH (f);
1074
1075 x = (WINDOW_LEFT_EDGE_X (w)
1076 + window_box_left_offset (w, area));
1077
1078 return x;
1079 }
1080
1081
1082 /* Return the frame-relative coordinate of the right edge of display
1083 area AREA of window W. AREA < 0 means return the left edge of the
1084 whole window, to the left of the right fringe of W. */
1085
1086 INLINE int
1087 window_box_right (w, area)
1088 struct window *w;
1089 int area;
1090 {
1091 return window_box_left (w, area) + window_box_width (w, area);
1092 }
1093
1094 /* Get the bounding box of the display area AREA of window W, without
1095 mode lines, in frame-relative coordinates. AREA < 0 means the
1096 whole window, not including the left and right fringes of
1097 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1098 coordinates of the upper-left corner of the box. Return in
1099 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1100
1101 INLINE void
1102 window_box (w, area, box_x, box_y, box_width, box_height)
1103 struct window *w;
1104 int area;
1105 int *box_x, *box_y, *box_width, *box_height;
1106 {
1107 if (box_width)
1108 *box_width = window_box_width (w, area);
1109 if (box_height)
1110 *box_height = window_box_height (w);
1111 if (box_x)
1112 *box_x = window_box_left (w, area);
1113 if (box_y)
1114 {
1115 *box_y = WINDOW_TOP_EDGE_Y (w);
1116 if (WINDOW_WANTS_HEADER_LINE_P (w))
1117 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1118 }
1119 }
1120
1121
1122 /* Get the bounding box of the display area AREA of window W, without
1123 mode lines. AREA < 0 means the whole window, not including the
1124 left and right fringe of the window. Return in *TOP_LEFT_X
1125 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1126 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1127 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1128 box. */
1129
1130 INLINE void
1131 window_box_edges (w, area, top_left_x, top_left_y,
1132 bottom_right_x, bottom_right_y)
1133 struct window *w;
1134 int area;
1135 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1136 {
1137 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1138 bottom_right_y);
1139 *bottom_right_x += *top_left_x;
1140 *bottom_right_y += *top_left_y;
1141 }
1142
1143
1144 \f
1145 /***********************************************************************
1146 Utilities
1147 ***********************************************************************/
1148
1149 /* Return the bottom y-position of the line the iterator IT is in.
1150 This can modify IT's settings. */
1151
1152 int
1153 line_bottom_y (it)
1154 struct it *it;
1155 {
1156 int line_height = it->max_ascent + it->max_descent;
1157 int line_top_y = it->current_y;
1158
1159 if (line_height == 0)
1160 {
1161 if (last_height)
1162 line_height = last_height;
1163 else if (IT_CHARPOS (*it) < ZV)
1164 {
1165 move_it_by_lines (it, 1, 1);
1166 line_height = (it->max_ascent || it->max_descent
1167 ? it->max_ascent + it->max_descent
1168 : last_height);
1169 }
1170 else
1171 {
1172 struct glyph_row *row = it->glyph_row;
1173
1174 /* Use the default character height. */
1175 it->glyph_row = NULL;
1176 it->what = IT_CHARACTER;
1177 it->c = ' ';
1178 it->len = 1;
1179 PRODUCE_GLYPHS (it);
1180 line_height = it->ascent + it->descent;
1181 it->glyph_row = row;
1182 }
1183 }
1184
1185 return line_top_y + line_height;
1186 }
1187
1188
1189 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1190 1 if POS is visible and the line containing POS is fully visible.
1191 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1192 and header-lines heights. */
1193
1194 int
1195 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1196 struct window *w;
1197 int charpos, *fully, exact_mode_line_heights_p;
1198 {
1199 struct it it;
1200 struct text_pos top;
1201 int visible_p;
1202 struct buffer *old_buffer = NULL;
1203
1204 if (XBUFFER (w->buffer) != current_buffer)
1205 {
1206 old_buffer = current_buffer;
1207 set_buffer_internal_1 (XBUFFER (w->buffer));
1208 }
1209
1210 *fully = visible_p = 0;
1211 SET_TEXT_POS_FROM_MARKER (top, w->start);
1212
1213 /* Compute exact mode line heights, if requested. */
1214 if (exact_mode_line_heights_p)
1215 {
1216 if (WINDOW_WANTS_MODELINE_P (w))
1217 current_mode_line_height
1218 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1219 current_buffer->mode_line_format);
1220
1221 if (WINDOW_WANTS_HEADER_LINE_P (w))
1222 current_header_line_height
1223 = display_mode_line (w, HEADER_LINE_FACE_ID,
1224 current_buffer->header_line_format);
1225 }
1226
1227 start_display (&it, w, top);
1228 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1229 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1230
1231 /* Note that we may overshoot because of invisible text. */
1232 if (IT_CHARPOS (it) >= charpos)
1233 {
1234 int top_y = it.current_y;
1235 int bottom_y = line_bottom_y (&it);
1236 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1237
1238 if (top_y < window_top_y)
1239 visible_p = bottom_y > window_top_y;
1240 else if (top_y < it.last_visible_y)
1241 {
1242 visible_p = 1;
1243 *fully = bottom_y <= it.last_visible_y;
1244 }
1245 }
1246 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1247 {
1248 move_it_by_lines (&it, 1, 0);
1249 if (charpos < IT_CHARPOS (it))
1250 {
1251 visible_p = 1;
1252 *fully = 0;
1253 }
1254 }
1255
1256 if (old_buffer)
1257 set_buffer_internal_1 (old_buffer);
1258
1259 current_header_line_height = current_mode_line_height = -1;
1260 return visible_p;
1261 }
1262
1263
1264 /* Return the next character from STR which is MAXLEN bytes long.
1265 Return in *LEN the length of the character. This is like
1266 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1267 we find one, we return a `?', but with the length of the invalid
1268 character. */
1269
1270 static INLINE int
1271 string_char_and_length (str, maxlen, len)
1272 const unsigned char *str;
1273 int maxlen, *len;
1274 {
1275 int c;
1276
1277 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1278 if (!CHAR_VALID_P (c, 1))
1279 /* We may not change the length here because other places in Emacs
1280 don't use this function, i.e. they silently accept invalid
1281 characters. */
1282 c = '?';
1283
1284 return c;
1285 }
1286
1287
1288
1289 /* Given a position POS containing a valid character and byte position
1290 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1291
1292 static struct text_pos
1293 string_pos_nchars_ahead (pos, string, nchars)
1294 struct text_pos pos;
1295 Lisp_Object string;
1296 int nchars;
1297 {
1298 xassert (STRINGP (string) && nchars >= 0);
1299
1300 if (STRING_MULTIBYTE (string))
1301 {
1302 int rest = SBYTES (string) - BYTEPOS (pos);
1303 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1304 int len;
1305
1306 while (nchars--)
1307 {
1308 string_char_and_length (p, rest, &len);
1309 p += len, rest -= len;
1310 xassert (rest >= 0);
1311 CHARPOS (pos) += 1;
1312 BYTEPOS (pos) += len;
1313 }
1314 }
1315 else
1316 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1317
1318 return pos;
1319 }
1320
1321
1322 /* Value is the text position, i.e. character and byte position,
1323 for character position CHARPOS in STRING. */
1324
1325 static INLINE struct text_pos
1326 string_pos (charpos, string)
1327 int charpos;
1328 Lisp_Object string;
1329 {
1330 struct text_pos pos;
1331 xassert (STRINGP (string));
1332 xassert (charpos >= 0);
1333 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1334 return pos;
1335 }
1336
1337
1338 /* Value is a text position, i.e. character and byte position, for
1339 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1340 means recognize multibyte characters. */
1341
1342 static struct text_pos
1343 c_string_pos (charpos, s, multibyte_p)
1344 int charpos;
1345 unsigned char *s;
1346 int multibyte_p;
1347 {
1348 struct text_pos pos;
1349
1350 xassert (s != NULL);
1351 xassert (charpos >= 0);
1352
1353 if (multibyte_p)
1354 {
1355 int rest = strlen (s), len;
1356
1357 SET_TEXT_POS (pos, 0, 0);
1358 while (charpos--)
1359 {
1360 string_char_and_length (s, rest, &len);
1361 s += len, rest -= len;
1362 xassert (rest >= 0);
1363 CHARPOS (pos) += 1;
1364 BYTEPOS (pos) += len;
1365 }
1366 }
1367 else
1368 SET_TEXT_POS (pos, charpos, charpos);
1369
1370 return pos;
1371 }
1372
1373
1374 /* Value is the number of characters in C string S. MULTIBYTE_P
1375 non-zero means recognize multibyte characters. */
1376
1377 static int
1378 number_of_chars (s, multibyte_p)
1379 unsigned char *s;
1380 int multibyte_p;
1381 {
1382 int nchars;
1383
1384 if (multibyte_p)
1385 {
1386 int rest = strlen (s), len;
1387 unsigned char *p = (unsigned char *) s;
1388
1389 for (nchars = 0; rest > 0; ++nchars)
1390 {
1391 string_char_and_length (p, rest, &len);
1392 rest -= len, p += len;
1393 }
1394 }
1395 else
1396 nchars = strlen (s);
1397
1398 return nchars;
1399 }
1400
1401
1402 /* Compute byte position NEWPOS->bytepos corresponding to
1403 NEWPOS->charpos. POS is a known position in string STRING.
1404 NEWPOS->charpos must be >= POS.charpos. */
1405
1406 static void
1407 compute_string_pos (newpos, pos, string)
1408 struct text_pos *newpos, pos;
1409 Lisp_Object string;
1410 {
1411 xassert (STRINGP (string));
1412 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1413
1414 if (STRING_MULTIBYTE (string))
1415 *newpos = string_pos_nchars_ahead (pos, string,
1416 CHARPOS (*newpos) - CHARPOS (pos));
1417 else
1418 BYTEPOS (*newpos) = CHARPOS (*newpos);
1419 }
1420
1421 /* EXPORT:
1422 Return an estimation of the pixel height of mode or top lines on
1423 frame F. FACE_ID specifies what line's height to estimate. */
1424
1425 int
1426 estimate_mode_line_height (f, face_id)
1427 struct frame *f;
1428 enum face_id face_id;
1429 {
1430 #ifdef HAVE_WINDOW_SYSTEM
1431 if (FRAME_WINDOW_P (f))
1432 {
1433 int height = FONT_HEIGHT (FRAME_FONT (f));
1434
1435 /* This function is called so early when Emacs starts that the face
1436 cache and mode line face are not yet initialized. */
1437 if (FRAME_FACE_CACHE (f))
1438 {
1439 struct face *face = FACE_FROM_ID (f, face_id);
1440 if (face)
1441 {
1442 if (face->font)
1443 height = FONT_HEIGHT (face->font);
1444 if (face->box_line_width > 0)
1445 height += 2 * face->box_line_width;
1446 }
1447 }
1448
1449 return height;
1450 }
1451 #endif
1452
1453 return 1;
1454 }
1455
1456 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1457 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1458 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1459 not force the value into range. */
1460
1461 void
1462 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1463 FRAME_PTR f;
1464 register int pix_x, pix_y;
1465 int *x, *y;
1466 NativeRectangle *bounds;
1467 int noclip;
1468 {
1469
1470 #ifdef HAVE_WINDOW_SYSTEM
1471 if (FRAME_WINDOW_P (f))
1472 {
1473 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1474 even for negative values. */
1475 if (pix_x < 0)
1476 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1477 if (pix_y < 0)
1478 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1479
1480 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1481 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1482
1483 if (bounds)
1484 STORE_NATIVE_RECT (*bounds,
1485 FRAME_COL_TO_PIXEL_X (f, pix_x),
1486 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1487 FRAME_COLUMN_WIDTH (f) - 1,
1488 FRAME_LINE_HEIGHT (f) - 1);
1489
1490 if (!noclip)
1491 {
1492 if (pix_x < 0)
1493 pix_x = 0;
1494 else if (pix_x > FRAME_TOTAL_COLS (f))
1495 pix_x = FRAME_TOTAL_COLS (f);
1496
1497 if (pix_y < 0)
1498 pix_y = 0;
1499 else if (pix_y > FRAME_LINES (f))
1500 pix_y = FRAME_LINES (f);
1501 }
1502 }
1503 #endif
1504
1505 *x = pix_x;
1506 *y = pix_y;
1507 }
1508
1509
1510 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1511 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1512 can't tell the positions because W's display is not up to date,
1513 return 0. */
1514
1515 int
1516 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1517 struct window *w;
1518 int hpos, vpos;
1519 int *frame_x, *frame_y;
1520 {
1521 #ifdef HAVE_WINDOW_SYSTEM
1522 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1523 {
1524 int success_p;
1525
1526 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1527 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1528
1529 if (display_completed)
1530 {
1531 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1532 struct glyph *glyph = row->glyphs[TEXT_AREA];
1533 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1534
1535 hpos = row->x;
1536 vpos = row->y;
1537 while (glyph < end)
1538 {
1539 hpos += glyph->pixel_width;
1540 ++glyph;
1541 }
1542
1543 success_p = 1;
1544 }
1545 else
1546 {
1547 hpos = vpos = 0;
1548 success_p = 0;
1549 }
1550
1551 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1552 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1553 return success_p;
1554 }
1555 #endif
1556
1557 *frame_x = hpos;
1558 *frame_y = vpos;
1559 return 1;
1560 }
1561
1562
1563 #ifdef HAVE_WINDOW_SYSTEM
1564
1565 /* Find the glyph under window-relative coordinates X/Y in window W.
1566 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1567 strings. Return in *HPOS and *VPOS the row and column number of
1568 the glyph found. Return in *AREA the glyph area containing X.
1569 Value is a pointer to the glyph found or null if X/Y is not on
1570 text, or we can't tell because W's current matrix is not up to
1571 date. */
1572
1573 static struct glyph *
1574 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area, buffer_only_p)
1575 struct window *w;
1576 int x, y;
1577 int *hpos, *vpos, *area;
1578 int buffer_only_p;
1579 {
1580 struct glyph *glyph, *end;
1581 struct glyph_row *row = NULL;
1582 int x0, i;
1583
1584 /* Find row containing Y. Give up if some row is not enabled. */
1585 for (i = 0; i < w->current_matrix->nrows; ++i)
1586 {
1587 row = MATRIX_ROW (w->current_matrix, i);
1588 if (!row->enabled_p)
1589 return NULL;
1590 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1591 break;
1592 }
1593
1594 *vpos = i;
1595 *hpos = 0;
1596
1597 /* Give up if Y is not in the window. */
1598 if (i == w->current_matrix->nrows)
1599 return NULL;
1600
1601 /* Get the glyph area containing X. */
1602 if (w->pseudo_window_p)
1603 {
1604 *area = TEXT_AREA;
1605 x0 = 0;
1606 }
1607 else
1608 {
1609 if (x < window_box_left_offset (w, TEXT_AREA))
1610 {
1611 *area = LEFT_MARGIN_AREA;
1612 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1613 }
1614 else if (x < window_box_right_offset (w, TEXT_AREA))
1615 {
1616 *area = TEXT_AREA;
1617 x0 = window_box_left_offset (w, TEXT_AREA);
1618 }
1619 else
1620 {
1621 *area = RIGHT_MARGIN_AREA;
1622 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1623 }
1624 }
1625
1626 /* Find glyph containing X. */
1627 glyph = row->glyphs[*area];
1628 end = glyph + row->used[*area];
1629 while (glyph < end)
1630 {
1631 if (x < x0 + glyph->pixel_width)
1632 {
1633 if (w->pseudo_window_p)
1634 break;
1635 else if (!buffer_only_p || BUFFERP (glyph->object))
1636 break;
1637 }
1638
1639 x0 += glyph->pixel_width;
1640 ++glyph;
1641 }
1642
1643 if (glyph == end)
1644 return NULL;
1645
1646 *hpos = glyph - row->glyphs[*area];
1647 return glyph;
1648 }
1649
1650
1651 /* EXPORT:
1652 Convert frame-relative x/y to coordinates relative to window W.
1653 Takes pseudo-windows into account. */
1654
1655 void
1656 frame_to_window_pixel_xy (w, x, y)
1657 struct window *w;
1658 int *x, *y;
1659 {
1660 if (w->pseudo_window_p)
1661 {
1662 /* A pseudo-window is always full-width, and starts at the
1663 left edge of the frame, plus a frame border. */
1664 struct frame *f = XFRAME (w->frame);
1665 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1666 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1667 }
1668 else
1669 {
1670 *x -= WINDOW_LEFT_EDGE_X (w);
1671 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1672 }
1673 }
1674
1675 /* EXPORT:
1676 Return in *R the clipping rectangle for glyph string S. */
1677
1678 void
1679 get_glyph_string_clip_rect (s, nr)
1680 struct glyph_string *s;
1681 NativeRectangle *nr;
1682 {
1683 XRectangle r;
1684
1685 if (s->row->full_width_p)
1686 {
1687 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1688 r.x = WINDOW_LEFT_EDGE_X (s->w);
1689 r.width = WINDOW_TOTAL_WIDTH (s->w);
1690
1691 /* Unless displaying a mode or menu bar line, which are always
1692 fully visible, clip to the visible part of the row. */
1693 if (s->w->pseudo_window_p)
1694 r.height = s->row->visible_height;
1695 else
1696 r.height = s->height;
1697 }
1698 else
1699 {
1700 /* This is a text line that may be partially visible. */
1701 r.x = window_box_left (s->w, s->area);
1702 r.width = window_box_width (s->w, s->area);
1703 r.height = s->row->visible_height;
1704 }
1705
1706 /* If S draws overlapping rows, it's sufficient to use the top and
1707 bottom of the window for clipping because this glyph string
1708 intentionally draws over other lines. */
1709 if (s->for_overlaps_p)
1710 {
1711 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1712 r.height = window_text_bottom_y (s->w) - r.y;
1713 }
1714 else
1715 {
1716 /* Don't use S->y for clipping because it doesn't take partially
1717 visible lines into account. For example, it can be negative for
1718 partially visible lines at the top of a window. */
1719 if (!s->row->full_width_p
1720 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1721 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1722 else
1723 r.y = max (0, s->row->y);
1724
1725 /* If drawing a tool-bar window, draw it over the internal border
1726 at the top of the window. */
1727 if (s->w == XWINDOW (s->f->tool_bar_window))
1728 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1729 }
1730
1731 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1732
1733 #ifdef HAVE_NTGUI
1734 /* ++KFS: From W32 port, but it looks ok for all platforms to me. */
1735 /* If drawing the cursor, don't let glyph draw outside its
1736 advertised boundaries. Cleartype does this under some circumstances. */
1737 if (s->hl == DRAW_CURSOR)
1738 {
1739 if (s->x > r.x)
1740 {
1741 r.width -= s->x - r.x;
1742 r.x = s->x;
1743 }
1744 r.width = min (r.width, s->first_glyph->pixel_width);
1745 }
1746 #endif
1747
1748 #ifdef CONVERT_FROM_XRECT
1749 CONVERT_FROM_XRECT (r, *nr);
1750 #else
1751 *nr = r;
1752 #endif
1753 }
1754
1755 #endif /* HAVE_WINDOW_SYSTEM */
1756
1757 \f
1758 /***********************************************************************
1759 Lisp form evaluation
1760 ***********************************************************************/
1761
1762 /* Error handler for safe_eval and safe_call. */
1763
1764 static Lisp_Object
1765 safe_eval_handler (arg)
1766 Lisp_Object arg;
1767 {
1768 add_to_log ("Error during redisplay: %s", arg, Qnil);
1769 return Qnil;
1770 }
1771
1772
1773 /* Evaluate SEXPR and return the result, or nil if something went
1774 wrong. Prevent redisplay during the evaluation. */
1775
1776 Lisp_Object
1777 safe_eval (sexpr)
1778 Lisp_Object sexpr;
1779 {
1780 Lisp_Object val;
1781
1782 if (inhibit_eval_during_redisplay)
1783 val = Qnil;
1784 else
1785 {
1786 int count = SPECPDL_INDEX ();
1787 struct gcpro gcpro1;
1788
1789 GCPRO1 (sexpr);
1790 specbind (Qinhibit_redisplay, Qt);
1791 /* Use Qt to ensure debugger does not run,
1792 so there is no possibility of wanting to redisplay. */
1793 val = internal_condition_case_1 (Feval, sexpr, Qt,
1794 safe_eval_handler);
1795 UNGCPRO;
1796 val = unbind_to (count, val);
1797 }
1798
1799 return val;
1800 }
1801
1802
1803 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1804 Return the result, or nil if something went wrong. Prevent
1805 redisplay during the evaluation. */
1806
1807 Lisp_Object
1808 safe_call (nargs, args)
1809 int nargs;
1810 Lisp_Object *args;
1811 {
1812 Lisp_Object val;
1813
1814 if (inhibit_eval_during_redisplay)
1815 val = Qnil;
1816 else
1817 {
1818 int count = SPECPDL_INDEX ();
1819 struct gcpro gcpro1;
1820
1821 GCPRO1 (args[0]);
1822 gcpro1.nvars = nargs;
1823 specbind (Qinhibit_redisplay, Qt);
1824 /* Use Qt to ensure debugger does not run,
1825 so there is no possibility of wanting to redisplay. */
1826 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1827 safe_eval_handler);
1828 UNGCPRO;
1829 val = unbind_to (count, val);
1830 }
1831
1832 return val;
1833 }
1834
1835
1836 /* Call function FN with one argument ARG.
1837 Return the result, or nil if something went wrong. */
1838
1839 Lisp_Object
1840 safe_call1 (fn, arg)
1841 Lisp_Object fn, arg;
1842 {
1843 Lisp_Object args[2];
1844 args[0] = fn;
1845 args[1] = arg;
1846 return safe_call (2, args);
1847 }
1848
1849
1850 \f
1851 /***********************************************************************
1852 Debugging
1853 ***********************************************************************/
1854
1855 #if 0
1856
1857 /* Define CHECK_IT to perform sanity checks on iterators.
1858 This is for debugging. It is too slow to do unconditionally. */
1859
1860 static void
1861 check_it (it)
1862 struct it *it;
1863 {
1864 if (it->method == next_element_from_string)
1865 {
1866 xassert (STRINGP (it->string));
1867 xassert (IT_STRING_CHARPOS (*it) >= 0);
1868 }
1869 else if (it->method == next_element_from_buffer)
1870 {
1871 /* Check that character and byte positions agree. */
1872 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1873 }
1874
1875 if (it->dpvec)
1876 xassert (it->current.dpvec_index >= 0);
1877 else
1878 xassert (it->current.dpvec_index < 0);
1879 }
1880
1881 #define CHECK_IT(IT) check_it ((IT))
1882
1883 #else /* not 0 */
1884
1885 #define CHECK_IT(IT) (void) 0
1886
1887 #endif /* not 0 */
1888
1889
1890 #if GLYPH_DEBUG
1891
1892 /* Check that the window end of window W is what we expect it
1893 to be---the last row in the current matrix displaying text. */
1894
1895 static void
1896 check_window_end (w)
1897 struct window *w;
1898 {
1899 if (!MINI_WINDOW_P (w)
1900 && !NILP (w->window_end_valid))
1901 {
1902 struct glyph_row *row;
1903 xassert ((row = MATRIX_ROW (w->current_matrix,
1904 XFASTINT (w->window_end_vpos)),
1905 !row->enabled_p
1906 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1907 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1908 }
1909 }
1910
1911 #define CHECK_WINDOW_END(W) check_window_end ((W))
1912
1913 #else /* not GLYPH_DEBUG */
1914
1915 #define CHECK_WINDOW_END(W) (void) 0
1916
1917 #endif /* not GLYPH_DEBUG */
1918
1919
1920 \f
1921 /***********************************************************************
1922 Iterator initialization
1923 ***********************************************************************/
1924
1925 /* Initialize IT for displaying current_buffer in window W, starting
1926 at character position CHARPOS. CHARPOS < 0 means that no buffer
1927 position is specified which is useful when the iterator is assigned
1928 a position later. BYTEPOS is the byte position corresponding to
1929 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1930
1931 If ROW is not null, calls to produce_glyphs with IT as parameter
1932 will produce glyphs in that row.
1933
1934 BASE_FACE_ID is the id of a base face to use. It must be one of
1935 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1936 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1937 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1938
1939 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1940 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1941 will be initialized to use the corresponding mode line glyph row of
1942 the desired matrix of W. */
1943
1944 void
1945 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1946 struct it *it;
1947 struct window *w;
1948 int charpos, bytepos;
1949 struct glyph_row *row;
1950 enum face_id base_face_id;
1951 {
1952 int highlight_region_p;
1953
1954 /* Some precondition checks. */
1955 xassert (w != NULL && it != NULL);
1956 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1957 && charpos <= ZV));
1958
1959 /* If face attributes have been changed since the last redisplay,
1960 free realized faces now because they depend on face definitions
1961 that might have changed. Don't free faces while there might be
1962 desired matrices pending which reference these faces. */
1963 if (face_change_count && !inhibit_free_realized_faces)
1964 {
1965 face_change_count = 0;
1966 free_all_realized_faces (Qnil);
1967 }
1968
1969 /* Use one of the mode line rows of W's desired matrix if
1970 appropriate. */
1971 if (row == NULL)
1972 {
1973 if (base_face_id == MODE_LINE_FACE_ID
1974 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
1975 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
1976 else if (base_face_id == HEADER_LINE_FACE_ID)
1977 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
1978 }
1979
1980 /* Clear IT. */
1981 bzero (it, sizeof *it);
1982 it->current.overlay_string_index = -1;
1983 it->current.dpvec_index = -1;
1984 it->base_face_id = base_face_id;
1985
1986 /* The window in which we iterate over current_buffer: */
1987 XSETWINDOW (it->window, w);
1988 it->w = w;
1989 it->f = XFRAME (w->frame);
1990
1991 /* Extra space between lines (on window systems only). */
1992 if (base_face_id == DEFAULT_FACE_ID
1993 && FRAME_WINDOW_P (it->f))
1994 {
1995 if (NATNUMP (current_buffer->extra_line_spacing))
1996 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
1997 else if (it->f->extra_line_spacing > 0)
1998 it->extra_line_spacing = it->f->extra_line_spacing;
1999 }
2000
2001 /* If realized faces have been removed, e.g. because of face
2002 attribute changes of named faces, recompute them. When running
2003 in batch mode, the face cache of Vterminal_frame is null. If
2004 we happen to get called, make a dummy face cache. */
2005 if (
2006 #ifndef WINDOWSNT
2007 noninteractive &&
2008 #endif
2009 FRAME_FACE_CACHE (it->f) == NULL)
2010 init_frame_faces (it->f);
2011 if (FRAME_FACE_CACHE (it->f)->used == 0)
2012 recompute_basic_faces (it->f);
2013
2014 /* Current value of the `space-width', and 'height' properties. */
2015 it->space_width = Qnil;
2016 it->font_height = Qnil;
2017
2018 /* Are control characters displayed as `^C'? */
2019 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2020
2021 /* -1 means everything between a CR and the following line end
2022 is invisible. >0 means lines indented more than this value are
2023 invisible. */
2024 it->selective = (INTEGERP (current_buffer->selective_display)
2025 ? XFASTINT (current_buffer->selective_display)
2026 : (!NILP (current_buffer->selective_display)
2027 ? -1 : 0));
2028 it->selective_display_ellipsis_p
2029 = !NILP (current_buffer->selective_display_ellipses);
2030
2031 /* Display table to use. */
2032 it->dp = window_display_table (w);
2033
2034 /* Are multibyte characters enabled in current_buffer? */
2035 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2036
2037 /* Non-zero if we should highlight the region. */
2038 highlight_region_p
2039 = (!NILP (Vtransient_mark_mode)
2040 && !NILP (current_buffer->mark_active)
2041 && XMARKER (current_buffer->mark)->buffer != 0);
2042
2043 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2044 start and end of a visible region in window IT->w. Set both to
2045 -1 to indicate no region. */
2046 if (highlight_region_p
2047 /* Maybe highlight only in selected window. */
2048 && (/* Either show region everywhere. */
2049 highlight_nonselected_windows
2050 /* Or show region in the selected window. */
2051 || w == XWINDOW (selected_window)
2052 /* Or show the region if we are in the mini-buffer and W is
2053 the window the mini-buffer refers to. */
2054 || (MINI_WINDOW_P (XWINDOW (selected_window))
2055 && WINDOWP (minibuf_selected_window)
2056 && w == XWINDOW (minibuf_selected_window))))
2057 {
2058 int charpos = marker_position (current_buffer->mark);
2059 it->region_beg_charpos = min (PT, charpos);
2060 it->region_end_charpos = max (PT, charpos);
2061 }
2062 else
2063 it->region_beg_charpos = it->region_end_charpos = -1;
2064
2065 /* Get the position at which the redisplay_end_trigger hook should
2066 be run, if it is to be run at all. */
2067 if (MARKERP (w->redisplay_end_trigger)
2068 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2069 it->redisplay_end_trigger_charpos
2070 = marker_position (w->redisplay_end_trigger);
2071 else if (INTEGERP (w->redisplay_end_trigger))
2072 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2073
2074 /* Correct bogus values of tab_width. */
2075 it->tab_width = XINT (current_buffer->tab_width);
2076 if (it->tab_width <= 0 || it->tab_width > 1000)
2077 it->tab_width = 8;
2078
2079 /* Are lines in the display truncated? */
2080 it->truncate_lines_p
2081 = (base_face_id != DEFAULT_FACE_ID
2082 || XINT (it->w->hscroll)
2083 || (truncate_partial_width_windows
2084 && !WINDOW_FULL_WIDTH_P (it->w))
2085 || !NILP (current_buffer->truncate_lines));
2086
2087 /* Get dimensions of truncation and continuation glyphs. These are
2088 displayed as fringe bitmaps under X, so we don't need them for such
2089 frames. */
2090 if (!FRAME_WINDOW_P (it->f))
2091 {
2092 if (it->truncate_lines_p)
2093 {
2094 /* We will need the truncation glyph. */
2095 xassert (it->glyph_row == NULL);
2096 produce_special_glyphs (it, IT_TRUNCATION);
2097 it->truncation_pixel_width = it->pixel_width;
2098 }
2099 else
2100 {
2101 /* We will need the continuation glyph. */
2102 xassert (it->glyph_row == NULL);
2103 produce_special_glyphs (it, IT_CONTINUATION);
2104 it->continuation_pixel_width = it->pixel_width;
2105 }
2106
2107 /* Reset these values to zero because the produce_special_glyphs
2108 above has changed them. */
2109 it->pixel_width = it->ascent = it->descent = 0;
2110 it->phys_ascent = it->phys_descent = 0;
2111 }
2112
2113 /* Set this after getting the dimensions of truncation and
2114 continuation glyphs, so that we don't produce glyphs when calling
2115 produce_special_glyphs, above. */
2116 it->glyph_row = row;
2117 it->area = TEXT_AREA;
2118
2119 /* Get the dimensions of the display area. The display area
2120 consists of the visible window area plus a horizontally scrolled
2121 part to the left of the window. All x-values are relative to the
2122 start of this total display area. */
2123 if (base_face_id != DEFAULT_FACE_ID)
2124 {
2125 /* Mode lines, menu bar in terminal frames. */
2126 it->first_visible_x = 0;
2127 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2128 }
2129 else
2130 {
2131 it->first_visible_x
2132 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2133 it->last_visible_x = (it->first_visible_x
2134 + window_box_width (w, TEXT_AREA));
2135
2136 /* If we truncate lines, leave room for the truncator glyph(s) at
2137 the right margin. Otherwise, leave room for the continuation
2138 glyph(s). Truncation and continuation glyphs are not inserted
2139 for window-based redisplay. */
2140 if (!FRAME_WINDOW_P (it->f))
2141 {
2142 if (it->truncate_lines_p)
2143 it->last_visible_x -= it->truncation_pixel_width;
2144 else
2145 it->last_visible_x -= it->continuation_pixel_width;
2146 }
2147
2148 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2149 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2150 }
2151
2152 /* Leave room for a border glyph. */
2153 if (!FRAME_WINDOW_P (it->f)
2154 && !WINDOW_RIGHTMOST_P (it->w))
2155 it->last_visible_x -= 1;
2156
2157 it->last_visible_y = window_text_bottom_y (w);
2158
2159 /* For mode lines and alike, arrange for the first glyph having a
2160 left box line if the face specifies a box. */
2161 if (base_face_id != DEFAULT_FACE_ID)
2162 {
2163 struct face *face;
2164
2165 it->face_id = base_face_id;
2166
2167 /* If we have a boxed mode line, make the first character appear
2168 with a left box line. */
2169 face = FACE_FROM_ID (it->f, base_face_id);
2170 if (face->box != FACE_NO_BOX)
2171 it->start_of_box_run_p = 1;
2172 }
2173
2174 /* If a buffer position was specified, set the iterator there,
2175 getting overlays and face properties from that position. */
2176 if (charpos >= BUF_BEG (current_buffer))
2177 {
2178 it->end_charpos = ZV;
2179 it->face_id = -1;
2180 IT_CHARPOS (*it) = charpos;
2181
2182 /* Compute byte position if not specified. */
2183 if (bytepos < charpos)
2184 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2185 else
2186 IT_BYTEPOS (*it) = bytepos;
2187
2188 /* Compute faces etc. */
2189 reseat (it, it->current.pos, 1);
2190 }
2191
2192 CHECK_IT (it);
2193 }
2194
2195
2196 /* Initialize IT for the display of window W with window start POS. */
2197
2198 void
2199 start_display (it, w, pos)
2200 struct it *it;
2201 struct window *w;
2202 struct text_pos pos;
2203 {
2204 struct glyph_row *row;
2205 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2206
2207 row = w->desired_matrix->rows + first_vpos;
2208 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2209
2210 if (!it->truncate_lines_p)
2211 {
2212 int start_at_line_beg_p;
2213 int first_y = it->current_y;
2214
2215 /* If window start is not at a line start, skip forward to POS to
2216 get the correct continuation lines width. */
2217 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2218 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2219 if (!start_at_line_beg_p)
2220 {
2221 int new_x;
2222
2223 reseat_at_previous_visible_line_start (it);
2224 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2225
2226 new_x = it->current_x + it->pixel_width;
2227
2228 /* If lines are continued, this line may end in the middle
2229 of a multi-glyph character (e.g. a control character
2230 displayed as \003, or in the middle of an overlay
2231 string). In this case move_it_to above will not have
2232 taken us to the start of the continuation line but to the
2233 end of the continued line. */
2234 if (it->current_x > 0
2235 && !it->truncate_lines_p /* Lines are continued. */
2236 && (/* And glyph doesn't fit on the line. */
2237 new_x > it->last_visible_x
2238 /* Or it fits exactly and we're on a window
2239 system frame. */
2240 || (new_x == it->last_visible_x
2241 && FRAME_WINDOW_P (it->f))))
2242 {
2243 if (it->current.dpvec_index >= 0
2244 || it->current.overlay_string_index >= 0)
2245 {
2246 set_iterator_to_next (it, 1);
2247 move_it_in_display_line_to (it, -1, -1, 0);
2248 }
2249
2250 it->continuation_lines_width += it->current_x;
2251 }
2252
2253 /* We're starting a new display line, not affected by the
2254 height of the continued line, so clear the appropriate
2255 fields in the iterator structure. */
2256 it->max_ascent = it->max_descent = 0;
2257 it->max_phys_ascent = it->max_phys_descent = 0;
2258
2259 it->current_y = first_y;
2260 it->vpos = 0;
2261 it->current_x = it->hpos = 0;
2262 }
2263 }
2264
2265 #if 0 /* Don't assert the following because start_display is sometimes
2266 called intentionally with a window start that is not at a
2267 line start. Please leave this code in as a comment. */
2268
2269 /* Window start should be on a line start, now. */
2270 xassert (it->continuation_lines_width
2271 || IT_CHARPOS (it) == BEGV
2272 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2273 #endif /* 0 */
2274 }
2275
2276
2277 /* Return 1 if POS is a position in ellipses displayed for invisible
2278 text. W is the window we display, for text property lookup. */
2279
2280 static int
2281 in_ellipses_for_invisible_text_p (pos, w)
2282 struct display_pos *pos;
2283 struct window *w;
2284 {
2285 Lisp_Object prop, window;
2286 int ellipses_p = 0;
2287 int charpos = CHARPOS (pos->pos);
2288
2289 /* If POS specifies a position in a display vector, this might
2290 be for an ellipsis displayed for invisible text. We won't
2291 get the iterator set up for delivering that ellipsis unless
2292 we make sure that it gets aware of the invisible text. */
2293 if (pos->dpvec_index >= 0
2294 && pos->overlay_string_index < 0
2295 && CHARPOS (pos->string_pos) < 0
2296 && charpos > BEGV
2297 && (XSETWINDOW (window, w),
2298 prop = Fget_char_property (make_number (charpos),
2299 Qinvisible, window),
2300 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2301 {
2302 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2303 window);
2304 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2305 }
2306
2307 return ellipses_p;
2308 }
2309
2310
2311 /* Initialize IT for stepping through current_buffer in window W,
2312 starting at position POS that includes overlay string and display
2313 vector/ control character translation position information. Value
2314 is zero if there are overlay strings with newlines at POS. */
2315
2316 static int
2317 init_from_display_pos (it, w, pos)
2318 struct it *it;
2319 struct window *w;
2320 struct display_pos *pos;
2321 {
2322 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2323 int i, overlay_strings_with_newlines = 0;
2324
2325 /* If POS specifies a position in a display vector, this might
2326 be for an ellipsis displayed for invisible text. We won't
2327 get the iterator set up for delivering that ellipsis unless
2328 we make sure that it gets aware of the invisible text. */
2329 if (in_ellipses_for_invisible_text_p (pos, w))
2330 {
2331 --charpos;
2332 bytepos = 0;
2333 }
2334
2335 /* Keep in mind: the call to reseat in init_iterator skips invisible
2336 text, so we might end up at a position different from POS. This
2337 is only a problem when POS is a row start after a newline and an
2338 overlay starts there with an after-string, and the overlay has an
2339 invisible property. Since we don't skip invisible text in
2340 display_line and elsewhere immediately after consuming the
2341 newline before the row start, such a POS will not be in a string,
2342 but the call to init_iterator below will move us to the
2343 after-string. */
2344 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2345
2346 for (i = 0; i < it->n_overlay_strings; ++i)
2347 {
2348 const char *s = SDATA (it->overlay_strings[i]);
2349 const char *e = s + SBYTES (it->overlay_strings[i]);
2350
2351 while (s < e && *s != '\n')
2352 ++s;
2353
2354 if (s < e)
2355 {
2356 overlay_strings_with_newlines = 1;
2357 break;
2358 }
2359 }
2360
2361 /* If position is within an overlay string, set up IT to the right
2362 overlay string. */
2363 if (pos->overlay_string_index >= 0)
2364 {
2365 int relative_index;
2366
2367 /* If the first overlay string happens to have a `display'
2368 property for an image, the iterator will be set up for that
2369 image, and we have to undo that setup first before we can
2370 correct the overlay string index. */
2371 if (it->method == next_element_from_image)
2372 pop_it (it);
2373
2374 /* We already have the first chunk of overlay strings in
2375 IT->overlay_strings. Load more until the one for
2376 pos->overlay_string_index is in IT->overlay_strings. */
2377 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2378 {
2379 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2380 it->current.overlay_string_index = 0;
2381 while (n--)
2382 {
2383 load_overlay_strings (it, 0);
2384 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2385 }
2386 }
2387
2388 it->current.overlay_string_index = pos->overlay_string_index;
2389 relative_index = (it->current.overlay_string_index
2390 % OVERLAY_STRING_CHUNK_SIZE);
2391 it->string = it->overlay_strings[relative_index];
2392 xassert (STRINGP (it->string));
2393 it->current.string_pos = pos->string_pos;
2394 it->method = next_element_from_string;
2395 }
2396
2397 #if 0 /* This is bogus because POS not having an overlay string
2398 position does not mean it's after the string. Example: A
2399 line starting with a before-string and initialization of IT
2400 to the previous row's end position. */
2401 else if (it->current.overlay_string_index >= 0)
2402 {
2403 /* If POS says we're already after an overlay string ending at
2404 POS, make sure to pop the iterator because it will be in
2405 front of that overlay string. When POS is ZV, we've thereby
2406 also ``processed'' overlay strings at ZV. */
2407 while (it->sp)
2408 pop_it (it);
2409 it->current.overlay_string_index = -1;
2410 it->method = next_element_from_buffer;
2411 if (CHARPOS (pos->pos) == ZV)
2412 it->overlay_strings_at_end_processed_p = 1;
2413 }
2414 #endif /* 0 */
2415
2416 if (CHARPOS (pos->string_pos) >= 0)
2417 {
2418 /* Recorded position is not in an overlay string, but in another
2419 string. This can only be a string from a `display' property.
2420 IT should already be filled with that string. */
2421 it->current.string_pos = pos->string_pos;
2422 xassert (STRINGP (it->string));
2423 }
2424
2425 /* Restore position in display vector translations, control
2426 character translations or ellipses. */
2427 if (pos->dpvec_index >= 0)
2428 {
2429 if (it->dpvec == NULL)
2430 get_next_display_element (it);
2431 xassert (it->dpvec && it->current.dpvec_index == 0);
2432 it->current.dpvec_index = pos->dpvec_index;
2433 }
2434
2435 CHECK_IT (it);
2436 return !overlay_strings_with_newlines;
2437 }
2438
2439
2440 /* Initialize IT for stepping through current_buffer in window W
2441 starting at ROW->start. */
2442
2443 static void
2444 init_to_row_start (it, w, row)
2445 struct it *it;
2446 struct window *w;
2447 struct glyph_row *row;
2448 {
2449 init_from_display_pos (it, w, &row->start);
2450 it->continuation_lines_width = row->continuation_lines_width;
2451 CHECK_IT (it);
2452 }
2453
2454
2455 /* Initialize IT for stepping through current_buffer in window W
2456 starting in the line following ROW, i.e. starting at ROW->end.
2457 Value is zero if there are overlay strings with newlines at ROW's
2458 end position. */
2459
2460 static int
2461 init_to_row_end (it, w, row)
2462 struct it *it;
2463 struct window *w;
2464 struct glyph_row *row;
2465 {
2466 int success = 0;
2467
2468 if (init_from_display_pos (it, w, &row->end))
2469 {
2470 if (row->continued_p)
2471 it->continuation_lines_width
2472 = row->continuation_lines_width + row->pixel_width;
2473 CHECK_IT (it);
2474 success = 1;
2475 }
2476
2477 return success;
2478 }
2479
2480
2481
2482 \f
2483 /***********************************************************************
2484 Text properties
2485 ***********************************************************************/
2486
2487 /* Called when IT reaches IT->stop_charpos. Handle text property and
2488 overlay changes. Set IT->stop_charpos to the next position where
2489 to stop. */
2490
2491 static void
2492 handle_stop (it)
2493 struct it *it;
2494 {
2495 enum prop_handled handled;
2496 int handle_overlay_change_p = 1;
2497 struct props *p;
2498
2499 it->dpvec = NULL;
2500 it->current.dpvec_index = -1;
2501
2502 do
2503 {
2504 handled = HANDLED_NORMALLY;
2505
2506 /* Call text property handlers. */
2507 for (p = it_props; p->handler; ++p)
2508 {
2509 handled = p->handler (it);
2510
2511 if (handled == HANDLED_RECOMPUTE_PROPS)
2512 break;
2513 else if (handled == HANDLED_RETURN)
2514 return;
2515 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2516 handle_overlay_change_p = 0;
2517 }
2518
2519 if (handled != HANDLED_RECOMPUTE_PROPS)
2520 {
2521 /* Don't check for overlay strings below when set to deliver
2522 characters from a display vector. */
2523 if (it->method == next_element_from_display_vector)
2524 handle_overlay_change_p = 0;
2525
2526 /* Handle overlay changes. */
2527 if (handle_overlay_change_p)
2528 handled = handle_overlay_change (it);
2529
2530 /* Determine where to stop next. */
2531 if (handled == HANDLED_NORMALLY)
2532 compute_stop_pos (it);
2533 }
2534 }
2535 while (handled == HANDLED_RECOMPUTE_PROPS);
2536 }
2537
2538
2539 /* Compute IT->stop_charpos from text property and overlay change
2540 information for IT's current position. */
2541
2542 static void
2543 compute_stop_pos (it)
2544 struct it *it;
2545 {
2546 register INTERVAL iv, next_iv;
2547 Lisp_Object object, limit, position;
2548
2549 /* If nowhere else, stop at the end. */
2550 it->stop_charpos = it->end_charpos;
2551
2552 if (STRINGP (it->string))
2553 {
2554 /* Strings are usually short, so don't limit the search for
2555 properties. */
2556 object = it->string;
2557 limit = Qnil;
2558 position = make_number (IT_STRING_CHARPOS (*it));
2559 }
2560 else
2561 {
2562 int charpos;
2563
2564 /* If next overlay change is in front of the current stop pos
2565 (which is IT->end_charpos), stop there. Note: value of
2566 next_overlay_change is point-max if no overlay change
2567 follows. */
2568 charpos = next_overlay_change (IT_CHARPOS (*it));
2569 if (charpos < it->stop_charpos)
2570 it->stop_charpos = charpos;
2571
2572 /* If showing the region, we have to stop at the region
2573 start or end because the face might change there. */
2574 if (it->region_beg_charpos > 0)
2575 {
2576 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2577 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2578 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2579 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2580 }
2581
2582 /* Set up variables for computing the stop position from text
2583 property changes. */
2584 XSETBUFFER (object, current_buffer);
2585 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2586 position = make_number (IT_CHARPOS (*it));
2587
2588 }
2589
2590 /* Get the interval containing IT's position. Value is a null
2591 interval if there isn't such an interval. */
2592 iv = validate_interval_range (object, &position, &position, 0);
2593 if (!NULL_INTERVAL_P (iv))
2594 {
2595 Lisp_Object values_here[LAST_PROP_IDX];
2596 struct props *p;
2597
2598 /* Get properties here. */
2599 for (p = it_props; p->handler; ++p)
2600 values_here[p->idx] = textget (iv->plist, *p->name);
2601
2602 /* Look for an interval following iv that has different
2603 properties. */
2604 for (next_iv = next_interval (iv);
2605 (!NULL_INTERVAL_P (next_iv)
2606 && (NILP (limit)
2607 || XFASTINT (limit) > next_iv->position));
2608 next_iv = next_interval (next_iv))
2609 {
2610 for (p = it_props; p->handler; ++p)
2611 {
2612 Lisp_Object new_value;
2613
2614 new_value = textget (next_iv->plist, *p->name);
2615 if (!EQ (values_here[p->idx], new_value))
2616 break;
2617 }
2618
2619 if (p->handler)
2620 break;
2621 }
2622
2623 if (!NULL_INTERVAL_P (next_iv))
2624 {
2625 if (INTEGERP (limit)
2626 && next_iv->position >= XFASTINT (limit))
2627 /* No text property change up to limit. */
2628 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2629 else
2630 /* Text properties change in next_iv. */
2631 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2632 }
2633 }
2634
2635 xassert (STRINGP (it->string)
2636 || (it->stop_charpos >= BEGV
2637 && it->stop_charpos >= IT_CHARPOS (*it)));
2638 }
2639
2640
2641 /* Return the position of the next overlay change after POS in
2642 current_buffer. Value is point-max if no overlay change
2643 follows. This is like `next-overlay-change' but doesn't use
2644 xmalloc. */
2645
2646 static int
2647 next_overlay_change (pos)
2648 int pos;
2649 {
2650 int noverlays;
2651 int endpos;
2652 Lisp_Object *overlays;
2653 int len;
2654 int i;
2655
2656 /* Get all overlays at the given position. */
2657 len = 10;
2658 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2659 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2660 if (noverlays > len)
2661 {
2662 len = noverlays;
2663 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2664 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2665 }
2666
2667 /* If any of these overlays ends before endpos,
2668 use its ending point instead. */
2669 for (i = 0; i < noverlays; ++i)
2670 {
2671 Lisp_Object oend;
2672 int oendpos;
2673
2674 oend = OVERLAY_END (overlays[i]);
2675 oendpos = OVERLAY_POSITION (oend);
2676 endpos = min (endpos, oendpos);
2677 }
2678
2679 return endpos;
2680 }
2681
2682
2683 \f
2684 /***********************************************************************
2685 Fontification
2686 ***********************************************************************/
2687
2688 /* Handle changes in the `fontified' property of the current buffer by
2689 calling hook functions from Qfontification_functions to fontify
2690 regions of text. */
2691
2692 static enum prop_handled
2693 handle_fontified_prop (it)
2694 struct it *it;
2695 {
2696 Lisp_Object prop, pos;
2697 enum prop_handled handled = HANDLED_NORMALLY;
2698
2699 /* Get the value of the `fontified' property at IT's current buffer
2700 position. (The `fontified' property doesn't have a special
2701 meaning in strings.) If the value is nil, call functions from
2702 Qfontification_functions. */
2703 if (!STRINGP (it->string)
2704 && it->s == NULL
2705 && !NILP (Vfontification_functions)
2706 && !NILP (Vrun_hooks)
2707 && (pos = make_number (IT_CHARPOS (*it)),
2708 prop = Fget_char_property (pos, Qfontified, Qnil),
2709 NILP (prop)))
2710 {
2711 int count = SPECPDL_INDEX ();
2712 Lisp_Object val;
2713
2714 val = Vfontification_functions;
2715 specbind (Qfontification_functions, Qnil);
2716
2717 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2718 safe_call1 (val, pos);
2719 else
2720 {
2721 Lisp_Object globals, fn;
2722 struct gcpro gcpro1, gcpro2;
2723
2724 globals = Qnil;
2725 GCPRO2 (val, globals);
2726
2727 for (; CONSP (val); val = XCDR (val))
2728 {
2729 fn = XCAR (val);
2730
2731 if (EQ (fn, Qt))
2732 {
2733 /* A value of t indicates this hook has a local
2734 binding; it means to run the global binding too.
2735 In a global value, t should not occur. If it
2736 does, we must ignore it to avoid an endless
2737 loop. */
2738 for (globals = Fdefault_value (Qfontification_functions);
2739 CONSP (globals);
2740 globals = XCDR (globals))
2741 {
2742 fn = XCAR (globals);
2743 if (!EQ (fn, Qt))
2744 safe_call1 (fn, pos);
2745 }
2746 }
2747 else
2748 safe_call1 (fn, pos);
2749 }
2750
2751 UNGCPRO;
2752 }
2753
2754 unbind_to (count, Qnil);
2755
2756 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2757 something. This avoids an endless loop if they failed to
2758 fontify the text for which reason ever. */
2759 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2760 handled = HANDLED_RECOMPUTE_PROPS;
2761 }
2762
2763 return handled;
2764 }
2765
2766
2767 \f
2768 /***********************************************************************
2769 Faces
2770 ***********************************************************************/
2771
2772 /* Set up iterator IT from face properties at its current position.
2773 Called from handle_stop. */
2774
2775 static enum prop_handled
2776 handle_face_prop (it)
2777 struct it *it;
2778 {
2779 int new_face_id, next_stop;
2780
2781 if (!STRINGP (it->string))
2782 {
2783 new_face_id
2784 = face_at_buffer_position (it->w,
2785 IT_CHARPOS (*it),
2786 it->region_beg_charpos,
2787 it->region_end_charpos,
2788 &next_stop,
2789 (IT_CHARPOS (*it)
2790 + TEXT_PROP_DISTANCE_LIMIT),
2791 0);
2792
2793 /* Is this a start of a run of characters with box face?
2794 Caveat: this can be called for a freshly initialized
2795 iterator; face_id is -1 in this case. We know that the new
2796 face will not change until limit, i.e. if the new face has a
2797 box, all characters up to limit will have one. But, as
2798 usual, we don't know whether limit is really the end. */
2799 if (new_face_id != it->face_id)
2800 {
2801 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2802
2803 /* If new face has a box but old face has not, this is
2804 the start of a run of characters with box, i.e. it has
2805 a shadow on the left side. The value of face_id of the
2806 iterator will be -1 if this is the initial call that gets
2807 the face. In this case, we have to look in front of IT's
2808 position and see whether there is a face != new_face_id. */
2809 it->start_of_box_run_p
2810 = (new_face->box != FACE_NO_BOX
2811 && (it->face_id >= 0
2812 || IT_CHARPOS (*it) == BEG
2813 || new_face_id != face_before_it_pos (it)));
2814 it->face_box_p = new_face->box != FACE_NO_BOX;
2815 }
2816 }
2817 else
2818 {
2819 int base_face_id, bufpos;
2820
2821 if (it->current.overlay_string_index >= 0)
2822 bufpos = IT_CHARPOS (*it);
2823 else
2824 bufpos = 0;
2825
2826 /* For strings from a buffer, i.e. overlay strings or strings
2827 from a `display' property, use the face at IT's current
2828 buffer position as the base face to merge with, so that
2829 overlay strings appear in the same face as surrounding
2830 text, unless they specify their own faces. */
2831 base_face_id = underlying_face_id (it);
2832
2833 new_face_id = face_at_string_position (it->w,
2834 it->string,
2835 IT_STRING_CHARPOS (*it),
2836 bufpos,
2837 it->region_beg_charpos,
2838 it->region_end_charpos,
2839 &next_stop,
2840 base_face_id, 0);
2841
2842 #if 0 /* This shouldn't be neccessary. Let's check it. */
2843 /* If IT is used to display a mode line we would really like to
2844 use the mode line face instead of the frame's default face. */
2845 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2846 && new_face_id == DEFAULT_FACE_ID)
2847 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2848 #endif
2849
2850 /* Is this a start of a run of characters with box? Caveat:
2851 this can be called for a freshly allocated iterator; face_id
2852 is -1 is this case. We know that the new face will not
2853 change until the next check pos, i.e. if the new face has a
2854 box, all characters up to that position will have a
2855 box. But, as usual, we don't know whether that position
2856 is really the end. */
2857 if (new_face_id != it->face_id)
2858 {
2859 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2860 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2861
2862 /* If new face has a box but old face hasn't, this is the
2863 start of a run of characters with box, i.e. it has a
2864 shadow on the left side. */
2865 it->start_of_box_run_p
2866 = new_face->box && (old_face == NULL || !old_face->box);
2867 it->face_box_p = new_face->box != FACE_NO_BOX;
2868 }
2869 }
2870
2871 it->face_id = new_face_id;
2872 return HANDLED_NORMALLY;
2873 }
2874
2875
2876 /* Return the ID of the face ``underlying'' IT's current position,
2877 which is in a string. If the iterator is associated with a
2878 buffer, return the face at IT's current buffer position.
2879 Otherwise, use the iterator's base_face_id. */
2880
2881 static int
2882 underlying_face_id (it)
2883 struct it *it;
2884 {
2885 int face_id = it->base_face_id, i;
2886
2887 xassert (STRINGP (it->string));
2888
2889 for (i = it->sp - 1; i >= 0; --i)
2890 if (NILP (it->stack[i].string))
2891 face_id = it->stack[i].face_id;
2892
2893 return face_id;
2894 }
2895
2896
2897 /* Compute the face one character before or after the current position
2898 of IT. BEFORE_P non-zero means get the face in front of IT's
2899 position. Value is the id of the face. */
2900
2901 static int
2902 face_before_or_after_it_pos (it, before_p)
2903 struct it *it;
2904 int before_p;
2905 {
2906 int face_id, limit;
2907 int next_check_charpos;
2908 struct text_pos pos;
2909
2910 xassert (it->s == NULL);
2911
2912 if (STRINGP (it->string))
2913 {
2914 int bufpos, base_face_id;
2915
2916 /* No face change past the end of the string (for the case
2917 we are padding with spaces). No face change before the
2918 string start. */
2919 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2920 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2921 return it->face_id;
2922
2923 /* Set pos to the position before or after IT's current position. */
2924 if (before_p)
2925 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2926 else
2927 /* For composition, we must check the character after the
2928 composition. */
2929 pos = (it->what == IT_COMPOSITION
2930 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2931 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2932
2933 if (it->current.overlay_string_index >= 0)
2934 bufpos = IT_CHARPOS (*it);
2935 else
2936 bufpos = 0;
2937
2938 base_face_id = underlying_face_id (it);
2939
2940 /* Get the face for ASCII, or unibyte. */
2941 face_id = face_at_string_position (it->w,
2942 it->string,
2943 CHARPOS (pos),
2944 bufpos,
2945 it->region_beg_charpos,
2946 it->region_end_charpos,
2947 &next_check_charpos,
2948 base_face_id, 0);
2949
2950 /* Correct the face for charsets different from ASCII. Do it
2951 for the multibyte case only. The face returned above is
2952 suitable for unibyte text if IT->string is unibyte. */
2953 if (STRING_MULTIBYTE (it->string))
2954 {
2955 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2956 int rest = SBYTES (it->string) - BYTEPOS (pos);
2957 int c, len;
2958 struct face *face = FACE_FROM_ID (it->f, face_id);
2959
2960 c = string_char_and_length (p, rest, &len);
2961 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
2962 }
2963 }
2964 else
2965 {
2966 if ((IT_CHARPOS (*it) >= ZV && !before_p)
2967 || (IT_CHARPOS (*it) <= BEGV && before_p))
2968 return it->face_id;
2969
2970 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
2971 pos = it->current.pos;
2972
2973 if (before_p)
2974 DEC_TEXT_POS (pos, it->multibyte_p);
2975 else
2976 {
2977 if (it->what == IT_COMPOSITION)
2978 /* For composition, we must check the position after the
2979 composition. */
2980 pos.charpos += it->cmp_len, pos.bytepos += it->len;
2981 else
2982 INC_TEXT_POS (pos, it->multibyte_p);
2983 }
2984
2985 /* Determine face for CHARSET_ASCII, or unibyte. */
2986 face_id = face_at_buffer_position (it->w,
2987 CHARPOS (pos),
2988 it->region_beg_charpos,
2989 it->region_end_charpos,
2990 &next_check_charpos,
2991 limit, 0);
2992
2993 /* Correct the face for charsets different from ASCII. Do it
2994 for the multibyte case only. The face returned above is
2995 suitable for unibyte text if current_buffer is unibyte. */
2996 if (it->multibyte_p)
2997 {
2998 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
2999 struct face *face = FACE_FROM_ID (it->f, face_id);
3000 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3001 }
3002 }
3003
3004 return face_id;
3005 }
3006
3007
3008 \f
3009 /***********************************************************************
3010 Invisible text
3011 ***********************************************************************/
3012
3013 /* Set up iterator IT from invisible properties at its current
3014 position. Called from handle_stop. */
3015
3016 static enum prop_handled
3017 handle_invisible_prop (it)
3018 struct it *it;
3019 {
3020 enum prop_handled handled = HANDLED_NORMALLY;
3021
3022 if (STRINGP (it->string))
3023 {
3024 extern Lisp_Object Qinvisible;
3025 Lisp_Object prop, end_charpos, limit, charpos;
3026
3027 /* Get the value of the invisible text property at the
3028 current position. Value will be nil if there is no such
3029 property. */
3030 charpos = make_number (IT_STRING_CHARPOS (*it));
3031 prop = Fget_text_property (charpos, Qinvisible, it->string);
3032
3033 if (!NILP (prop)
3034 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3035 {
3036 handled = HANDLED_RECOMPUTE_PROPS;
3037
3038 /* Get the position at which the next change of the
3039 invisible text property can be found in IT->string.
3040 Value will be nil if the property value is the same for
3041 all the rest of IT->string. */
3042 XSETINT (limit, SCHARS (it->string));
3043 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3044 it->string, limit);
3045
3046 /* Text at current position is invisible. The next
3047 change in the property is at position end_charpos.
3048 Move IT's current position to that position. */
3049 if (INTEGERP (end_charpos)
3050 && XFASTINT (end_charpos) < XFASTINT (limit))
3051 {
3052 struct text_pos old;
3053 old = it->current.string_pos;
3054 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3055 compute_string_pos (&it->current.string_pos, old, it->string);
3056 }
3057 else
3058 {
3059 /* The rest of the string is invisible. If this is an
3060 overlay string, proceed with the next overlay string
3061 or whatever comes and return a character from there. */
3062 if (it->current.overlay_string_index >= 0)
3063 {
3064 next_overlay_string (it);
3065 /* Don't check for overlay strings when we just
3066 finished processing them. */
3067 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3068 }
3069 else
3070 {
3071 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3072 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3073 }
3074 }
3075 }
3076 }
3077 else
3078 {
3079 int invis_p, newpos, next_stop, start_charpos;
3080 Lisp_Object pos, prop, overlay;
3081
3082 /* First of all, is there invisible text at this position? */
3083 start_charpos = IT_CHARPOS (*it);
3084 pos = make_number (IT_CHARPOS (*it));
3085 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3086 &overlay);
3087 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3088
3089 /* If we are on invisible text, skip over it. */
3090 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3091 {
3092 /* Record whether we have to display an ellipsis for the
3093 invisible text. */
3094 int display_ellipsis_p = invis_p == 2;
3095
3096 handled = HANDLED_RECOMPUTE_PROPS;
3097
3098 /* Loop skipping over invisible text. The loop is left at
3099 ZV or with IT on the first char being visible again. */
3100 do
3101 {
3102 /* Try to skip some invisible text. Return value is the
3103 position reached which can be equal to IT's position
3104 if there is nothing invisible here. This skips both
3105 over invisible text properties and overlays with
3106 invisible property. */
3107 newpos = skip_invisible (IT_CHARPOS (*it),
3108 &next_stop, ZV, it->window);
3109
3110 /* If we skipped nothing at all we weren't at invisible
3111 text in the first place. If everything to the end of
3112 the buffer was skipped, end the loop. */
3113 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3114 invis_p = 0;
3115 else
3116 {
3117 /* We skipped some characters but not necessarily
3118 all there are. Check if we ended up on visible
3119 text. Fget_char_property returns the property of
3120 the char before the given position, i.e. if we
3121 get invis_p = 0, this means that the char at
3122 newpos is visible. */
3123 pos = make_number (newpos);
3124 prop = Fget_char_property (pos, Qinvisible, it->window);
3125 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3126 }
3127
3128 /* If we ended up on invisible text, proceed to
3129 skip starting with next_stop. */
3130 if (invis_p)
3131 IT_CHARPOS (*it) = next_stop;
3132 }
3133 while (invis_p);
3134
3135 /* The position newpos is now either ZV or on visible text. */
3136 IT_CHARPOS (*it) = newpos;
3137 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3138
3139 /* If there are before-strings at the start of invisible
3140 text, and the text is invisible because of a text
3141 property, arrange to show before-strings because 20.x did
3142 it that way. (If the text is invisible because of an
3143 overlay property instead of a text property, this is
3144 already handled in the overlay code.) */
3145 if (NILP (overlay)
3146 && get_overlay_strings (it, start_charpos))
3147 {
3148 handled = HANDLED_RECOMPUTE_PROPS;
3149 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3150 }
3151 else if (display_ellipsis_p)
3152 setup_for_ellipsis (it);
3153 }
3154 }
3155
3156 return handled;
3157 }
3158
3159
3160 /* Make iterator IT return `...' next. */
3161
3162 static void
3163 setup_for_ellipsis (it)
3164 struct it *it;
3165 {
3166 if (it->dp
3167 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3168 {
3169 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3170 it->dpvec = v->contents;
3171 it->dpend = v->contents + v->size;
3172 }
3173 else
3174 {
3175 /* Default `...'. */
3176 it->dpvec = default_invis_vector;
3177 it->dpend = default_invis_vector + 3;
3178 }
3179
3180 /* The ellipsis display does not replace the display of the
3181 character at the new position. Indicate this by setting
3182 IT->dpvec_char_len to zero. */
3183 it->dpvec_char_len = 0;
3184
3185 it->current.dpvec_index = 0;
3186 it->method = next_element_from_display_vector;
3187 }
3188
3189
3190 \f
3191 /***********************************************************************
3192 'display' property
3193 ***********************************************************************/
3194
3195 /* Set up iterator IT from `display' property at its current position.
3196 Called from handle_stop. */
3197
3198 static enum prop_handled
3199 handle_display_prop (it)
3200 struct it *it;
3201 {
3202 Lisp_Object prop, object;
3203 struct text_pos *position;
3204 int display_replaced_p = 0;
3205
3206 if (STRINGP (it->string))
3207 {
3208 object = it->string;
3209 position = &it->current.string_pos;
3210 }
3211 else
3212 {
3213 object = it->w->buffer;
3214 position = &it->current.pos;
3215 }
3216
3217 /* Reset those iterator values set from display property values. */
3218 it->font_height = Qnil;
3219 it->space_width = Qnil;
3220 it->voffset = 0;
3221
3222 /* We don't support recursive `display' properties, i.e. string
3223 values that have a string `display' property, that have a string
3224 `display' property etc. */
3225 if (!it->string_from_display_prop_p)
3226 it->area = TEXT_AREA;
3227
3228 prop = Fget_char_property (make_number (position->charpos),
3229 Qdisplay, object);
3230 if (NILP (prop))
3231 return HANDLED_NORMALLY;
3232
3233 if (CONSP (prop)
3234 /* Simple properties. */
3235 && !EQ (XCAR (prop), Qimage)
3236 && !EQ (XCAR (prop), Qspace)
3237 && !EQ (XCAR (prop), Qwhen)
3238 && !EQ (XCAR (prop), Qspace_width)
3239 && !EQ (XCAR (prop), Qheight)
3240 && !EQ (XCAR (prop), Qraise)
3241 /* Marginal area specifications. */
3242 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3243 && !NILP (XCAR (prop)))
3244 {
3245 for (; CONSP (prop); prop = XCDR (prop))
3246 {
3247 if (handle_single_display_prop (it, XCAR (prop), object,
3248 position, display_replaced_p))
3249 display_replaced_p = 1;
3250 }
3251 }
3252 else if (VECTORP (prop))
3253 {
3254 int i;
3255 for (i = 0; i < ASIZE (prop); ++i)
3256 if (handle_single_display_prop (it, AREF (prop, i), object,
3257 position, display_replaced_p))
3258 display_replaced_p = 1;
3259 }
3260 else
3261 {
3262 if (handle_single_display_prop (it, prop, object, position, 0))
3263 display_replaced_p = 1;
3264 }
3265
3266 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3267 }
3268
3269
3270 /* Value is the position of the end of the `display' property starting
3271 at START_POS in OBJECT. */
3272
3273 static struct text_pos
3274 display_prop_end (it, object, start_pos)
3275 struct it *it;
3276 Lisp_Object object;
3277 struct text_pos start_pos;
3278 {
3279 Lisp_Object end;
3280 struct text_pos end_pos;
3281
3282 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3283 Qdisplay, object, Qnil);
3284 CHARPOS (end_pos) = XFASTINT (end);
3285 if (STRINGP (object))
3286 compute_string_pos (&end_pos, start_pos, it->string);
3287 else
3288 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3289
3290 return end_pos;
3291 }
3292
3293
3294 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3295 is the object in which the `display' property was found. *POSITION
3296 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3297 means that we previously saw a display sub-property which already
3298 replaced text display with something else, for example an image;
3299 ignore such properties after the first one has been processed.
3300
3301 If PROP is a `space' or `image' sub-property, set *POSITION to the
3302 end position of the `display' property.
3303
3304 Value is non-zero if something was found which replaces the display
3305 of buffer or string text. */
3306
3307 static int
3308 handle_single_display_prop (it, prop, object, position,
3309 display_replaced_before_p)
3310 struct it *it;
3311 Lisp_Object prop;
3312 Lisp_Object object;
3313 struct text_pos *position;
3314 int display_replaced_before_p;
3315 {
3316 Lisp_Object value;
3317 int replaces_text_display_p = 0;
3318 Lisp_Object form;
3319
3320 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3321 evaluated. If the result is nil, VALUE is ignored. */
3322 form = Qt;
3323 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3324 {
3325 prop = XCDR (prop);
3326 if (!CONSP (prop))
3327 return 0;
3328 form = XCAR (prop);
3329 prop = XCDR (prop);
3330 }
3331
3332 if (!NILP (form) && !EQ (form, Qt))
3333 {
3334 int count = SPECPDL_INDEX ();
3335 struct gcpro gcpro1;
3336
3337 /* Bind `object' to the object having the `display' property, a
3338 buffer or string. Bind `position' to the position in the
3339 object where the property was found, and `buffer-position'
3340 to the current position in the buffer. */
3341 specbind (Qobject, object);
3342 specbind (Qposition, make_number (CHARPOS (*position)));
3343 specbind (Qbuffer_position,
3344 make_number (STRINGP (object)
3345 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3346 GCPRO1 (form);
3347 form = safe_eval (form);
3348 UNGCPRO;
3349 unbind_to (count, Qnil);
3350 }
3351
3352 if (NILP (form))
3353 return 0;
3354
3355 if (CONSP (prop)
3356 && EQ (XCAR (prop), Qheight)
3357 && CONSP (XCDR (prop)))
3358 {
3359 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3360 return 0;
3361
3362 /* `(height HEIGHT)'. */
3363 it->font_height = XCAR (XCDR (prop));
3364 if (!NILP (it->font_height))
3365 {
3366 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3367 int new_height = -1;
3368
3369 if (CONSP (it->font_height)
3370 && (EQ (XCAR (it->font_height), Qplus)
3371 || EQ (XCAR (it->font_height), Qminus))
3372 && CONSP (XCDR (it->font_height))
3373 && INTEGERP (XCAR (XCDR (it->font_height))))
3374 {
3375 /* `(+ N)' or `(- N)' where N is an integer. */
3376 int steps = XINT (XCAR (XCDR (it->font_height)));
3377 if (EQ (XCAR (it->font_height), Qplus))
3378 steps = - steps;
3379 it->face_id = smaller_face (it->f, it->face_id, steps);
3380 }
3381 else if (FUNCTIONP (it->font_height))
3382 {
3383 /* Call function with current height as argument.
3384 Value is the new height. */
3385 Lisp_Object height;
3386 height = safe_call1 (it->font_height,
3387 face->lface[LFACE_HEIGHT_INDEX]);
3388 if (NUMBERP (height))
3389 new_height = XFLOATINT (height);
3390 }
3391 else if (NUMBERP (it->font_height))
3392 {
3393 /* Value is a multiple of the canonical char height. */
3394 struct face *face;
3395
3396 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3397 new_height = (XFLOATINT (it->font_height)
3398 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3399 }
3400 else
3401 {
3402 /* Evaluate IT->font_height with `height' bound to the
3403 current specified height to get the new height. */
3404 Lisp_Object value;
3405 int count = SPECPDL_INDEX ();
3406
3407 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3408 value = safe_eval (it->font_height);
3409 unbind_to (count, Qnil);
3410
3411 if (NUMBERP (value))
3412 new_height = XFLOATINT (value);
3413 }
3414
3415 if (new_height > 0)
3416 it->face_id = face_with_height (it->f, it->face_id, new_height);
3417 }
3418 }
3419 else if (CONSP (prop)
3420 && EQ (XCAR (prop), Qspace_width)
3421 && CONSP (XCDR (prop)))
3422 {
3423 /* `(space_width WIDTH)'. */
3424 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3425 return 0;
3426
3427 value = XCAR (XCDR (prop));
3428 if (NUMBERP (value) && XFLOATINT (value) > 0)
3429 it->space_width = value;
3430 }
3431 else if (CONSP (prop)
3432 && EQ (XCAR (prop), Qraise)
3433 && CONSP (XCDR (prop)))
3434 {
3435 /* `(raise FACTOR)'. */
3436 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3437 return 0;
3438
3439 #ifdef HAVE_WINDOW_SYSTEM
3440 value = XCAR (XCDR (prop));
3441 if (NUMBERP (value))
3442 {
3443 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3444 it->voffset = - (XFLOATINT (value)
3445 * (FONT_HEIGHT (face->font)));
3446 }
3447 #endif /* HAVE_WINDOW_SYSTEM */
3448 }
3449 else if (!it->string_from_display_prop_p)
3450 {
3451 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3452 VALUE) or `((margin nil) VALUE)' or VALUE. */
3453 Lisp_Object location, value;
3454 struct text_pos start_pos;
3455 int valid_p;
3456
3457 /* Characters having this form of property are not displayed, so
3458 we have to find the end of the property. */
3459 start_pos = *position;
3460 *position = display_prop_end (it, object, start_pos);
3461 value = Qnil;
3462
3463 /* Let's stop at the new position and assume that all
3464 text properties change there. */
3465 it->stop_charpos = position->charpos;
3466
3467 location = Qunbound;
3468 if (CONSP (prop) && CONSP (XCAR (prop)))
3469 {
3470 Lisp_Object tem;
3471
3472 value = XCDR (prop);
3473 if (CONSP (value))
3474 value = XCAR (value);
3475
3476 tem = XCAR (prop);
3477 if (EQ (XCAR (tem), Qmargin)
3478 && (tem = XCDR (tem),
3479 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3480 (NILP (tem)
3481 || EQ (tem, Qleft_margin)
3482 || EQ (tem, Qright_margin))))
3483 location = tem;
3484 }
3485
3486 if (EQ (location, Qunbound))
3487 {
3488 location = Qnil;
3489 value = prop;
3490 }
3491
3492 #ifdef HAVE_WINDOW_SYSTEM
3493 if (FRAME_TERMCAP_P (it->f))
3494 valid_p = STRINGP (value);
3495 else
3496 valid_p = (STRINGP (value)
3497 || (CONSP (value) && EQ (XCAR (value), Qspace))
3498 || valid_image_p (value));
3499 #else /* not HAVE_WINDOW_SYSTEM */
3500 valid_p = STRINGP (value);
3501 #endif /* not HAVE_WINDOW_SYSTEM */
3502
3503 if ((EQ (location, Qleft_margin)
3504 || EQ (location, Qright_margin)
3505 || NILP (location))
3506 && valid_p
3507 && !display_replaced_before_p)
3508 {
3509 replaces_text_display_p = 1;
3510
3511 /* Save current settings of IT so that we can restore them
3512 when we are finished with the glyph property value. */
3513 push_it (it);
3514
3515 if (NILP (location))
3516 it->area = TEXT_AREA;
3517 else if (EQ (location, Qleft_margin))
3518 it->area = LEFT_MARGIN_AREA;
3519 else
3520 it->area = RIGHT_MARGIN_AREA;
3521
3522 if (STRINGP (value))
3523 {
3524 it->string = value;
3525 it->multibyte_p = STRING_MULTIBYTE (it->string);
3526 it->current.overlay_string_index = -1;
3527 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3528 it->end_charpos = it->string_nchars = SCHARS (it->string);
3529 it->method = next_element_from_string;
3530 it->stop_charpos = 0;
3531 it->string_from_display_prop_p = 1;
3532 /* Say that we haven't consumed the characters with
3533 `display' property yet. The call to pop_it in
3534 set_iterator_to_next will clean this up. */
3535 *position = start_pos;
3536 }
3537 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3538 {
3539 it->method = next_element_from_stretch;
3540 it->object = value;
3541 it->current.pos = it->position = start_pos;
3542 }
3543 #ifdef HAVE_WINDOW_SYSTEM
3544 else
3545 {
3546 it->what = IT_IMAGE;
3547 it->image_id = lookup_image (it->f, value);
3548 it->position = start_pos;
3549 it->object = NILP (object) ? it->w->buffer : object;
3550 it->method = next_element_from_image;
3551
3552 /* Say that we haven't consumed the characters with
3553 `display' property yet. The call to pop_it in
3554 set_iterator_to_next will clean this up. */
3555 *position = start_pos;
3556 }
3557 #endif /* HAVE_WINDOW_SYSTEM */
3558 }
3559 else
3560 /* Invalid property or property not supported. Restore
3561 the position to what it was before. */
3562 *position = start_pos;
3563 }
3564
3565 return replaces_text_display_p;
3566 }
3567
3568
3569 /* Check if PROP is a display sub-property value whose text should be
3570 treated as intangible. */
3571
3572 static int
3573 single_display_prop_intangible_p (prop)
3574 Lisp_Object prop;
3575 {
3576 /* Skip over `when FORM'. */
3577 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3578 {
3579 prop = XCDR (prop);
3580 if (!CONSP (prop))
3581 return 0;
3582 prop = XCDR (prop);
3583 }
3584
3585 if (STRINGP (prop))
3586 return 1;
3587
3588 if (!CONSP (prop))
3589 return 0;
3590
3591 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3592 we don't need to treat text as intangible. */
3593 if (EQ (XCAR (prop), Qmargin))
3594 {
3595 prop = XCDR (prop);
3596 if (!CONSP (prop))
3597 return 0;
3598
3599 prop = XCDR (prop);
3600 if (!CONSP (prop)
3601 || EQ (XCAR (prop), Qleft_margin)
3602 || EQ (XCAR (prop), Qright_margin))
3603 return 0;
3604 }
3605
3606 return (CONSP (prop)
3607 && (EQ (XCAR (prop), Qimage)
3608 || EQ (XCAR (prop), Qspace)));
3609 }
3610
3611
3612 /* Check if PROP is a display property value whose text should be
3613 treated as intangible. */
3614
3615 int
3616 display_prop_intangible_p (prop)
3617 Lisp_Object prop;
3618 {
3619 if (CONSP (prop)
3620 && CONSP (XCAR (prop))
3621 && !EQ (Qmargin, XCAR (XCAR (prop))))
3622 {
3623 /* A list of sub-properties. */
3624 while (CONSP (prop))
3625 {
3626 if (single_display_prop_intangible_p (XCAR (prop)))
3627 return 1;
3628 prop = XCDR (prop);
3629 }
3630 }
3631 else if (VECTORP (prop))
3632 {
3633 /* A vector of sub-properties. */
3634 int i;
3635 for (i = 0; i < ASIZE (prop); ++i)
3636 if (single_display_prop_intangible_p (AREF (prop, i)))
3637 return 1;
3638 }
3639 else
3640 return single_display_prop_intangible_p (prop);
3641
3642 return 0;
3643 }
3644
3645
3646 /* Return 1 if PROP is a display sub-property value containing STRING. */
3647
3648 static int
3649 single_display_prop_string_p (prop, string)
3650 Lisp_Object prop, string;
3651 {
3652 if (EQ (string, prop))
3653 return 1;
3654
3655 /* Skip over `when FORM'. */
3656 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3657 {
3658 prop = XCDR (prop);
3659 if (!CONSP (prop))
3660 return 0;
3661 prop = XCDR (prop);
3662 }
3663
3664 if (CONSP (prop))
3665 /* Skip over `margin LOCATION'. */
3666 if (EQ (XCAR (prop), Qmargin))
3667 {
3668 prop = XCDR (prop);
3669 if (!CONSP (prop))
3670 return 0;
3671
3672 prop = XCDR (prop);
3673 if (!CONSP (prop))
3674 return 0;
3675 }
3676
3677 return CONSP (prop) && EQ (XCAR (prop), string);
3678 }
3679
3680
3681 /* Return 1 if STRING appears in the `display' property PROP. */
3682
3683 static int
3684 display_prop_string_p (prop, string)
3685 Lisp_Object prop, string;
3686 {
3687 if (CONSP (prop)
3688 && CONSP (XCAR (prop))
3689 && !EQ (Qmargin, XCAR (XCAR (prop))))
3690 {
3691 /* A list of sub-properties. */
3692 while (CONSP (prop))
3693 {
3694 if (single_display_prop_string_p (XCAR (prop), string))
3695 return 1;
3696 prop = XCDR (prop);
3697 }
3698 }
3699 else if (VECTORP (prop))
3700 {
3701 /* A vector of sub-properties. */
3702 int i;
3703 for (i = 0; i < ASIZE (prop); ++i)
3704 if (single_display_prop_string_p (AREF (prop, i), string))
3705 return 1;
3706 }
3707 else
3708 return single_display_prop_string_p (prop, string);
3709
3710 return 0;
3711 }
3712
3713
3714 /* Determine from which buffer position in W's buffer STRING comes
3715 from. AROUND_CHARPOS is an approximate position where it could
3716 be from. Value is the buffer position or 0 if it couldn't be
3717 determined.
3718
3719 W's buffer must be current.
3720
3721 This function is necessary because we don't record buffer positions
3722 in glyphs generated from strings (to keep struct glyph small).
3723 This function may only use code that doesn't eval because it is
3724 called asynchronously from note_mouse_highlight. */
3725
3726 int
3727 string_buffer_position (w, string, around_charpos)
3728 struct window *w;
3729 Lisp_Object string;
3730 int around_charpos;
3731 {
3732 Lisp_Object limit, prop, pos;
3733 const int MAX_DISTANCE = 1000;
3734 int found = 0;
3735
3736 pos = make_number (around_charpos);
3737 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3738 while (!found && !EQ (pos, limit))
3739 {
3740 prop = Fget_char_property (pos, Qdisplay, Qnil);
3741 if (!NILP (prop) && display_prop_string_p (prop, string))
3742 found = 1;
3743 else
3744 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3745 }
3746
3747 if (!found)
3748 {
3749 pos = make_number (around_charpos);
3750 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3751 while (!found && !EQ (pos, limit))
3752 {
3753 prop = Fget_char_property (pos, Qdisplay, Qnil);
3754 if (!NILP (prop) && display_prop_string_p (prop, string))
3755 found = 1;
3756 else
3757 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3758 limit);
3759 }
3760 }
3761
3762 return found ? XINT (pos) : 0;
3763 }
3764
3765
3766 \f
3767 /***********************************************************************
3768 `composition' property
3769 ***********************************************************************/
3770
3771 static enum prop_handled
3772 handle_auto_composed_prop (it)
3773 struct it *it;
3774 {
3775 enum prop_handled handled = HANDLED_NORMALLY;
3776
3777 if (FUNCTIONP (Vauto_composition_function))
3778 {
3779 Lisp_Object val;
3780 EMACS_INT pos, this_pos;
3781
3782 if (STRINGP (it->string))
3783 pos = IT_STRING_CHARPOS (*it);
3784 else
3785 pos = IT_CHARPOS (*it);
3786 this_pos = pos;
3787
3788 val =Fget_char_property (make_number (pos), Qauto_composed, it->string);
3789 if (! NILP (val))
3790 {
3791 Lisp_Object limit = Qnil, next;
3792
3793 /* As Fnext_single_char_property_change is very slow, we
3794 limit the search to the current line. */
3795 if (STRINGP (it->string))
3796 limit = make_number (SCHARS (it->string));
3797 else
3798 limit = make_number (find_next_newline_no_quit (pos, 1));
3799
3800 next = (Fnext_single_property_change
3801 (make_number (pos), Qauto_composed, it->string, limit));
3802 if (XINT (next) < XINT (limit))
3803 {
3804 /* The current point is auto-composed, but there exist
3805 characters not yet composed beyond the auto-composed
3806 region. There's a possiblity that the last
3807 characters in the region may be newly composed. */
3808 int charpos = XINT (next) - 1, bytepos, c;
3809
3810 if (STRINGP (it->string))
3811 {
3812 bytepos = string_char_to_byte (it->string, charpos);
3813 c = SDATA (it->string)[bytepos];
3814 }
3815 else
3816 {
3817 bytepos = CHAR_TO_BYTE (charpos);
3818 c = FETCH_BYTE (bytepos);
3819 }
3820 if (c != '\n')
3821 /* If the last character is not newline, it may be
3822 composed with the following characters. */
3823 val = Qnil, pos = charpos + 1;
3824 }
3825 }
3826 if (NILP (val))
3827 {
3828 int count = SPECPDL_INDEX ();
3829 Lisp_Object args[3];
3830
3831 args[0] = Vauto_composition_function;
3832 specbind (Qauto_composition_function, Qnil);
3833 args[1] = make_number (pos);
3834 args[2] = it->string;
3835 safe_call (3, args);
3836 unbind_to (count, Qnil);
3837
3838 if (this_pos == pos)
3839 {
3840 val = Fget_char_property (args[1], Qauto_composed, it->string);
3841 /* Return HANDLED_RECOMPUTE_PROPS only if function composed
3842 something. This avoids an endless loop if they failed to
3843 fontify the text for which reason ever. */
3844 if (! NILP (val))
3845 handled = HANDLED_RECOMPUTE_PROPS;
3846 }
3847 else
3848 handled = HANDLED_RECOMPUTE_PROPS;
3849 }
3850 }
3851
3852 return handled;
3853 }
3854
3855 /* Set up iterator IT from `composition' property at its current
3856 position. Called from handle_stop. */
3857
3858 static enum prop_handled
3859 handle_composition_prop (it)
3860 struct it *it;
3861 {
3862 Lisp_Object prop, string;
3863 EMACS_INT pos, pos_byte, start, end;
3864 enum prop_handled handled = HANDLED_NORMALLY;
3865
3866 if (STRINGP (it->string))
3867 {
3868 pos = IT_STRING_CHARPOS (*it);
3869 pos_byte = IT_STRING_BYTEPOS (*it);
3870 string = it->string;
3871 }
3872 else
3873 {
3874 pos = IT_CHARPOS (*it);
3875 pos_byte = IT_BYTEPOS (*it);
3876 string = Qnil;
3877 }
3878
3879 /* If there's a valid composition and point is not inside of the
3880 composition (in the case that the composition is from the current
3881 buffer), draw a glyph composed from the composition components. */
3882 if (find_composition (pos, -1, &start, &end, &prop, string)
3883 && COMPOSITION_VALID_P (start, end, prop)
3884 && (STRINGP (it->string) || (PT <= start || PT >= end)))
3885 {
3886 int id;
3887
3888 if (start != pos)
3889 {
3890 if (STRINGP (it->string))
3891 pos_byte = string_char_to_byte (it->string, start);
3892 else
3893 pos_byte = CHAR_TO_BYTE (start);
3894 }
3895 id = get_composition_id (start, pos_byte, end - start, prop, string);
3896
3897 if (id >= 0)
3898 {
3899 it->method = next_element_from_composition;
3900 it->cmp_id = id;
3901 it->cmp_len = COMPOSITION_LENGTH (prop);
3902 /* For a terminal, draw only the first character of the
3903 components. */
3904 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3905 it->len = (STRINGP (it->string)
3906 ? string_char_to_byte (it->string, end)
3907 : CHAR_TO_BYTE (end)) - pos_byte;
3908 it->stop_charpos = end;
3909 handled = HANDLED_RETURN;
3910 }
3911 }
3912
3913 return handled;
3914 }
3915
3916
3917 \f
3918 /***********************************************************************
3919 Overlay strings
3920 ***********************************************************************/
3921
3922 /* The following structure is used to record overlay strings for
3923 later sorting in load_overlay_strings. */
3924
3925 struct overlay_entry
3926 {
3927 Lisp_Object overlay;
3928 Lisp_Object string;
3929 int priority;
3930 int after_string_p;
3931 };
3932
3933
3934 /* Set up iterator IT from overlay strings at its current position.
3935 Called from handle_stop. */
3936
3937 static enum prop_handled
3938 handle_overlay_change (it)
3939 struct it *it;
3940 {
3941 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3942 return HANDLED_RECOMPUTE_PROPS;
3943 else
3944 return HANDLED_NORMALLY;
3945 }
3946
3947
3948 /* Set up the next overlay string for delivery by IT, if there is an
3949 overlay string to deliver. Called by set_iterator_to_next when the
3950 end of the current overlay string is reached. If there are more
3951 overlay strings to display, IT->string and
3952 IT->current.overlay_string_index are set appropriately here.
3953 Otherwise IT->string is set to nil. */
3954
3955 static void
3956 next_overlay_string (it)
3957 struct it *it;
3958 {
3959 ++it->current.overlay_string_index;
3960 if (it->current.overlay_string_index == it->n_overlay_strings)
3961 {
3962 /* No more overlay strings. Restore IT's settings to what
3963 they were before overlay strings were processed, and
3964 continue to deliver from current_buffer. */
3965 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3966
3967 pop_it (it);
3968 xassert (it->stop_charpos >= BEGV
3969 && it->stop_charpos <= it->end_charpos);
3970 it->string = Qnil;
3971 it->current.overlay_string_index = -1;
3972 SET_TEXT_POS (it->current.string_pos, -1, -1);
3973 it->n_overlay_strings = 0;
3974 it->method = next_element_from_buffer;
3975
3976 /* If we're at the end of the buffer, record that we have
3977 processed the overlay strings there already, so that
3978 next_element_from_buffer doesn't try it again. */
3979 if (IT_CHARPOS (*it) >= it->end_charpos)
3980 it->overlay_strings_at_end_processed_p = 1;
3981
3982 /* If we have to display `...' for invisible text, set
3983 the iterator up for that. */
3984 if (display_ellipsis_p)
3985 setup_for_ellipsis (it);
3986 }
3987 else
3988 {
3989 /* There are more overlay strings to process. If
3990 IT->current.overlay_string_index has advanced to a position
3991 where we must load IT->overlay_strings with more strings, do
3992 it. */
3993 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3994
3995 if (it->current.overlay_string_index && i == 0)
3996 load_overlay_strings (it, 0);
3997
3998 /* Initialize IT to deliver display elements from the overlay
3999 string. */
4000 it->string = it->overlay_strings[i];
4001 it->multibyte_p = STRING_MULTIBYTE (it->string);
4002 SET_TEXT_POS (it->current.string_pos, 0, 0);
4003 it->method = next_element_from_string;
4004 it->stop_charpos = 0;
4005 }
4006
4007 CHECK_IT (it);
4008 }
4009
4010
4011 /* Compare two overlay_entry structures E1 and E2. Used as a
4012 comparison function for qsort in load_overlay_strings. Overlay
4013 strings for the same position are sorted so that
4014
4015 1. All after-strings come in front of before-strings, except
4016 when they come from the same overlay.
4017
4018 2. Within after-strings, strings are sorted so that overlay strings
4019 from overlays with higher priorities come first.
4020
4021 2. Within before-strings, strings are sorted so that overlay
4022 strings from overlays with higher priorities come last.
4023
4024 Value is analogous to strcmp. */
4025
4026
4027 static int
4028 compare_overlay_entries (e1, e2)
4029 void *e1, *e2;
4030 {
4031 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4032 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4033 int result;
4034
4035 if (entry1->after_string_p != entry2->after_string_p)
4036 {
4037 /* Let after-strings appear in front of before-strings if
4038 they come from different overlays. */
4039 if (EQ (entry1->overlay, entry2->overlay))
4040 result = entry1->after_string_p ? 1 : -1;
4041 else
4042 result = entry1->after_string_p ? -1 : 1;
4043 }
4044 else if (entry1->after_string_p)
4045 /* After-strings sorted in order of decreasing priority. */
4046 result = entry2->priority - entry1->priority;
4047 else
4048 /* Before-strings sorted in order of increasing priority. */
4049 result = entry1->priority - entry2->priority;
4050
4051 return result;
4052 }
4053
4054
4055 /* Load the vector IT->overlay_strings with overlay strings from IT's
4056 current buffer position, or from CHARPOS if that is > 0. Set
4057 IT->n_overlays to the total number of overlay strings found.
4058
4059 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4060 a time. On entry into load_overlay_strings,
4061 IT->current.overlay_string_index gives the number of overlay
4062 strings that have already been loaded by previous calls to this
4063 function.
4064
4065 IT->add_overlay_start contains an additional overlay start
4066 position to consider for taking overlay strings from, if non-zero.
4067 This position comes into play when the overlay has an `invisible'
4068 property, and both before and after-strings. When we've skipped to
4069 the end of the overlay, because of its `invisible' property, we
4070 nevertheless want its before-string to appear.
4071 IT->add_overlay_start will contain the overlay start position
4072 in this case.
4073
4074 Overlay strings are sorted so that after-string strings come in
4075 front of before-string strings. Within before and after-strings,
4076 strings are sorted by overlay priority. See also function
4077 compare_overlay_entries. */
4078
4079 static void
4080 load_overlay_strings (it, charpos)
4081 struct it *it;
4082 int charpos;
4083 {
4084 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4085 Lisp_Object overlay, window, str, invisible;
4086 struct Lisp_Overlay *ov;
4087 int start, end;
4088 int size = 20;
4089 int n = 0, i, j, invis_p;
4090 struct overlay_entry *entries
4091 = (struct overlay_entry *) alloca (size * sizeof *entries);
4092
4093 if (charpos <= 0)
4094 charpos = IT_CHARPOS (*it);
4095
4096 /* Append the overlay string STRING of overlay OVERLAY to vector
4097 `entries' which has size `size' and currently contains `n'
4098 elements. AFTER_P non-zero means STRING is an after-string of
4099 OVERLAY. */
4100 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4101 do \
4102 { \
4103 Lisp_Object priority; \
4104 \
4105 if (n == size) \
4106 { \
4107 int new_size = 2 * size; \
4108 struct overlay_entry *old = entries; \
4109 entries = \
4110 (struct overlay_entry *) alloca (new_size \
4111 * sizeof *entries); \
4112 bcopy (old, entries, size * sizeof *entries); \
4113 size = new_size; \
4114 } \
4115 \
4116 entries[n].string = (STRING); \
4117 entries[n].overlay = (OVERLAY); \
4118 priority = Foverlay_get ((OVERLAY), Qpriority); \
4119 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4120 entries[n].after_string_p = (AFTER_P); \
4121 ++n; \
4122 } \
4123 while (0)
4124
4125 /* Process overlay before the overlay center. */
4126 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4127 {
4128 XSETMISC (overlay, ov);
4129 xassert (OVERLAYP (overlay));
4130 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4131 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4132
4133 if (end < charpos)
4134 break;
4135
4136 /* Skip this overlay if it doesn't start or end at IT's current
4137 position. */
4138 if (end != charpos && start != charpos)
4139 continue;
4140
4141 /* Skip this overlay if it doesn't apply to IT->w. */
4142 window = Foverlay_get (overlay, Qwindow);
4143 if (WINDOWP (window) && XWINDOW (window) != it->w)
4144 continue;
4145
4146 /* If the text ``under'' the overlay is invisible, both before-
4147 and after-strings from this overlay are visible; start and
4148 end position are indistinguishable. */
4149 invisible = Foverlay_get (overlay, Qinvisible);
4150 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4151
4152 /* If overlay has a non-empty before-string, record it. */
4153 if ((start == charpos || (end == charpos && invis_p))
4154 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4155 && SCHARS (str))
4156 RECORD_OVERLAY_STRING (overlay, str, 0);
4157
4158 /* If overlay has a non-empty after-string, record it. */
4159 if ((end == charpos || (start == charpos && invis_p))
4160 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4161 && SCHARS (str))
4162 RECORD_OVERLAY_STRING (overlay, str, 1);
4163 }
4164
4165 /* Process overlays after the overlay center. */
4166 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4167 {
4168 XSETMISC (overlay, ov);
4169 xassert (OVERLAYP (overlay));
4170 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4171 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4172
4173 if (start > charpos)
4174 break;
4175
4176 /* Skip this overlay if it doesn't start or end at IT's current
4177 position. */
4178 if (end != charpos && start != charpos)
4179 continue;
4180
4181 /* Skip this overlay if it doesn't apply to IT->w. */
4182 window = Foverlay_get (overlay, Qwindow);
4183 if (WINDOWP (window) && XWINDOW (window) != it->w)
4184 continue;
4185
4186 /* If the text ``under'' the overlay is invisible, it has a zero
4187 dimension, and both before- and after-strings apply. */
4188 invisible = Foverlay_get (overlay, Qinvisible);
4189 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4190
4191 /* If overlay has a non-empty before-string, record it. */
4192 if ((start == charpos || (end == charpos && invis_p))
4193 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4194 && SCHARS (str))
4195 RECORD_OVERLAY_STRING (overlay, str, 0);
4196
4197 /* If overlay has a non-empty after-string, record it. */
4198 if ((end == charpos || (start == charpos && invis_p))
4199 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4200 && SCHARS (str))
4201 RECORD_OVERLAY_STRING (overlay, str, 1);
4202 }
4203
4204 #undef RECORD_OVERLAY_STRING
4205
4206 /* Sort entries. */
4207 if (n > 1)
4208 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4209
4210 /* Record the total number of strings to process. */
4211 it->n_overlay_strings = n;
4212
4213 /* IT->current.overlay_string_index is the number of overlay strings
4214 that have already been consumed by IT. Copy some of the
4215 remaining overlay strings to IT->overlay_strings. */
4216 i = 0;
4217 j = it->current.overlay_string_index;
4218 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4219 it->overlay_strings[i++] = entries[j++].string;
4220
4221 CHECK_IT (it);
4222 }
4223
4224
4225 /* Get the first chunk of overlay strings at IT's current buffer
4226 position, or at CHARPOS if that is > 0. Value is non-zero if at
4227 least one overlay string was found. */
4228
4229 static int
4230 get_overlay_strings (it, charpos)
4231 struct it *it;
4232 int charpos;
4233 {
4234 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4235 process. This fills IT->overlay_strings with strings, and sets
4236 IT->n_overlay_strings to the total number of strings to process.
4237 IT->pos.overlay_string_index has to be set temporarily to zero
4238 because load_overlay_strings needs this; it must be set to -1
4239 when no overlay strings are found because a zero value would
4240 indicate a position in the first overlay string. */
4241 it->current.overlay_string_index = 0;
4242 load_overlay_strings (it, charpos);
4243
4244 /* If we found overlay strings, set up IT to deliver display
4245 elements from the first one. Otherwise set up IT to deliver
4246 from current_buffer. */
4247 if (it->n_overlay_strings)
4248 {
4249 /* Make sure we know settings in current_buffer, so that we can
4250 restore meaningful values when we're done with the overlay
4251 strings. */
4252 compute_stop_pos (it);
4253 xassert (it->face_id >= 0);
4254
4255 /* Save IT's settings. They are restored after all overlay
4256 strings have been processed. */
4257 xassert (it->sp == 0);
4258 push_it (it);
4259
4260 /* Set up IT to deliver display elements from the first overlay
4261 string. */
4262 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4263 it->string = it->overlay_strings[0];
4264 it->stop_charpos = 0;
4265 xassert (STRINGP (it->string));
4266 it->end_charpos = SCHARS (it->string);
4267 it->multibyte_p = STRING_MULTIBYTE (it->string);
4268 it->method = next_element_from_string;
4269 }
4270 else
4271 {
4272 it->string = Qnil;
4273 it->current.overlay_string_index = -1;
4274 it->method = next_element_from_buffer;
4275 }
4276
4277 CHECK_IT (it);
4278
4279 /* Value is non-zero if we found at least one overlay string. */
4280 return STRINGP (it->string);
4281 }
4282
4283
4284 \f
4285 /***********************************************************************
4286 Saving and restoring state
4287 ***********************************************************************/
4288
4289 /* Save current settings of IT on IT->stack. Called, for example,
4290 before setting up IT for an overlay string, to be able to restore
4291 IT's settings to what they were after the overlay string has been
4292 processed. */
4293
4294 static void
4295 push_it (it)
4296 struct it *it;
4297 {
4298 struct iterator_stack_entry *p;
4299
4300 xassert (it->sp < 2);
4301 p = it->stack + it->sp;
4302
4303 p->stop_charpos = it->stop_charpos;
4304 xassert (it->face_id >= 0);
4305 p->face_id = it->face_id;
4306 p->string = it->string;
4307 p->pos = it->current;
4308 p->end_charpos = it->end_charpos;
4309 p->string_nchars = it->string_nchars;
4310 p->area = it->area;
4311 p->multibyte_p = it->multibyte_p;
4312 p->space_width = it->space_width;
4313 p->font_height = it->font_height;
4314 p->voffset = it->voffset;
4315 p->string_from_display_prop_p = it->string_from_display_prop_p;
4316 p->display_ellipsis_p = 0;
4317 ++it->sp;
4318 }
4319
4320
4321 /* Restore IT's settings from IT->stack. Called, for example, when no
4322 more overlay strings must be processed, and we return to delivering
4323 display elements from a buffer, or when the end of a string from a
4324 `display' property is reached and we return to delivering display
4325 elements from an overlay string, or from a buffer. */
4326
4327 static void
4328 pop_it (it)
4329 struct it *it;
4330 {
4331 struct iterator_stack_entry *p;
4332
4333 xassert (it->sp > 0);
4334 --it->sp;
4335 p = it->stack + it->sp;
4336 it->stop_charpos = p->stop_charpos;
4337 it->face_id = p->face_id;
4338 it->string = p->string;
4339 it->current = p->pos;
4340 it->end_charpos = p->end_charpos;
4341 it->string_nchars = p->string_nchars;
4342 it->area = p->area;
4343 it->multibyte_p = p->multibyte_p;
4344 it->space_width = p->space_width;
4345 it->font_height = p->font_height;
4346 it->voffset = p->voffset;
4347 it->string_from_display_prop_p = p->string_from_display_prop_p;
4348 }
4349
4350
4351 \f
4352 /***********************************************************************
4353 Moving over lines
4354 ***********************************************************************/
4355
4356 /* Set IT's current position to the previous line start. */
4357
4358 static void
4359 back_to_previous_line_start (it)
4360 struct it *it;
4361 {
4362 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4363 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4364 }
4365
4366
4367 /* Move IT to the next line start.
4368
4369 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4370 we skipped over part of the text (as opposed to moving the iterator
4371 continuously over the text). Otherwise, don't change the value
4372 of *SKIPPED_P.
4373
4374 Newlines may come from buffer text, overlay strings, or strings
4375 displayed via the `display' property. That's the reason we can't
4376 simply use find_next_newline_no_quit.
4377
4378 Note that this function may not skip over invisible text that is so
4379 because of text properties and immediately follows a newline. If
4380 it would, function reseat_at_next_visible_line_start, when called
4381 from set_iterator_to_next, would effectively make invisible
4382 characters following a newline part of the wrong glyph row, which
4383 leads to wrong cursor motion. */
4384
4385 static int
4386 forward_to_next_line_start (it, skipped_p)
4387 struct it *it;
4388 int *skipped_p;
4389 {
4390 int old_selective, newline_found_p, n;
4391 const int MAX_NEWLINE_DISTANCE = 500;
4392
4393 /* If already on a newline, just consume it to avoid unintended
4394 skipping over invisible text below. */
4395 if (it->what == IT_CHARACTER
4396 && it->c == '\n'
4397 && CHARPOS (it->position) == IT_CHARPOS (*it))
4398 {
4399 set_iterator_to_next (it, 0);
4400 it->c = 0;
4401 return 1;
4402 }
4403
4404 /* Don't handle selective display in the following. It's (a)
4405 unnecessary because it's done by the caller, and (b) leads to an
4406 infinite recursion because next_element_from_ellipsis indirectly
4407 calls this function. */
4408 old_selective = it->selective;
4409 it->selective = 0;
4410
4411 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4412 from buffer text. */
4413 for (n = newline_found_p = 0;
4414 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4415 n += STRINGP (it->string) ? 0 : 1)
4416 {
4417 if (!get_next_display_element (it))
4418 return 0;
4419 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4420 set_iterator_to_next (it, 0);
4421 }
4422
4423 /* If we didn't find a newline near enough, see if we can use a
4424 short-cut. */
4425 if (!newline_found_p)
4426 {
4427 int start = IT_CHARPOS (*it);
4428 int limit = find_next_newline_no_quit (start, 1);
4429 Lisp_Object pos;
4430
4431 xassert (!STRINGP (it->string));
4432
4433 /* If there isn't any `display' property in sight, and no
4434 overlays, we can just use the position of the newline in
4435 buffer text. */
4436 if (it->stop_charpos >= limit
4437 || ((pos = Fnext_single_property_change (make_number (start),
4438 Qdisplay,
4439 Qnil, make_number (limit)),
4440 NILP (pos))
4441 && next_overlay_change (start) == ZV))
4442 {
4443 IT_CHARPOS (*it) = limit;
4444 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4445 *skipped_p = newline_found_p = 1;
4446 }
4447 else
4448 {
4449 while (get_next_display_element (it)
4450 && !newline_found_p)
4451 {
4452 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4453 set_iterator_to_next (it, 0);
4454 }
4455 }
4456 }
4457
4458 it->selective = old_selective;
4459 return newline_found_p;
4460 }
4461
4462
4463 /* Set IT's current position to the previous visible line start. Skip
4464 invisible text that is so either due to text properties or due to
4465 selective display. Caution: this does not change IT->current_x and
4466 IT->hpos. */
4467
4468 static void
4469 back_to_previous_visible_line_start (it)
4470 struct it *it;
4471 {
4472 int visible_p = 0;
4473
4474 /* Go back one newline if not on BEGV already. */
4475 if (IT_CHARPOS (*it) > BEGV)
4476 back_to_previous_line_start (it);
4477
4478 /* Move over lines that are invisible because of selective display
4479 or text properties. */
4480 while (IT_CHARPOS (*it) > BEGV
4481 && !visible_p)
4482 {
4483 visible_p = 1;
4484
4485 /* If selective > 0, then lines indented more than that values
4486 are invisible. */
4487 if (it->selective > 0
4488 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4489 (double) it->selective)) /* iftc */
4490 visible_p = 0;
4491 else
4492 {
4493 Lisp_Object prop;
4494
4495 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4496 Qinvisible, it->window);
4497 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4498 visible_p = 0;
4499 }
4500
4501 /* Back one more newline if the current one is invisible. */
4502 if (!visible_p)
4503 back_to_previous_line_start (it);
4504 }
4505
4506 xassert (IT_CHARPOS (*it) >= BEGV);
4507 xassert (IT_CHARPOS (*it) == BEGV
4508 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4509 CHECK_IT (it);
4510 }
4511
4512
4513 /* Reseat iterator IT at the previous visible line start. Skip
4514 invisible text that is so either due to text properties or due to
4515 selective display. At the end, update IT's overlay information,
4516 face information etc. */
4517
4518 static void
4519 reseat_at_previous_visible_line_start (it)
4520 struct it *it;
4521 {
4522 back_to_previous_visible_line_start (it);
4523 reseat (it, it->current.pos, 1);
4524 CHECK_IT (it);
4525 }
4526
4527
4528 /* Reseat iterator IT on the next visible line start in the current
4529 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4530 preceding the line start. Skip over invisible text that is so
4531 because of selective display. Compute faces, overlays etc at the
4532 new position. Note that this function does not skip over text that
4533 is invisible because of text properties. */
4534
4535 static void
4536 reseat_at_next_visible_line_start (it, on_newline_p)
4537 struct it *it;
4538 int on_newline_p;
4539 {
4540 int newline_found_p, skipped_p = 0;
4541
4542 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4543
4544 /* Skip over lines that are invisible because they are indented
4545 more than the value of IT->selective. */
4546 if (it->selective > 0)
4547 while (IT_CHARPOS (*it) < ZV
4548 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4549 (double) it->selective)) /* iftc */
4550 {
4551 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4552 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4553 }
4554
4555 /* Position on the newline if that's what's requested. */
4556 if (on_newline_p && newline_found_p)
4557 {
4558 if (STRINGP (it->string))
4559 {
4560 if (IT_STRING_CHARPOS (*it) > 0)
4561 {
4562 --IT_STRING_CHARPOS (*it);
4563 --IT_STRING_BYTEPOS (*it);
4564 }
4565 }
4566 else if (IT_CHARPOS (*it) > BEGV)
4567 {
4568 --IT_CHARPOS (*it);
4569 --IT_BYTEPOS (*it);
4570 reseat (it, it->current.pos, 0);
4571 }
4572 }
4573 else if (skipped_p)
4574 reseat (it, it->current.pos, 0);
4575
4576 CHECK_IT (it);
4577 }
4578
4579
4580 \f
4581 /***********************************************************************
4582 Changing an iterator's position
4583 ***********************************************************************/
4584
4585 /* Change IT's current position to POS in current_buffer. If FORCE_P
4586 is non-zero, always check for text properties at the new position.
4587 Otherwise, text properties are only looked up if POS >=
4588 IT->check_charpos of a property. */
4589
4590 static void
4591 reseat (it, pos, force_p)
4592 struct it *it;
4593 struct text_pos pos;
4594 int force_p;
4595 {
4596 int original_pos = IT_CHARPOS (*it);
4597
4598 reseat_1 (it, pos, 0);
4599
4600 /* Determine where to check text properties. Avoid doing it
4601 where possible because text property lookup is very expensive. */
4602 if (force_p
4603 || CHARPOS (pos) > it->stop_charpos
4604 || CHARPOS (pos) < original_pos)
4605 handle_stop (it);
4606
4607 CHECK_IT (it);
4608 }
4609
4610
4611 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4612 IT->stop_pos to POS, also. */
4613
4614 static void
4615 reseat_1 (it, pos, set_stop_p)
4616 struct it *it;
4617 struct text_pos pos;
4618 int set_stop_p;
4619 {
4620 /* Don't call this function when scanning a C string. */
4621 xassert (it->s == NULL);
4622
4623 /* POS must be a reasonable value. */
4624 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4625
4626 it->current.pos = it->position = pos;
4627 XSETBUFFER (it->object, current_buffer);
4628 it->end_charpos = ZV;
4629 it->dpvec = NULL;
4630 it->current.dpvec_index = -1;
4631 it->current.overlay_string_index = -1;
4632 IT_STRING_CHARPOS (*it) = -1;
4633 IT_STRING_BYTEPOS (*it) = -1;
4634 it->string = Qnil;
4635 it->method = next_element_from_buffer;
4636 /* RMS: I added this to fix a bug in move_it_vertically_backward
4637 where it->area continued to relate to the starting point
4638 for the backward motion. Bug report from
4639 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4640 However, I am not sure whether reseat still does the right thing
4641 in general after this change. */
4642 it->area = TEXT_AREA;
4643 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4644 it->sp = 0;
4645 it->face_before_selective_p = 0;
4646
4647 if (set_stop_p)
4648 it->stop_charpos = CHARPOS (pos);
4649 }
4650
4651
4652 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4653 If S is non-null, it is a C string to iterate over. Otherwise,
4654 STRING gives a Lisp string to iterate over.
4655
4656 If PRECISION > 0, don't return more then PRECISION number of
4657 characters from the string.
4658
4659 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4660 characters have been returned. FIELD_WIDTH < 0 means an infinite
4661 field width.
4662
4663 MULTIBYTE = 0 means disable processing of multibyte characters,
4664 MULTIBYTE > 0 means enable it,
4665 MULTIBYTE < 0 means use IT->multibyte_p.
4666
4667 IT must be initialized via a prior call to init_iterator before
4668 calling this function. */
4669
4670 static void
4671 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4672 struct it *it;
4673 unsigned char *s;
4674 Lisp_Object string;
4675 int charpos;
4676 int precision, field_width, multibyte;
4677 {
4678 /* No region in strings. */
4679 it->region_beg_charpos = it->region_end_charpos = -1;
4680
4681 /* No text property checks performed by default, but see below. */
4682 it->stop_charpos = -1;
4683
4684 /* Set iterator position and end position. */
4685 bzero (&it->current, sizeof it->current);
4686 it->current.overlay_string_index = -1;
4687 it->current.dpvec_index = -1;
4688 xassert (charpos >= 0);
4689
4690 /* If STRING is specified, use its multibyteness, otherwise use the
4691 setting of MULTIBYTE, if specified. */
4692 if (multibyte >= 0)
4693 it->multibyte_p = multibyte > 0;
4694
4695 if (s == NULL)
4696 {
4697 xassert (STRINGP (string));
4698 it->string = string;
4699 it->s = NULL;
4700 it->end_charpos = it->string_nchars = SCHARS (string);
4701 it->method = next_element_from_string;
4702 it->current.string_pos = string_pos (charpos, string);
4703 }
4704 else
4705 {
4706 it->s = s;
4707 it->string = Qnil;
4708
4709 /* Note that we use IT->current.pos, not it->current.string_pos,
4710 for displaying C strings. */
4711 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4712 if (it->multibyte_p)
4713 {
4714 it->current.pos = c_string_pos (charpos, s, 1);
4715 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4716 }
4717 else
4718 {
4719 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4720 it->end_charpos = it->string_nchars = strlen (s);
4721 }
4722
4723 it->method = next_element_from_c_string;
4724 }
4725
4726 /* PRECISION > 0 means don't return more than PRECISION characters
4727 from the string. */
4728 if (precision > 0 && it->end_charpos - charpos > precision)
4729 it->end_charpos = it->string_nchars = charpos + precision;
4730
4731 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4732 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4733 FIELD_WIDTH < 0 means infinite field width. This is useful for
4734 padding with `-' at the end of a mode line. */
4735 if (field_width < 0)
4736 field_width = INFINITY;
4737 if (field_width > it->end_charpos - charpos)
4738 it->end_charpos = charpos + field_width;
4739
4740 /* Use the standard display table for displaying strings. */
4741 if (DISP_TABLE_P (Vstandard_display_table))
4742 it->dp = XCHAR_TABLE (Vstandard_display_table);
4743
4744 it->stop_charpos = charpos;
4745 CHECK_IT (it);
4746 }
4747
4748
4749 \f
4750 /***********************************************************************
4751 Iteration
4752 ***********************************************************************/
4753
4754 /* Load IT's display element fields with information about the next
4755 display element from the current position of IT. Value is zero if
4756 end of buffer (or C string) is reached. */
4757
4758 int
4759 get_next_display_element (it)
4760 struct it *it;
4761 {
4762 /* Non-zero means that we found a display element. Zero means that
4763 we hit the end of what we iterate over. Performance note: the
4764 function pointer `method' used here turns out to be faster than
4765 using a sequence of if-statements. */
4766 int success_p = (*it->method) (it);
4767
4768 if (it->what == IT_CHARACTER)
4769 {
4770 /* Map via display table or translate control characters.
4771 IT->c, IT->len etc. have been set to the next character by
4772 the function call above. If we have a display table, and it
4773 contains an entry for IT->c, translate it. Don't do this if
4774 IT->c itself comes from a display table, otherwise we could
4775 end up in an infinite recursion. (An alternative could be to
4776 count the recursion depth of this function and signal an
4777 error when a certain maximum depth is reached.) Is it worth
4778 it? */
4779 if (success_p && it->dpvec == NULL)
4780 {
4781 Lisp_Object dv;
4782
4783 if (it->dp
4784 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4785 VECTORP (dv)))
4786 {
4787 struct Lisp_Vector *v = XVECTOR (dv);
4788
4789 /* Return the first character from the display table
4790 entry, if not empty. If empty, don't display the
4791 current character. */
4792 if (v->size)
4793 {
4794 it->dpvec_char_len = it->len;
4795 it->dpvec = v->contents;
4796 it->dpend = v->contents + v->size;
4797 it->current.dpvec_index = 0;
4798 it->method = next_element_from_display_vector;
4799 success_p = get_next_display_element (it);
4800 }
4801 else
4802 {
4803 set_iterator_to_next (it, 0);
4804 success_p = get_next_display_element (it);
4805 }
4806 }
4807
4808 /* Translate control characters into `\003' or `^C' form.
4809 Control characters coming from a display table entry are
4810 currently not translated because we use IT->dpvec to hold
4811 the translation. This could easily be changed but I
4812 don't believe that it is worth doing.
4813
4814 If it->multibyte_p is nonzero, eight-bit characters and
4815 non-printable multibyte characters are also translated to
4816 octal form.
4817
4818 If it->multibyte_p is zero, eight-bit characters that
4819 don't have corresponding multibyte char code are also
4820 translated to octal form. */
4821 else if ((it->c < ' '
4822 && (it->area != TEXT_AREA
4823 || (it->c != '\n' && it->c != '\t')))
4824 || (it->c != '\n' && it->c != '\t'
4825 && (it->multibyte_p ? !CHAR_PRINTABLE_P (it->c)
4826 : it->c == 127)))
4827 {
4828 /* IT->c is a control character which must be displayed
4829 either as '\003' or as `^C' where the '\\' and '^'
4830 can be defined in the display table. Fill
4831 IT->ctl_chars with glyphs for what we have to
4832 display. Then, set IT->dpvec to these glyphs. */
4833 GLYPH g;
4834
4835 if (it->c < 128 && it->ctl_arrow_p)
4836 {
4837 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4838 if (it->dp
4839 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4840 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4841 g = XINT (DISP_CTRL_GLYPH (it->dp));
4842 else
4843 g = FAST_MAKE_GLYPH ('^', 0);
4844 XSETINT (it->ctl_chars[0], g);
4845
4846 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4847 XSETINT (it->ctl_chars[1], g);
4848
4849 /* Set up IT->dpvec and return first character from it. */
4850 it->dpvec_char_len = it->len;
4851 it->dpvec = it->ctl_chars;
4852 it->dpend = it->dpvec + 2;
4853 it->current.dpvec_index = 0;
4854 it->method = next_element_from_display_vector;
4855 get_next_display_element (it);
4856 }
4857 else
4858 {
4859 unsigned char str[MAX_MULTIBYTE_LENGTH];
4860 int len;
4861 int i;
4862 GLYPH escape_glyph;
4863
4864 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4865 if (it->dp
4866 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4867 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4868 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4869 else
4870 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4871
4872 if (CHAR_BYTE8_P (it->c))
4873 {
4874 str[0] = CHAR_TO_BYTE8 (it->c);
4875 len = 1;
4876 }
4877 else if (it->c < 256)
4878 {
4879 str[0] = it->c;
4880 len = 1;
4881 }
4882 else
4883 {
4884 /* It's an invalid character, which
4885 shouldn't happen actually, but due to
4886 bugs it may happen. Let's print the char
4887 as is, there's not much meaningful we can
4888 do with it. */
4889 str[0] = it->c;
4890 str[1] = it->c >> 8;
4891 str[2] = it->c >> 16;
4892 str[3] = it->c >> 24;
4893 len = 4;
4894 }
4895
4896 for (i = 0; i < len; i++)
4897 {
4898 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4899 /* Insert three more glyphs into IT->ctl_chars for
4900 the octal display of the character. */
4901 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4902 XSETINT (it->ctl_chars[i * 4 + 1], g);
4903 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4904 XSETINT (it->ctl_chars[i * 4 + 2], g);
4905 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4906 XSETINT (it->ctl_chars[i * 4 + 3], g);
4907 }
4908
4909 /* Set up IT->dpvec and return the first character
4910 from it. */
4911 it->dpvec_char_len = it->len;
4912 it->dpvec = it->ctl_chars;
4913 it->dpend = it->dpvec + len * 4;
4914 it->current.dpvec_index = 0;
4915 it->method = next_element_from_display_vector;
4916 get_next_display_element (it);
4917 }
4918 }
4919 }
4920
4921 /* Adjust face id for a multibyte character. There are no
4922 multibyte character in unibyte text. */
4923 if (it->multibyte_p
4924 && success_p
4925 && FRAME_WINDOW_P (it->f))
4926 {
4927 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4928 int pos = (it->s ? -1
4929 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
4930 : IT_CHARPOS (*it));
4931
4932 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
4933 }
4934 }
4935
4936 /* Is this character the last one of a run of characters with
4937 box? If yes, set IT->end_of_box_run_p to 1. */
4938 if (it->face_box_p
4939 && it->s == NULL)
4940 {
4941 int face_id;
4942 struct face *face;
4943
4944 it->end_of_box_run_p
4945 = ((face_id = face_after_it_pos (it),
4946 face_id != it->face_id)
4947 && (face = FACE_FROM_ID (it->f, face_id),
4948 face->box == FACE_NO_BOX));
4949 }
4950
4951 /* Value is 0 if end of buffer or string reached. */
4952 return success_p;
4953 }
4954
4955
4956 /* Move IT to the next display element.
4957
4958 RESEAT_P non-zero means if called on a newline in buffer text,
4959 skip to the next visible line start.
4960
4961 Functions get_next_display_element and set_iterator_to_next are
4962 separate because I find this arrangement easier to handle than a
4963 get_next_display_element function that also increments IT's
4964 position. The way it is we can first look at an iterator's current
4965 display element, decide whether it fits on a line, and if it does,
4966 increment the iterator position. The other way around we probably
4967 would either need a flag indicating whether the iterator has to be
4968 incremented the next time, or we would have to implement a
4969 decrement position function which would not be easy to write. */
4970
4971 void
4972 set_iterator_to_next (it, reseat_p)
4973 struct it *it;
4974 int reseat_p;
4975 {
4976 /* Reset flags indicating start and end of a sequence of characters
4977 with box. Reset them at the start of this function because
4978 moving the iterator to a new position might set them. */
4979 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4980
4981 if (it->method == next_element_from_buffer)
4982 {
4983 /* The current display element of IT is a character from
4984 current_buffer. Advance in the buffer, and maybe skip over
4985 invisible lines that are so because of selective display. */
4986 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4987 reseat_at_next_visible_line_start (it, 0);
4988 else
4989 {
4990 xassert (it->len != 0);
4991 IT_BYTEPOS (*it) += it->len;
4992 IT_CHARPOS (*it) += 1;
4993 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4994 }
4995 }
4996 else if (it->method == next_element_from_composition)
4997 {
4998 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4999 if (STRINGP (it->string))
5000 {
5001 IT_STRING_BYTEPOS (*it) += it->len;
5002 IT_STRING_CHARPOS (*it) += it->cmp_len;
5003 it->method = next_element_from_string;
5004 goto consider_string_end;
5005 }
5006 else
5007 {
5008 IT_BYTEPOS (*it) += it->len;
5009 IT_CHARPOS (*it) += it->cmp_len;
5010 it->method = next_element_from_buffer;
5011 }
5012 }
5013 else if (it->method == next_element_from_c_string)
5014 {
5015 /* Current display element of IT is from a C string. */
5016 IT_BYTEPOS (*it) += it->len;
5017 IT_CHARPOS (*it) += 1;
5018 }
5019 else if (it->method == next_element_from_display_vector)
5020 {
5021 /* Current display element of IT is from a display table entry.
5022 Advance in the display table definition. Reset it to null if
5023 end reached, and continue with characters from buffers/
5024 strings. */
5025 ++it->current.dpvec_index;
5026
5027 /* Restore face of the iterator to what they were before the
5028 display vector entry (these entries may contain faces). */
5029 it->face_id = it->saved_face_id;
5030
5031 if (it->dpvec + it->current.dpvec_index == it->dpend)
5032 {
5033 if (it->s)
5034 it->method = next_element_from_c_string;
5035 else if (STRINGP (it->string))
5036 it->method = next_element_from_string;
5037 else
5038 it->method = next_element_from_buffer;
5039
5040 it->dpvec = NULL;
5041 it->current.dpvec_index = -1;
5042
5043 /* Skip over characters which were displayed via IT->dpvec. */
5044 if (it->dpvec_char_len < 0)
5045 reseat_at_next_visible_line_start (it, 1);
5046 else if (it->dpvec_char_len > 0)
5047 {
5048 it->len = it->dpvec_char_len;
5049 set_iterator_to_next (it, reseat_p);
5050 }
5051 }
5052 }
5053 else if (it->method == next_element_from_string)
5054 {
5055 /* Current display element is a character from a Lisp string. */
5056 xassert (it->s == NULL && STRINGP (it->string));
5057 IT_STRING_BYTEPOS (*it) += it->len;
5058 IT_STRING_CHARPOS (*it) += 1;
5059
5060 consider_string_end:
5061
5062 if (it->current.overlay_string_index >= 0)
5063 {
5064 /* IT->string is an overlay string. Advance to the
5065 next, if there is one. */
5066 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5067 next_overlay_string (it);
5068 }
5069 else
5070 {
5071 /* IT->string is not an overlay string. If we reached
5072 its end, and there is something on IT->stack, proceed
5073 with what is on the stack. This can be either another
5074 string, this time an overlay string, or a buffer. */
5075 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5076 && it->sp > 0)
5077 {
5078 pop_it (it);
5079 if (!STRINGP (it->string))
5080 it->method = next_element_from_buffer;
5081 else
5082 goto consider_string_end;
5083 }
5084 }
5085 }
5086 else if (it->method == next_element_from_image
5087 || it->method == next_element_from_stretch)
5088 {
5089 /* The position etc with which we have to proceed are on
5090 the stack. The position may be at the end of a string,
5091 if the `display' property takes up the whole string. */
5092 pop_it (it);
5093 it->image_id = 0;
5094 if (STRINGP (it->string))
5095 {
5096 it->method = next_element_from_string;
5097 goto consider_string_end;
5098 }
5099 else
5100 it->method = next_element_from_buffer;
5101 }
5102 else
5103 /* There are no other methods defined, so this should be a bug. */
5104 abort ();
5105
5106 xassert (it->method != next_element_from_string
5107 || (STRINGP (it->string)
5108 && IT_STRING_CHARPOS (*it) >= 0));
5109 }
5110
5111
5112 /* Load IT's display element fields with information about the next
5113 display element which comes from a display table entry or from the
5114 result of translating a control character to one of the forms `^C'
5115 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5116
5117 static int
5118 next_element_from_display_vector (it)
5119 struct it *it;
5120 {
5121 /* Precondition. */
5122 xassert (it->dpvec && it->current.dpvec_index >= 0);
5123
5124 /* Remember the current face id in case glyphs specify faces.
5125 IT's face is restored in set_iterator_to_next. */
5126 it->saved_face_id = it->face_id;
5127
5128 if (INTEGERP (*it->dpvec)
5129 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5130 {
5131 int lface_id;
5132 GLYPH g;
5133
5134 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5135 it->c = FAST_GLYPH_CHAR (g);
5136 it->len = CHAR_BYTES (it->c);
5137
5138 /* The entry may contain a face id to use. Such a face id is
5139 the id of a Lisp face, not a realized face. A face id of
5140 zero means no face is specified. */
5141 lface_id = FAST_GLYPH_FACE (g);
5142 if (lface_id)
5143 {
5144 /* The function returns -1 if lface_id is invalid. */
5145 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5146 if (face_id >= 0)
5147 it->face_id = face_id;
5148 }
5149 }
5150 else
5151 /* Display table entry is invalid. Return a space. */
5152 it->c = ' ', it->len = 1;
5153
5154 /* Don't change position and object of the iterator here. They are
5155 still the values of the character that had this display table
5156 entry or was translated, and that's what we want. */
5157 it->what = IT_CHARACTER;
5158 return 1;
5159 }
5160
5161
5162 /* Load IT with the next display element from Lisp string IT->string.
5163 IT->current.string_pos is the current position within the string.
5164 If IT->current.overlay_string_index >= 0, the Lisp string is an
5165 overlay string. */
5166
5167 static int
5168 next_element_from_string (it)
5169 struct it *it;
5170 {
5171 struct text_pos position;
5172
5173 xassert (STRINGP (it->string));
5174 xassert (IT_STRING_CHARPOS (*it) >= 0);
5175 position = it->current.string_pos;
5176
5177 /* Time to check for invisible text? */
5178 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5179 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5180 {
5181 handle_stop (it);
5182
5183 /* Since a handler may have changed IT->method, we must
5184 recurse here. */
5185 return get_next_display_element (it);
5186 }
5187
5188 if (it->current.overlay_string_index >= 0)
5189 {
5190 /* Get the next character from an overlay string. In overlay
5191 strings, There is no field width or padding with spaces to
5192 do. */
5193 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5194 {
5195 it->what = IT_EOB;
5196 return 0;
5197 }
5198 else if (STRING_MULTIBYTE (it->string))
5199 {
5200 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5201 const unsigned char *s = (SDATA (it->string)
5202 + IT_STRING_BYTEPOS (*it));
5203 it->c = string_char_and_length (s, remaining, &it->len);
5204 }
5205 else
5206 {
5207 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5208 it->len = 1;
5209 }
5210 }
5211 else
5212 {
5213 /* Get the next character from a Lisp string that is not an
5214 overlay string. Such strings come from the mode line, for
5215 example. We may have to pad with spaces, or truncate the
5216 string. See also next_element_from_c_string. */
5217 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5218 {
5219 it->what = IT_EOB;
5220 return 0;
5221 }
5222 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5223 {
5224 /* Pad with spaces. */
5225 it->c = ' ', it->len = 1;
5226 CHARPOS (position) = BYTEPOS (position) = -1;
5227 }
5228 else if (STRING_MULTIBYTE (it->string))
5229 {
5230 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5231 const unsigned char *s = (SDATA (it->string)
5232 + IT_STRING_BYTEPOS (*it));
5233 it->c = string_char_and_length (s, maxlen, &it->len);
5234 }
5235 else
5236 {
5237 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5238 it->len = 1;
5239 }
5240 }
5241
5242 /* Record what we have and where it came from. Note that we store a
5243 buffer position in IT->position although it could arguably be a
5244 string position. */
5245 it->what = IT_CHARACTER;
5246 it->object = it->string;
5247 it->position = position;
5248 return 1;
5249 }
5250
5251
5252 /* Load IT with next display element from C string IT->s.
5253 IT->string_nchars is the maximum number of characters to return
5254 from the string. IT->end_charpos may be greater than
5255 IT->string_nchars when this function is called, in which case we
5256 may have to return padding spaces. Value is zero if end of string
5257 reached, including padding spaces. */
5258
5259 static int
5260 next_element_from_c_string (it)
5261 struct it *it;
5262 {
5263 int success_p = 1;
5264
5265 xassert (it->s);
5266 it->what = IT_CHARACTER;
5267 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5268 it->object = Qnil;
5269
5270 /* IT's position can be greater IT->string_nchars in case a field
5271 width or precision has been specified when the iterator was
5272 initialized. */
5273 if (IT_CHARPOS (*it) >= it->end_charpos)
5274 {
5275 /* End of the game. */
5276 it->what = IT_EOB;
5277 success_p = 0;
5278 }
5279 else if (IT_CHARPOS (*it) >= it->string_nchars)
5280 {
5281 /* Pad with spaces. */
5282 it->c = ' ', it->len = 1;
5283 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5284 }
5285 else if (it->multibyte_p)
5286 {
5287 /* Implementation note: The calls to strlen apparently aren't a
5288 performance problem because there is no noticeable performance
5289 difference between Emacs running in unibyte or multibyte mode. */
5290 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5291 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5292 maxlen, &it->len);
5293 }
5294 else
5295 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5296
5297 return success_p;
5298 }
5299
5300
5301 /* Set up IT to return characters from an ellipsis, if appropriate.
5302 The definition of the ellipsis glyphs may come from a display table
5303 entry. This function Fills IT with the first glyph from the
5304 ellipsis if an ellipsis is to be displayed. */
5305
5306 static int
5307 next_element_from_ellipsis (it)
5308 struct it *it;
5309 {
5310 if (it->selective_display_ellipsis_p)
5311 {
5312 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5313 {
5314 /* Use the display table definition for `...'. Invalid glyphs
5315 will be handled by the method returning elements from dpvec. */
5316 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5317 it->dpvec_char_len = it->len;
5318 it->dpvec = v->contents;
5319 it->dpend = v->contents + v->size;
5320 it->current.dpvec_index = 0;
5321 it->method = next_element_from_display_vector;
5322 }
5323 else
5324 {
5325 /* Use default `...' which is stored in default_invis_vector. */
5326 it->dpvec_char_len = it->len;
5327 it->dpvec = default_invis_vector;
5328 it->dpend = default_invis_vector + 3;
5329 it->current.dpvec_index = 0;
5330 it->method = next_element_from_display_vector;
5331 }
5332 }
5333 else
5334 {
5335 /* The face at the current position may be different from the
5336 face we find after the invisible text. Remember what it
5337 was in IT->saved_face_id, and signal that it's there by
5338 setting face_before_selective_p. */
5339 it->saved_face_id = it->face_id;
5340 it->method = next_element_from_buffer;
5341 reseat_at_next_visible_line_start (it, 1);
5342 it->face_before_selective_p = 1;
5343 }
5344
5345 return get_next_display_element (it);
5346 }
5347
5348
5349 /* Deliver an image display element. The iterator IT is already
5350 filled with image information (done in handle_display_prop). Value
5351 is always 1. */
5352
5353
5354 static int
5355 next_element_from_image (it)
5356 struct it *it;
5357 {
5358 it->what = IT_IMAGE;
5359 return 1;
5360 }
5361
5362
5363 /* Fill iterator IT with next display element from a stretch glyph
5364 property. IT->object is the value of the text property. Value is
5365 always 1. */
5366
5367 static int
5368 next_element_from_stretch (it)
5369 struct it *it;
5370 {
5371 it->what = IT_STRETCH;
5372 return 1;
5373 }
5374
5375
5376 /* Load IT with the next display element from current_buffer. Value
5377 is zero if end of buffer reached. IT->stop_charpos is the next
5378 position at which to stop and check for text properties or buffer
5379 end. */
5380
5381 static int
5382 next_element_from_buffer (it)
5383 struct it *it;
5384 {
5385 int success_p = 1;
5386
5387 /* Check this assumption, otherwise, we would never enter the
5388 if-statement, below. */
5389 xassert (IT_CHARPOS (*it) >= BEGV
5390 && IT_CHARPOS (*it) <= it->stop_charpos);
5391
5392 if (IT_CHARPOS (*it) >= it->stop_charpos)
5393 {
5394 if (IT_CHARPOS (*it) >= it->end_charpos)
5395 {
5396 int overlay_strings_follow_p;
5397
5398 /* End of the game, except when overlay strings follow that
5399 haven't been returned yet. */
5400 if (it->overlay_strings_at_end_processed_p)
5401 overlay_strings_follow_p = 0;
5402 else
5403 {
5404 it->overlay_strings_at_end_processed_p = 1;
5405 overlay_strings_follow_p = get_overlay_strings (it, 0);
5406 }
5407
5408 if (overlay_strings_follow_p)
5409 success_p = get_next_display_element (it);
5410 else
5411 {
5412 it->what = IT_EOB;
5413 it->position = it->current.pos;
5414 success_p = 0;
5415 }
5416 }
5417 else
5418 {
5419 handle_stop (it);
5420 return get_next_display_element (it);
5421 }
5422 }
5423 else
5424 {
5425 /* No face changes, overlays etc. in sight, so just return a
5426 character from current_buffer. */
5427 unsigned char *p;
5428
5429 /* Maybe run the redisplay end trigger hook. Performance note:
5430 This doesn't seem to cost measurable time. */
5431 if (it->redisplay_end_trigger_charpos
5432 && it->glyph_row
5433 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5434 run_redisplay_end_trigger_hook (it);
5435
5436 /* Get the next character, maybe multibyte. */
5437 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5438 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5439 {
5440 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5441 - IT_BYTEPOS (*it));
5442 it->c = string_char_and_length (p, maxlen, &it->len);
5443 }
5444 else
5445 it->c = *p, it->len = 1;
5446
5447 /* Record what we have and where it came from. */
5448 it->what = IT_CHARACTER;;
5449 it->object = it->w->buffer;
5450 it->position = it->current.pos;
5451
5452 /* Normally we return the character found above, except when we
5453 really want to return an ellipsis for selective display. */
5454 if (it->selective)
5455 {
5456 if (it->c == '\n')
5457 {
5458 /* A value of selective > 0 means hide lines indented more
5459 than that number of columns. */
5460 if (it->selective > 0
5461 && IT_CHARPOS (*it) + 1 < ZV
5462 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5463 IT_BYTEPOS (*it) + 1,
5464 (double) it->selective)) /* iftc */
5465 {
5466 success_p = next_element_from_ellipsis (it);
5467 it->dpvec_char_len = -1;
5468 }
5469 }
5470 else if (it->c == '\r' && it->selective == -1)
5471 {
5472 /* A value of selective == -1 means that everything from the
5473 CR to the end of the line is invisible, with maybe an
5474 ellipsis displayed for it. */
5475 success_p = next_element_from_ellipsis (it);
5476 it->dpvec_char_len = -1;
5477 }
5478 }
5479 }
5480
5481 /* Value is zero if end of buffer reached. */
5482 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5483 return success_p;
5484 }
5485
5486
5487 /* Run the redisplay end trigger hook for IT. */
5488
5489 static void
5490 run_redisplay_end_trigger_hook (it)
5491 struct it *it;
5492 {
5493 Lisp_Object args[3];
5494
5495 /* IT->glyph_row should be non-null, i.e. we should be actually
5496 displaying something, or otherwise we should not run the hook. */
5497 xassert (it->glyph_row);
5498
5499 /* Set up hook arguments. */
5500 args[0] = Qredisplay_end_trigger_functions;
5501 args[1] = it->window;
5502 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5503 it->redisplay_end_trigger_charpos = 0;
5504
5505 /* Since we are *trying* to run these functions, don't try to run
5506 them again, even if they get an error. */
5507 it->w->redisplay_end_trigger = Qnil;
5508 Frun_hook_with_args (3, args);
5509
5510 /* Notice if it changed the face of the character we are on. */
5511 handle_face_prop (it);
5512 }
5513
5514
5515 /* Deliver a composition display element. The iterator IT is already
5516 filled with composition information (done in
5517 handle_composition_prop). Value is always 1. */
5518
5519 static int
5520 next_element_from_composition (it)
5521 struct it *it;
5522 {
5523 it->what = IT_COMPOSITION;
5524 it->position = (STRINGP (it->string)
5525 ? it->current.string_pos
5526 : it->current.pos);
5527 return 1;
5528 }
5529
5530
5531 \f
5532 /***********************************************************************
5533 Moving an iterator without producing glyphs
5534 ***********************************************************************/
5535
5536 /* Move iterator IT to a specified buffer or X position within one
5537 line on the display without producing glyphs.
5538
5539 OP should be a bit mask including some or all of these bits:
5540 MOVE_TO_X: Stop on reaching x-position TO_X.
5541 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5542 Regardless of OP's value, stop in reaching the end of the display line.
5543
5544 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5545 This means, in particular, that TO_X includes window's horizontal
5546 scroll amount.
5547
5548 The return value has several possible values that
5549 say what condition caused the scan to stop:
5550
5551 MOVE_POS_MATCH_OR_ZV
5552 - when TO_POS or ZV was reached.
5553
5554 MOVE_X_REACHED
5555 -when TO_X was reached before TO_POS or ZV were reached.
5556
5557 MOVE_LINE_CONTINUED
5558 - when we reached the end of the display area and the line must
5559 be continued.
5560
5561 MOVE_LINE_TRUNCATED
5562 - when we reached the end of the display area and the line is
5563 truncated.
5564
5565 MOVE_NEWLINE_OR_CR
5566 - when we stopped at a line end, i.e. a newline or a CR and selective
5567 display is on. */
5568
5569 static enum move_it_result
5570 move_it_in_display_line_to (it, to_charpos, to_x, op)
5571 struct it *it;
5572 int to_charpos, to_x, op;
5573 {
5574 enum move_it_result result = MOVE_UNDEFINED;
5575 struct glyph_row *saved_glyph_row;
5576
5577 /* Don't produce glyphs in produce_glyphs. */
5578 saved_glyph_row = it->glyph_row;
5579 it->glyph_row = NULL;
5580
5581 while (1)
5582 {
5583 int x, i, ascent = 0, descent = 0;
5584
5585 /* Stop when ZV or TO_CHARPOS reached. */
5586 if (!get_next_display_element (it)
5587 || ((op & MOVE_TO_POS) != 0
5588 && BUFFERP (it->object)
5589 && IT_CHARPOS (*it) >= to_charpos))
5590 {
5591 result = MOVE_POS_MATCH_OR_ZV;
5592 break;
5593 }
5594
5595 /* The call to produce_glyphs will get the metrics of the
5596 display element IT is loaded with. We record in x the
5597 x-position before this display element in case it does not
5598 fit on the line. */
5599 x = it->current_x;
5600
5601 /* Remember the line height so far in case the next element doesn't
5602 fit on the line. */
5603 if (!it->truncate_lines_p)
5604 {
5605 ascent = it->max_ascent;
5606 descent = it->max_descent;
5607 }
5608
5609 PRODUCE_GLYPHS (it);
5610
5611 if (it->area != TEXT_AREA)
5612 {
5613 set_iterator_to_next (it, 1);
5614 continue;
5615 }
5616
5617 /* The number of glyphs we get back in IT->nglyphs will normally
5618 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5619 character on a terminal frame, or (iii) a line end. For the
5620 second case, IT->nglyphs - 1 padding glyphs will be present
5621 (on X frames, there is only one glyph produced for a
5622 composite character.
5623
5624 The behavior implemented below means, for continuation lines,
5625 that as many spaces of a TAB as fit on the current line are
5626 displayed there. For terminal frames, as many glyphs of a
5627 multi-glyph character are displayed in the current line, too.
5628 This is what the old redisplay code did, and we keep it that
5629 way. Under X, the whole shape of a complex character must
5630 fit on the line or it will be completely displayed in the
5631 next line.
5632
5633 Note that both for tabs and padding glyphs, all glyphs have
5634 the same width. */
5635 if (it->nglyphs)
5636 {
5637 /* More than one glyph or glyph doesn't fit on line. All
5638 glyphs have the same width. */
5639 int single_glyph_width = it->pixel_width / it->nglyphs;
5640 int new_x;
5641
5642 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5643 {
5644 new_x = x + single_glyph_width;
5645
5646 /* We want to leave anything reaching TO_X to the caller. */
5647 if ((op & MOVE_TO_X) && new_x > to_x)
5648 {
5649 it->current_x = x;
5650 result = MOVE_X_REACHED;
5651 break;
5652 }
5653 else if (/* Lines are continued. */
5654 !it->truncate_lines_p
5655 && (/* And glyph doesn't fit on the line. */
5656 new_x > it->last_visible_x
5657 /* Or it fits exactly and we're on a window
5658 system frame. */
5659 || (new_x == it->last_visible_x
5660 && FRAME_WINDOW_P (it->f))))
5661 {
5662 if (/* IT->hpos == 0 means the very first glyph
5663 doesn't fit on the line, e.g. a wide image. */
5664 it->hpos == 0
5665 || (new_x == it->last_visible_x
5666 && FRAME_WINDOW_P (it->f)))
5667 {
5668 ++it->hpos;
5669 it->current_x = new_x;
5670 if (i == it->nglyphs - 1)
5671 set_iterator_to_next (it, 1);
5672 }
5673 else
5674 {
5675 it->current_x = x;
5676 it->max_ascent = ascent;
5677 it->max_descent = descent;
5678 }
5679
5680 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5681 IT_CHARPOS (*it)));
5682 result = MOVE_LINE_CONTINUED;
5683 break;
5684 }
5685 else if (new_x > it->first_visible_x)
5686 {
5687 /* Glyph is visible. Increment number of glyphs that
5688 would be displayed. */
5689 ++it->hpos;
5690 }
5691 else
5692 {
5693 /* Glyph is completely off the left margin of the display
5694 area. Nothing to do. */
5695 }
5696 }
5697
5698 if (result != MOVE_UNDEFINED)
5699 break;
5700 }
5701 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5702 {
5703 /* Stop when TO_X specified and reached. This check is
5704 necessary here because of lines consisting of a line end,
5705 only. The line end will not produce any glyphs and we
5706 would never get MOVE_X_REACHED. */
5707 xassert (it->nglyphs == 0);
5708 result = MOVE_X_REACHED;
5709 break;
5710 }
5711
5712 /* Is this a line end? If yes, we're done. */
5713 if (ITERATOR_AT_END_OF_LINE_P (it))
5714 {
5715 result = MOVE_NEWLINE_OR_CR;
5716 break;
5717 }
5718
5719 /* The current display element has been consumed. Advance
5720 to the next. */
5721 set_iterator_to_next (it, 1);
5722
5723 /* Stop if lines are truncated and IT's current x-position is
5724 past the right edge of the window now. */
5725 if (it->truncate_lines_p
5726 && it->current_x >= it->last_visible_x)
5727 {
5728 result = MOVE_LINE_TRUNCATED;
5729 break;
5730 }
5731 }
5732
5733 /* Restore the iterator settings altered at the beginning of this
5734 function. */
5735 it->glyph_row = saved_glyph_row;
5736 return result;
5737 }
5738
5739
5740 /* Move IT forward until it satisfies one or more of the criteria in
5741 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5742
5743 OP is a bit-mask that specifies where to stop, and in particular,
5744 which of those four position arguments makes a difference. See the
5745 description of enum move_operation_enum.
5746
5747 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5748 screen line, this function will set IT to the next position >
5749 TO_CHARPOS. */
5750
5751 void
5752 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5753 struct it *it;
5754 int to_charpos, to_x, to_y, to_vpos;
5755 int op;
5756 {
5757 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5758 int line_height;
5759 int reached = 0;
5760
5761 for (;;)
5762 {
5763 if (op & MOVE_TO_VPOS)
5764 {
5765 /* If no TO_CHARPOS and no TO_X specified, stop at the
5766 start of the line TO_VPOS. */
5767 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5768 {
5769 if (it->vpos == to_vpos)
5770 {
5771 reached = 1;
5772 break;
5773 }
5774 else
5775 skip = move_it_in_display_line_to (it, -1, -1, 0);
5776 }
5777 else
5778 {
5779 /* TO_VPOS >= 0 means stop at TO_X in the line at
5780 TO_VPOS, or at TO_POS, whichever comes first. */
5781 if (it->vpos == to_vpos)
5782 {
5783 reached = 2;
5784 break;
5785 }
5786
5787 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5788
5789 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5790 {
5791 reached = 3;
5792 break;
5793 }
5794 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5795 {
5796 /* We have reached TO_X but not in the line we want. */
5797 skip = move_it_in_display_line_to (it, to_charpos,
5798 -1, MOVE_TO_POS);
5799 if (skip == MOVE_POS_MATCH_OR_ZV)
5800 {
5801 reached = 4;
5802 break;
5803 }
5804 }
5805 }
5806 }
5807 else if (op & MOVE_TO_Y)
5808 {
5809 struct it it_backup;
5810
5811 /* TO_Y specified means stop at TO_X in the line containing
5812 TO_Y---or at TO_CHARPOS if this is reached first. The
5813 problem is that we can't really tell whether the line
5814 contains TO_Y before we have completely scanned it, and
5815 this may skip past TO_X. What we do is to first scan to
5816 TO_X.
5817
5818 If TO_X is not specified, use a TO_X of zero. The reason
5819 is to make the outcome of this function more predictable.
5820 If we didn't use TO_X == 0, we would stop at the end of
5821 the line which is probably not what a caller would expect
5822 to happen. */
5823 skip = move_it_in_display_line_to (it, to_charpos,
5824 ((op & MOVE_TO_X)
5825 ? to_x : 0),
5826 (MOVE_TO_X
5827 | (op & MOVE_TO_POS)));
5828
5829 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5830 if (skip == MOVE_POS_MATCH_OR_ZV)
5831 {
5832 reached = 5;
5833 break;
5834 }
5835
5836 /* If TO_X was reached, we would like to know whether TO_Y
5837 is in the line. This can only be said if we know the
5838 total line height which requires us to scan the rest of
5839 the line. */
5840 if (skip == MOVE_X_REACHED)
5841 {
5842 /* Wait! We can conclude that TO_Y is in the line if
5843 the already scanned glyphs make the line tall enough
5844 because further scanning doesn't make it shorter. */
5845 line_height = it->max_ascent + it->max_descent;
5846 if (to_y >= it->current_y
5847 && to_y < it->current_y + line_height)
5848 {
5849 reached = 6;
5850 break;
5851 }
5852 it_backup = *it;
5853 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5854 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5855 op & MOVE_TO_POS);
5856 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5857 }
5858
5859 /* Now, decide whether TO_Y is in this line. */
5860 line_height = it->max_ascent + it->max_descent;
5861 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5862
5863 if (to_y >= it->current_y
5864 && to_y < it->current_y + line_height)
5865 {
5866 if (skip == MOVE_X_REACHED)
5867 /* If TO_Y is in this line and TO_X was reached above,
5868 we scanned too far. We have to restore IT's settings
5869 to the ones before skipping. */
5870 *it = it_backup;
5871 reached = 6;
5872 }
5873 else if (skip == MOVE_X_REACHED)
5874 {
5875 skip = skip2;
5876 if (skip == MOVE_POS_MATCH_OR_ZV)
5877 reached = 7;
5878 }
5879
5880 if (reached)
5881 break;
5882 }
5883 else
5884 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5885
5886 switch (skip)
5887 {
5888 case MOVE_POS_MATCH_OR_ZV:
5889 reached = 8;
5890 goto out;
5891
5892 case MOVE_NEWLINE_OR_CR:
5893 set_iterator_to_next (it, 1);
5894 it->continuation_lines_width = 0;
5895 break;
5896
5897 case MOVE_LINE_TRUNCATED:
5898 it->continuation_lines_width = 0;
5899 reseat_at_next_visible_line_start (it, 0);
5900 if ((op & MOVE_TO_POS) != 0
5901 && IT_CHARPOS (*it) > to_charpos)
5902 {
5903 reached = 9;
5904 goto out;
5905 }
5906 break;
5907
5908 case MOVE_LINE_CONTINUED:
5909 it->continuation_lines_width += it->current_x;
5910 break;
5911
5912 default:
5913 abort ();
5914 }
5915
5916 /* Reset/increment for the next run. */
5917 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5918 it->current_x = it->hpos = 0;
5919 it->current_y += it->max_ascent + it->max_descent;
5920 ++it->vpos;
5921 last_height = it->max_ascent + it->max_descent;
5922 last_max_ascent = it->max_ascent;
5923 it->max_ascent = it->max_descent = 0;
5924 }
5925
5926 out:
5927
5928 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5929 }
5930
5931
5932 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5933
5934 If DY > 0, move IT backward at least that many pixels. DY = 0
5935 means move IT backward to the preceding line start or BEGV. This
5936 function may move over more than DY pixels if IT->current_y - DY
5937 ends up in the middle of a line; in this case IT->current_y will be
5938 set to the top of the line moved to. */
5939
5940 void
5941 move_it_vertically_backward (it, dy)
5942 struct it *it;
5943 int dy;
5944 {
5945 int nlines, h;
5946 struct it it2, it3;
5947 int start_pos = IT_CHARPOS (*it);
5948
5949 xassert (dy >= 0);
5950
5951 /* Estimate how many newlines we must move back. */
5952 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5953
5954 /* Set the iterator's position that many lines back. */
5955 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5956 back_to_previous_visible_line_start (it);
5957
5958 /* Reseat the iterator here. When moving backward, we don't want
5959 reseat to skip forward over invisible text, set up the iterator
5960 to deliver from overlay strings at the new position etc. So,
5961 use reseat_1 here. */
5962 reseat_1 (it, it->current.pos, 1);
5963
5964 /* We are now surely at a line start. */
5965 it->current_x = it->hpos = 0;
5966 it->continuation_lines_width = 0;
5967
5968 /* Move forward and see what y-distance we moved. First move to the
5969 start of the next line so that we get its height. We need this
5970 height to be able to tell whether we reached the specified
5971 y-distance. */
5972 it2 = *it;
5973 it2.max_ascent = it2.max_descent = 0;
5974 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5975 MOVE_TO_POS | MOVE_TO_VPOS);
5976 xassert (IT_CHARPOS (*it) >= BEGV);
5977 it3 = it2;
5978
5979 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5980 xassert (IT_CHARPOS (*it) >= BEGV);
5981 /* H is the actual vertical distance from the position in *IT
5982 and the starting position. */
5983 h = it2.current_y - it->current_y;
5984 /* NLINES is the distance in number of lines. */
5985 nlines = it2.vpos - it->vpos;
5986
5987 /* Correct IT's y and vpos position
5988 so that they are relative to the starting point. */
5989 it->vpos -= nlines;
5990 it->current_y -= h;
5991
5992 if (dy == 0)
5993 {
5994 /* DY == 0 means move to the start of the screen line. The
5995 value of nlines is > 0 if continuation lines were involved. */
5996 if (nlines > 0)
5997 move_it_by_lines (it, nlines, 1);
5998 xassert (IT_CHARPOS (*it) <= start_pos);
5999 }
6000 else
6001 {
6002 /* The y-position we try to reach, relative to *IT.
6003 Note that H has been subtracted in front of the if-statement. */
6004 int target_y = it->current_y + h - dy;
6005 int y0 = it3.current_y;
6006 int y1 = line_bottom_y (&it3);
6007 int line_height = y1 - y0;
6008
6009 /* If we did not reach target_y, try to move further backward if
6010 we can. If we moved too far backward, try to move forward. */
6011 if (target_y < it->current_y
6012 /* This is heuristic. In a window that's 3 lines high, with
6013 a line height of 13 pixels each, recentering with point
6014 on the bottom line will try to move -39/2 = 19 pixels
6015 backward. Try to avoid moving into the first line. */
6016 && it->current_y - target_y > line_height / 3 * 2
6017 && IT_CHARPOS (*it) > BEGV)
6018 {
6019 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6020 target_y - it->current_y));
6021 move_it_vertically (it, target_y - it->current_y);
6022 xassert (IT_CHARPOS (*it) >= BEGV);
6023 }
6024 else if (target_y >= it->current_y + line_height
6025 && IT_CHARPOS (*it) < ZV)
6026 {
6027 /* Should move forward by at least one line, maybe more.
6028
6029 Note: Calling move_it_by_lines can be expensive on
6030 terminal frames, where compute_motion is used (via
6031 vmotion) to do the job, when there are very long lines
6032 and truncate-lines is nil. That's the reason for
6033 treating terminal frames specially here. */
6034
6035 if (!FRAME_WINDOW_P (it->f))
6036 move_it_vertically (it, target_y - (it->current_y + line_height));
6037 else
6038 {
6039 do
6040 {
6041 move_it_by_lines (it, 1, 1);
6042 }
6043 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6044 }
6045
6046 xassert (IT_CHARPOS (*it) >= BEGV);
6047 }
6048 }
6049 }
6050
6051
6052 /* Move IT by a specified amount of pixel lines DY. DY negative means
6053 move backwards. DY = 0 means move to start of screen line. At the
6054 end, IT will be on the start of a screen line. */
6055
6056 void
6057 move_it_vertically (it, dy)
6058 struct it *it;
6059 int dy;
6060 {
6061 if (dy <= 0)
6062 move_it_vertically_backward (it, -dy);
6063 else if (dy > 0)
6064 {
6065 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6066 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6067 MOVE_TO_POS | MOVE_TO_Y);
6068 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6069
6070 /* If buffer ends in ZV without a newline, move to the start of
6071 the line to satisfy the post-condition. */
6072 if (IT_CHARPOS (*it) == ZV
6073 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6074 move_it_by_lines (it, 0, 0);
6075 }
6076 }
6077
6078
6079 /* Move iterator IT past the end of the text line it is in. */
6080
6081 void
6082 move_it_past_eol (it)
6083 struct it *it;
6084 {
6085 enum move_it_result rc;
6086
6087 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6088 if (rc == MOVE_NEWLINE_OR_CR)
6089 set_iterator_to_next (it, 0);
6090 }
6091
6092
6093 #if 0 /* Currently not used. */
6094
6095 /* Return non-zero if some text between buffer positions START_CHARPOS
6096 and END_CHARPOS is invisible. IT->window is the window for text
6097 property lookup. */
6098
6099 static int
6100 invisible_text_between_p (it, start_charpos, end_charpos)
6101 struct it *it;
6102 int start_charpos, end_charpos;
6103 {
6104 Lisp_Object prop, limit;
6105 int invisible_found_p;
6106
6107 xassert (it != NULL && start_charpos <= end_charpos);
6108
6109 /* Is text at START invisible? */
6110 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6111 it->window);
6112 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6113 invisible_found_p = 1;
6114 else
6115 {
6116 limit = Fnext_single_char_property_change (make_number (start_charpos),
6117 Qinvisible, Qnil,
6118 make_number (end_charpos));
6119 invisible_found_p = XFASTINT (limit) < end_charpos;
6120 }
6121
6122 return invisible_found_p;
6123 }
6124
6125 #endif /* 0 */
6126
6127
6128 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6129 negative means move up. DVPOS == 0 means move to the start of the
6130 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6131 NEED_Y_P is zero, IT->current_y will be left unchanged.
6132
6133 Further optimization ideas: If we would know that IT->f doesn't use
6134 a face with proportional font, we could be faster for
6135 truncate-lines nil. */
6136
6137 void
6138 move_it_by_lines (it, dvpos, need_y_p)
6139 struct it *it;
6140 int dvpos, need_y_p;
6141 {
6142 struct position pos;
6143
6144 if (!FRAME_WINDOW_P (it->f))
6145 {
6146 struct text_pos textpos;
6147
6148 /* We can use vmotion on frames without proportional fonts. */
6149 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6150 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6151 reseat (it, textpos, 1);
6152 it->vpos += pos.vpos;
6153 it->current_y += pos.vpos;
6154 }
6155 else if (dvpos == 0)
6156 {
6157 /* DVPOS == 0 means move to the start of the screen line. */
6158 move_it_vertically_backward (it, 0);
6159 xassert (it->current_x == 0 && it->hpos == 0);
6160 }
6161 else if (dvpos > 0)
6162 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6163 else
6164 {
6165 struct it it2;
6166 int start_charpos, i;
6167
6168 /* Start at the beginning of the screen line containing IT's
6169 position. */
6170 move_it_vertically_backward (it, 0);
6171
6172 /* Go back -DVPOS visible lines and reseat the iterator there. */
6173 start_charpos = IT_CHARPOS (*it);
6174 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6175 back_to_previous_visible_line_start (it);
6176 reseat (it, it->current.pos, 1);
6177 it->current_x = it->hpos = 0;
6178
6179 /* Above call may have moved too far if continuation lines
6180 are involved. Scan forward and see if it did. */
6181 it2 = *it;
6182 it2.vpos = it2.current_y = 0;
6183 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6184 it->vpos -= it2.vpos;
6185 it->current_y -= it2.current_y;
6186 it->current_x = it->hpos = 0;
6187
6188 /* If we moved too far, move IT some lines forward. */
6189 if (it2.vpos > -dvpos)
6190 {
6191 int delta = it2.vpos + dvpos;
6192 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6193 }
6194 }
6195 }
6196
6197 /* Return 1 if IT points into the middle of a display vector. */
6198
6199 int
6200 in_display_vector_p (it)
6201 struct it *it;
6202 {
6203 return (it->method == next_element_from_display_vector
6204 && it->current.dpvec_index > 0
6205 && it->dpvec + it->current.dpvec_index != it->dpend);
6206 }
6207
6208 \f
6209 /***********************************************************************
6210 Messages
6211 ***********************************************************************/
6212
6213
6214 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6215 to *Messages*. */
6216
6217 void
6218 add_to_log (format, arg1, arg2)
6219 char *format;
6220 Lisp_Object arg1, arg2;
6221 {
6222 Lisp_Object args[3];
6223 Lisp_Object msg, fmt;
6224 char *buffer;
6225 int len;
6226 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6227
6228 /* Do nothing if called asynchronously. Inserting text into
6229 a buffer may call after-change-functions and alike and
6230 that would means running Lisp asynchronously. */
6231 if (handling_signal)
6232 return;
6233
6234 fmt = msg = Qnil;
6235 GCPRO4 (fmt, msg, arg1, arg2);
6236
6237 args[0] = fmt = build_string (format);
6238 args[1] = arg1;
6239 args[2] = arg2;
6240 msg = Fformat (3, args);
6241
6242 len = SBYTES (msg) + 1;
6243 buffer = (char *) alloca (len);
6244 bcopy (SDATA (msg), buffer, len);
6245
6246 message_dolog (buffer, len - 1, 1, 0);
6247 UNGCPRO;
6248 }
6249
6250
6251 /* Output a newline in the *Messages* buffer if "needs" one. */
6252
6253 void
6254 message_log_maybe_newline ()
6255 {
6256 if (message_log_need_newline)
6257 message_dolog ("", 0, 1, 0);
6258 }
6259
6260
6261 /* Add a string M of length NBYTES to the message log, optionally
6262 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6263 nonzero, means interpret the contents of M as multibyte. This
6264 function calls low-level routines in order to bypass text property
6265 hooks, etc. which might not be safe to run. */
6266
6267 void
6268 message_dolog (m, nbytes, nlflag, multibyte)
6269 const char *m;
6270 int nbytes, nlflag, multibyte;
6271 {
6272 if (!NILP (Vmemory_full))
6273 return;
6274
6275 if (!NILP (Vmessage_log_max))
6276 {
6277 struct buffer *oldbuf;
6278 Lisp_Object oldpoint, oldbegv, oldzv;
6279 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6280 int point_at_end = 0;
6281 int zv_at_end = 0;
6282 Lisp_Object old_deactivate_mark, tem;
6283 struct gcpro gcpro1;
6284
6285 old_deactivate_mark = Vdeactivate_mark;
6286 oldbuf = current_buffer;
6287 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6288 current_buffer->undo_list = Qt;
6289
6290 oldpoint = message_dolog_marker1;
6291 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6292 oldbegv = message_dolog_marker2;
6293 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6294 oldzv = message_dolog_marker3;
6295 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6296 GCPRO1 (old_deactivate_mark);
6297
6298 if (PT == Z)
6299 point_at_end = 1;
6300 if (ZV == Z)
6301 zv_at_end = 1;
6302
6303 BEGV = BEG;
6304 BEGV_BYTE = BEG_BYTE;
6305 ZV = Z;
6306 ZV_BYTE = Z_BYTE;
6307 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6308
6309 /* Insert the string--maybe converting multibyte to single byte
6310 or vice versa, so that all the text fits the buffer. */
6311 if (multibyte
6312 && NILP (current_buffer->enable_multibyte_characters))
6313 {
6314 int i, c, char_bytes;
6315 unsigned char work[1];
6316
6317 /* Convert a multibyte string to single-byte
6318 for the *Message* buffer. */
6319 for (i = 0; i < nbytes; i += char_bytes)
6320 {
6321 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6322 work[0] = (ASCII_CHAR_P (c)
6323 ? c
6324 : multibyte_char_to_unibyte (c, Qnil));
6325 insert_1_both (work, 1, 1, 1, 0, 0);
6326 }
6327 }
6328 else if (! multibyte
6329 && ! NILP (current_buffer->enable_multibyte_characters))
6330 {
6331 int i, c, char_bytes;
6332 unsigned char *msg = (unsigned char *) m;
6333 unsigned char str[MAX_MULTIBYTE_LENGTH];
6334 /* Convert a single-byte string to multibyte
6335 for the *Message* buffer. */
6336 for (i = 0; i < nbytes; i++)
6337 {
6338 c = unibyte_char_to_multibyte (msg[i]);
6339 char_bytes = CHAR_STRING (c, str);
6340 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6341 }
6342 }
6343 else if (nbytes)
6344 insert_1 (m, nbytes, 1, 0, 0);
6345
6346 if (nlflag)
6347 {
6348 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6349 insert_1 ("\n", 1, 1, 0, 0);
6350
6351 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6352 this_bol = PT;
6353 this_bol_byte = PT_BYTE;
6354
6355 /* See if this line duplicates the previous one.
6356 If so, combine duplicates. */
6357 if (this_bol > BEG)
6358 {
6359 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6360 prev_bol = PT;
6361 prev_bol_byte = PT_BYTE;
6362
6363 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6364 this_bol, this_bol_byte);
6365 if (dup)
6366 {
6367 del_range_both (prev_bol, prev_bol_byte,
6368 this_bol, this_bol_byte, 0);
6369 if (dup > 1)
6370 {
6371 char dupstr[40];
6372 int duplen;
6373
6374 /* If you change this format, don't forget to also
6375 change message_log_check_duplicate. */
6376 sprintf (dupstr, " [%d times]", dup);
6377 duplen = strlen (dupstr);
6378 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6379 insert_1 (dupstr, duplen, 1, 0, 1);
6380 }
6381 }
6382 }
6383
6384 /* If we have more than the desired maximum number of lines
6385 in the *Messages* buffer now, delete the oldest ones.
6386 This is safe because we don't have undo in this buffer. */
6387
6388 if (NATNUMP (Vmessage_log_max))
6389 {
6390 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6391 -XFASTINT (Vmessage_log_max) - 1, 0);
6392 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6393 }
6394 }
6395 BEGV = XMARKER (oldbegv)->charpos;
6396 BEGV_BYTE = marker_byte_position (oldbegv);
6397
6398 if (zv_at_end)
6399 {
6400 ZV = Z;
6401 ZV_BYTE = Z_BYTE;
6402 }
6403 else
6404 {
6405 ZV = XMARKER (oldzv)->charpos;
6406 ZV_BYTE = marker_byte_position (oldzv);
6407 }
6408
6409 if (point_at_end)
6410 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6411 else
6412 /* We can't do Fgoto_char (oldpoint) because it will run some
6413 Lisp code. */
6414 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6415 XMARKER (oldpoint)->bytepos);
6416
6417 UNGCPRO;
6418 unchain_marker (XMARKER (oldpoint));
6419 unchain_marker (XMARKER (oldbegv));
6420 unchain_marker (XMARKER (oldzv));
6421
6422 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6423 set_buffer_internal (oldbuf);
6424 if (NILP (tem))
6425 windows_or_buffers_changed = old_windows_or_buffers_changed;
6426 message_log_need_newline = !nlflag;
6427 Vdeactivate_mark = old_deactivate_mark;
6428 }
6429 }
6430
6431
6432 /* We are at the end of the buffer after just having inserted a newline.
6433 (Note: We depend on the fact we won't be crossing the gap.)
6434 Check to see if the most recent message looks a lot like the previous one.
6435 Return 0 if different, 1 if the new one should just replace it, or a
6436 value N > 1 if we should also append " [N times]". */
6437
6438 static int
6439 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6440 int prev_bol, this_bol;
6441 int prev_bol_byte, this_bol_byte;
6442 {
6443 int i;
6444 int len = Z_BYTE - 1 - this_bol_byte;
6445 int seen_dots = 0;
6446 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6447 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6448
6449 for (i = 0; i < len; i++)
6450 {
6451 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6452 seen_dots = 1;
6453 if (p1[i] != p2[i])
6454 return seen_dots;
6455 }
6456 p1 += len;
6457 if (*p1 == '\n')
6458 return 2;
6459 if (*p1++ == ' ' && *p1++ == '[')
6460 {
6461 int n = 0;
6462 while (*p1 >= '0' && *p1 <= '9')
6463 n = n * 10 + *p1++ - '0';
6464 if (strncmp (p1, " times]\n", 8) == 0)
6465 return n+1;
6466 }
6467 return 0;
6468 }
6469
6470
6471 /* Display an echo area message M with a specified length of NBYTES
6472 bytes. The string may include null characters. If M is 0, clear
6473 out any existing message, and let the mini-buffer text show
6474 through.
6475
6476 The buffer M must continue to exist until after the echo area gets
6477 cleared or some other message gets displayed there. This means do
6478 not pass text that is stored in a Lisp string; do not pass text in
6479 a buffer that was alloca'd. */
6480
6481 void
6482 message2 (m, nbytes, multibyte)
6483 const char *m;
6484 int nbytes;
6485 int multibyte;
6486 {
6487 /* First flush out any partial line written with print. */
6488 message_log_maybe_newline ();
6489 if (m)
6490 message_dolog (m, nbytes, 1, multibyte);
6491 message2_nolog (m, nbytes, multibyte);
6492 }
6493
6494
6495 /* The non-logging counterpart of message2. */
6496
6497 void
6498 message2_nolog (m, nbytes, multibyte)
6499 const char *m;
6500 int nbytes, multibyte;
6501 {
6502 struct frame *sf = SELECTED_FRAME ();
6503 message_enable_multibyte = multibyte;
6504
6505 if (noninteractive)
6506 {
6507 if (noninteractive_need_newline)
6508 putc ('\n', stderr);
6509 noninteractive_need_newline = 0;
6510 if (m)
6511 fwrite (m, nbytes, 1, stderr);
6512 if (cursor_in_echo_area == 0)
6513 fprintf (stderr, "\n");
6514 fflush (stderr);
6515 }
6516 /* A null message buffer means that the frame hasn't really been
6517 initialized yet. Error messages get reported properly by
6518 cmd_error, so this must be just an informative message; toss it. */
6519 else if (INTERACTIVE
6520 && sf->glyphs_initialized_p
6521 && FRAME_MESSAGE_BUF (sf))
6522 {
6523 Lisp_Object mini_window;
6524 struct frame *f;
6525
6526 /* Get the frame containing the mini-buffer
6527 that the selected frame is using. */
6528 mini_window = FRAME_MINIBUF_WINDOW (sf);
6529 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6530
6531 FRAME_SAMPLE_VISIBILITY (f);
6532 if (FRAME_VISIBLE_P (sf)
6533 && ! FRAME_VISIBLE_P (f))
6534 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6535
6536 if (m)
6537 {
6538 set_message (m, Qnil, nbytes, multibyte);
6539 if (minibuffer_auto_raise)
6540 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6541 }
6542 else
6543 clear_message (1, 1);
6544
6545 do_pending_window_change (0);
6546 echo_area_display (1);
6547 do_pending_window_change (0);
6548 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6549 (*frame_up_to_date_hook) (f);
6550 }
6551 }
6552
6553
6554 /* Display an echo area message M with a specified length of NBYTES
6555 bytes. The string may include null characters. If M is not a
6556 string, clear out any existing message, and let the mini-buffer
6557 text show through. */
6558
6559 void
6560 message3 (m, nbytes, multibyte)
6561 Lisp_Object m;
6562 int nbytes;
6563 int multibyte;
6564 {
6565 struct gcpro gcpro1;
6566
6567 GCPRO1 (m);
6568
6569 /* First flush out any partial line written with print. */
6570 message_log_maybe_newline ();
6571 if (STRINGP (m))
6572 message_dolog (SDATA (m), nbytes, 1, multibyte);
6573 message3_nolog (m, nbytes, multibyte);
6574
6575 UNGCPRO;
6576 }
6577
6578
6579 /* The non-logging version of message3. */
6580
6581 void
6582 message3_nolog (m, nbytes, multibyte)
6583 Lisp_Object m;
6584 int nbytes, multibyte;
6585 {
6586 struct frame *sf = SELECTED_FRAME ();
6587 message_enable_multibyte = multibyte;
6588
6589 if (noninteractive)
6590 {
6591 if (noninteractive_need_newline)
6592 putc ('\n', stderr);
6593 noninteractive_need_newline = 0;
6594 if (STRINGP (m))
6595 fwrite (SDATA (m), nbytes, 1, stderr);
6596 if (cursor_in_echo_area == 0)
6597 fprintf (stderr, "\n");
6598 fflush (stderr);
6599 }
6600 /* A null message buffer means that the frame hasn't really been
6601 initialized yet. Error messages get reported properly by
6602 cmd_error, so this must be just an informative message; toss it. */
6603 else if (INTERACTIVE
6604 && sf->glyphs_initialized_p
6605 && FRAME_MESSAGE_BUF (sf))
6606 {
6607 Lisp_Object mini_window;
6608 Lisp_Object frame;
6609 struct frame *f;
6610
6611 /* Get the frame containing the mini-buffer
6612 that the selected frame is using. */
6613 mini_window = FRAME_MINIBUF_WINDOW (sf);
6614 frame = XWINDOW (mini_window)->frame;
6615 f = XFRAME (frame);
6616
6617 FRAME_SAMPLE_VISIBILITY (f);
6618 if (FRAME_VISIBLE_P (sf)
6619 && !FRAME_VISIBLE_P (f))
6620 Fmake_frame_visible (frame);
6621
6622 if (STRINGP (m) && SCHARS (m) > 0)
6623 {
6624 set_message (NULL, m, nbytes, multibyte);
6625 if (minibuffer_auto_raise)
6626 Fraise_frame (frame);
6627 }
6628 else
6629 clear_message (1, 1);
6630
6631 do_pending_window_change (0);
6632 echo_area_display (1);
6633 do_pending_window_change (0);
6634 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6635 (*frame_up_to_date_hook) (f);
6636 }
6637 }
6638
6639
6640 /* Display a null-terminated echo area message M. If M is 0, clear
6641 out any existing message, and let the mini-buffer text show through.
6642
6643 The buffer M must continue to exist until after the echo area gets
6644 cleared or some other message gets displayed there. Do not pass
6645 text that is stored in a Lisp string. Do not pass text in a buffer
6646 that was alloca'd. */
6647
6648 void
6649 message1 (m)
6650 char *m;
6651 {
6652 message2 (m, (m ? strlen (m) : 0), 0);
6653 }
6654
6655
6656 /* The non-logging counterpart of message1. */
6657
6658 void
6659 message1_nolog (m)
6660 char *m;
6661 {
6662 message2_nolog (m, (m ? strlen (m) : 0), 0);
6663 }
6664
6665 /* Display a message M which contains a single %s
6666 which gets replaced with STRING. */
6667
6668 void
6669 message_with_string (m, string, log)
6670 char *m;
6671 Lisp_Object string;
6672 int log;
6673 {
6674 CHECK_STRING (string);
6675
6676 if (noninteractive)
6677 {
6678 if (m)
6679 {
6680 if (noninteractive_need_newline)
6681 putc ('\n', stderr);
6682 noninteractive_need_newline = 0;
6683 fprintf (stderr, m, SDATA (string));
6684 if (cursor_in_echo_area == 0)
6685 fprintf (stderr, "\n");
6686 fflush (stderr);
6687 }
6688 }
6689 else if (INTERACTIVE)
6690 {
6691 /* The frame whose minibuffer we're going to display the message on.
6692 It may be larger than the selected frame, so we need
6693 to use its buffer, not the selected frame's buffer. */
6694 Lisp_Object mini_window;
6695 struct frame *f, *sf = SELECTED_FRAME ();
6696
6697 /* Get the frame containing the minibuffer
6698 that the selected frame is using. */
6699 mini_window = FRAME_MINIBUF_WINDOW (sf);
6700 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6701
6702 /* A null message buffer means that the frame hasn't really been
6703 initialized yet. Error messages get reported properly by
6704 cmd_error, so this must be just an informative message; toss it. */
6705 if (FRAME_MESSAGE_BUF (f))
6706 {
6707 Lisp_Object args[2], message;
6708 struct gcpro gcpro1, gcpro2;
6709
6710 args[0] = build_string (m);
6711 args[1] = message = string;
6712 GCPRO2 (args[0], message);
6713 gcpro1.nvars = 2;
6714
6715 message = Fformat (2, args);
6716
6717 if (log)
6718 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6719 else
6720 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6721
6722 UNGCPRO;
6723
6724 /* Print should start at the beginning of the message
6725 buffer next time. */
6726 message_buf_print = 0;
6727 }
6728 }
6729 }
6730
6731
6732 /* Dump an informative message to the minibuf. If M is 0, clear out
6733 any existing message, and let the mini-buffer text show through. */
6734
6735 /* VARARGS 1 */
6736 void
6737 message (m, a1, a2, a3)
6738 char *m;
6739 EMACS_INT a1, a2, a3;
6740 {
6741 if (noninteractive)
6742 {
6743 if (m)
6744 {
6745 if (noninteractive_need_newline)
6746 putc ('\n', stderr);
6747 noninteractive_need_newline = 0;
6748 fprintf (stderr, m, a1, a2, a3);
6749 if (cursor_in_echo_area == 0)
6750 fprintf (stderr, "\n");
6751 fflush (stderr);
6752 }
6753 }
6754 else if (INTERACTIVE)
6755 {
6756 /* The frame whose mini-buffer we're going to display the message
6757 on. It may be larger than the selected frame, so we need to
6758 use its buffer, not the selected frame's buffer. */
6759 Lisp_Object mini_window;
6760 struct frame *f, *sf = SELECTED_FRAME ();
6761
6762 /* Get the frame containing the mini-buffer
6763 that the selected frame is using. */
6764 mini_window = FRAME_MINIBUF_WINDOW (sf);
6765 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6766
6767 /* A null message buffer means that the frame hasn't really been
6768 initialized yet. Error messages get reported properly by
6769 cmd_error, so this must be just an informative message; toss
6770 it. */
6771 if (FRAME_MESSAGE_BUF (f))
6772 {
6773 if (m)
6774 {
6775 int len;
6776 #ifdef NO_ARG_ARRAY
6777 char *a[3];
6778 a[0] = (char *) a1;
6779 a[1] = (char *) a2;
6780 a[2] = (char *) a3;
6781
6782 len = doprnt (FRAME_MESSAGE_BUF (f),
6783 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6784 #else
6785 len = doprnt (FRAME_MESSAGE_BUF (f),
6786 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6787 (char **) &a1);
6788 #endif /* NO_ARG_ARRAY */
6789
6790 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6791 }
6792 else
6793 message1 (0);
6794
6795 /* Print should start at the beginning of the message
6796 buffer next time. */
6797 message_buf_print = 0;
6798 }
6799 }
6800 }
6801
6802
6803 /* The non-logging version of message. */
6804
6805 void
6806 message_nolog (m, a1, a2, a3)
6807 char *m;
6808 EMACS_INT a1, a2, a3;
6809 {
6810 Lisp_Object old_log_max;
6811 old_log_max = Vmessage_log_max;
6812 Vmessage_log_max = Qnil;
6813 message (m, a1, a2, a3);
6814 Vmessage_log_max = old_log_max;
6815 }
6816
6817
6818 /* Display the current message in the current mini-buffer. This is
6819 only called from error handlers in process.c, and is not time
6820 critical. */
6821
6822 void
6823 update_echo_area ()
6824 {
6825 if (!NILP (echo_area_buffer[0]))
6826 {
6827 Lisp_Object string;
6828 string = Fcurrent_message ();
6829 message3 (string, SBYTES (string),
6830 !NILP (current_buffer->enable_multibyte_characters));
6831 }
6832 }
6833
6834
6835 /* Make sure echo area buffers in `echo_buffers' are live.
6836 If they aren't, make new ones. */
6837
6838 static void
6839 ensure_echo_area_buffers ()
6840 {
6841 int i;
6842
6843 for (i = 0; i < 2; ++i)
6844 if (!BUFFERP (echo_buffer[i])
6845 || NILP (XBUFFER (echo_buffer[i])->name))
6846 {
6847 char name[30];
6848 Lisp_Object old_buffer;
6849 int j;
6850
6851 old_buffer = echo_buffer[i];
6852 sprintf (name, " *Echo Area %d*", i);
6853 echo_buffer[i] = Fget_buffer_create (build_string (name));
6854 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6855
6856 for (j = 0; j < 2; ++j)
6857 if (EQ (old_buffer, echo_area_buffer[j]))
6858 echo_area_buffer[j] = echo_buffer[i];
6859 }
6860 }
6861
6862
6863 /* Call FN with args A1..A4 with either the current or last displayed
6864 echo_area_buffer as current buffer.
6865
6866 WHICH zero means use the current message buffer
6867 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6868 from echo_buffer[] and clear it.
6869
6870 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6871 suitable buffer from echo_buffer[] and clear it.
6872
6873 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6874 that the current message becomes the last displayed one, make
6875 choose a suitable buffer for echo_area_buffer[0], and clear it.
6876
6877 Value is what FN returns. */
6878
6879 static int
6880 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6881 struct window *w;
6882 int which;
6883 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6884 EMACS_INT a1;
6885 Lisp_Object a2;
6886 EMACS_INT a3, a4;
6887 {
6888 Lisp_Object buffer;
6889 int this_one, the_other, clear_buffer_p, rc;
6890 int count = SPECPDL_INDEX ();
6891
6892 /* If buffers aren't live, make new ones. */
6893 ensure_echo_area_buffers ();
6894
6895 clear_buffer_p = 0;
6896
6897 if (which == 0)
6898 this_one = 0, the_other = 1;
6899 else if (which > 0)
6900 this_one = 1, the_other = 0;
6901 else
6902 {
6903 this_one = 0, the_other = 1;
6904 clear_buffer_p = 1;
6905
6906 /* We need a fresh one in case the current echo buffer equals
6907 the one containing the last displayed echo area message. */
6908 if (!NILP (echo_area_buffer[this_one])
6909 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6910 echo_area_buffer[this_one] = Qnil;
6911 }
6912
6913 /* Choose a suitable buffer from echo_buffer[] is we don't
6914 have one. */
6915 if (NILP (echo_area_buffer[this_one]))
6916 {
6917 echo_area_buffer[this_one]
6918 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6919 ? echo_buffer[the_other]
6920 : echo_buffer[this_one]);
6921 clear_buffer_p = 1;
6922 }
6923
6924 buffer = echo_area_buffer[this_one];
6925
6926 /* Don't get confused by reusing the buffer used for echoing
6927 for a different purpose. */
6928 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6929 cancel_echoing ();
6930
6931 record_unwind_protect (unwind_with_echo_area_buffer,
6932 with_echo_area_buffer_unwind_data (w));
6933
6934 /* Make the echo area buffer current. Note that for display
6935 purposes, it is not necessary that the displayed window's buffer
6936 == current_buffer, except for text property lookup. So, let's
6937 only set that buffer temporarily here without doing a full
6938 Fset_window_buffer. We must also change w->pointm, though,
6939 because otherwise an assertions in unshow_buffer fails, and Emacs
6940 aborts. */
6941 set_buffer_internal_1 (XBUFFER (buffer));
6942 if (w)
6943 {
6944 w->buffer = buffer;
6945 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6946 }
6947
6948 current_buffer->undo_list = Qt;
6949 current_buffer->read_only = Qnil;
6950 specbind (Qinhibit_read_only, Qt);
6951 specbind (Qinhibit_modification_hooks, Qt);
6952
6953 if (clear_buffer_p && Z > BEG)
6954 del_range (BEG, Z);
6955
6956 xassert (BEGV >= BEG);
6957 xassert (ZV <= Z && ZV >= BEGV);
6958
6959 rc = fn (a1, a2, a3, a4);
6960
6961 xassert (BEGV >= BEG);
6962 xassert (ZV <= Z && ZV >= BEGV);
6963
6964 unbind_to (count, Qnil);
6965 return rc;
6966 }
6967
6968
6969 /* Save state that should be preserved around the call to the function
6970 FN called in with_echo_area_buffer. */
6971
6972 static Lisp_Object
6973 with_echo_area_buffer_unwind_data (w)
6974 struct window *w;
6975 {
6976 int i = 0;
6977 Lisp_Object vector;
6978
6979 /* Reduce consing by keeping one vector in
6980 Vwith_echo_area_save_vector. */
6981 vector = Vwith_echo_area_save_vector;
6982 Vwith_echo_area_save_vector = Qnil;
6983
6984 if (NILP (vector))
6985 vector = Fmake_vector (make_number (7), Qnil);
6986
6987 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6988 AREF (vector, i) = Vdeactivate_mark, ++i;
6989 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6990
6991 if (w)
6992 {
6993 XSETWINDOW (AREF (vector, i), w); ++i;
6994 AREF (vector, i) = w->buffer; ++i;
6995 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6996 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6997 }
6998 else
6999 {
7000 int end = i + 4;
7001 for (; i < end; ++i)
7002 AREF (vector, i) = Qnil;
7003 }
7004
7005 xassert (i == ASIZE (vector));
7006 return vector;
7007 }
7008
7009
7010 /* Restore global state from VECTOR which was created by
7011 with_echo_area_buffer_unwind_data. */
7012
7013 static Lisp_Object
7014 unwind_with_echo_area_buffer (vector)
7015 Lisp_Object vector;
7016 {
7017 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7018 Vdeactivate_mark = AREF (vector, 1);
7019 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7020
7021 if (WINDOWP (AREF (vector, 3)))
7022 {
7023 struct window *w;
7024 Lisp_Object buffer, charpos, bytepos;
7025
7026 w = XWINDOW (AREF (vector, 3));
7027 buffer = AREF (vector, 4);
7028 charpos = AREF (vector, 5);
7029 bytepos = AREF (vector, 6);
7030
7031 w->buffer = buffer;
7032 set_marker_both (w->pointm, buffer,
7033 XFASTINT (charpos), XFASTINT (bytepos));
7034 }
7035
7036 Vwith_echo_area_save_vector = vector;
7037 return Qnil;
7038 }
7039
7040
7041 /* Set up the echo area for use by print functions. MULTIBYTE_P
7042 non-zero means we will print multibyte. */
7043
7044 void
7045 setup_echo_area_for_printing (multibyte_p)
7046 int multibyte_p;
7047 {
7048 /* If we can't find an echo area any more, exit. */
7049 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7050 Fkill_emacs (Qnil);
7051
7052 ensure_echo_area_buffers ();
7053
7054 if (!message_buf_print)
7055 {
7056 /* A message has been output since the last time we printed.
7057 Choose a fresh echo area buffer. */
7058 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7059 echo_area_buffer[0] = echo_buffer[1];
7060 else
7061 echo_area_buffer[0] = echo_buffer[0];
7062
7063 /* Switch to that buffer and clear it. */
7064 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7065 current_buffer->truncate_lines = Qnil;
7066
7067 if (Z > BEG)
7068 {
7069 int count = SPECPDL_INDEX ();
7070 specbind (Qinhibit_read_only, Qt);
7071 /* Note that undo recording is always disabled. */
7072 del_range (BEG, Z);
7073 unbind_to (count, Qnil);
7074 }
7075 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7076
7077 /* Set up the buffer for the multibyteness we need. */
7078 if (multibyte_p
7079 != !NILP (current_buffer->enable_multibyte_characters))
7080 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7081
7082 /* Raise the frame containing the echo area. */
7083 if (minibuffer_auto_raise)
7084 {
7085 struct frame *sf = SELECTED_FRAME ();
7086 Lisp_Object mini_window;
7087 mini_window = FRAME_MINIBUF_WINDOW (sf);
7088 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7089 }
7090
7091 message_log_maybe_newline ();
7092 message_buf_print = 1;
7093 }
7094 else
7095 {
7096 if (NILP (echo_area_buffer[0]))
7097 {
7098 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7099 echo_area_buffer[0] = echo_buffer[1];
7100 else
7101 echo_area_buffer[0] = echo_buffer[0];
7102 }
7103
7104 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7105 {
7106 /* Someone switched buffers between print requests. */
7107 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7108 current_buffer->truncate_lines = Qnil;
7109 }
7110 }
7111 }
7112
7113
7114 /* Display an echo area message in window W. Value is non-zero if W's
7115 height is changed. If display_last_displayed_message_p is
7116 non-zero, display the message that was last displayed, otherwise
7117 display the current message. */
7118
7119 static int
7120 display_echo_area (w)
7121 struct window *w;
7122 {
7123 int i, no_message_p, window_height_changed_p, count;
7124
7125 /* Temporarily disable garbage collections while displaying the echo
7126 area. This is done because a GC can print a message itself.
7127 That message would modify the echo area buffer's contents while a
7128 redisplay of the buffer is going on, and seriously confuse
7129 redisplay. */
7130 count = inhibit_garbage_collection ();
7131
7132 /* If there is no message, we must call display_echo_area_1
7133 nevertheless because it resizes the window. But we will have to
7134 reset the echo_area_buffer in question to nil at the end because
7135 with_echo_area_buffer will sets it to an empty buffer. */
7136 i = display_last_displayed_message_p ? 1 : 0;
7137 no_message_p = NILP (echo_area_buffer[i]);
7138
7139 window_height_changed_p
7140 = with_echo_area_buffer (w, display_last_displayed_message_p,
7141 display_echo_area_1,
7142 (EMACS_INT) w, Qnil, 0, 0);
7143
7144 if (no_message_p)
7145 echo_area_buffer[i] = Qnil;
7146
7147 unbind_to (count, Qnil);
7148 return window_height_changed_p;
7149 }
7150
7151
7152 /* Helper for display_echo_area. Display the current buffer which
7153 contains the current echo area message in window W, a mini-window,
7154 a pointer to which is passed in A1. A2..A4 are currently not used.
7155 Change the height of W so that all of the message is displayed.
7156 Value is non-zero if height of W was changed. */
7157
7158 static int
7159 display_echo_area_1 (a1, a2, a3, a4)
7160 EMACS_INT a1;
7161 Lisp_Object a2;
7162 EMACS_INT a3, a4;
7163 {
7164 struct window *w = (struct window *) a1;
7165 Lisp_Object window;
7166 struct text_pos start;
7167 int window_height_changed_p = 0;
7168
7169 /* Do this before displaying, so that we have a large enough glyph
7170 matrix for the display. */
7171 window_height_changed_p = resize_mini_window (w, 0);
7172
7173 /* Display. */
7174 clear_glyph_matrix (w->desired_matrix);
7175 XSETWINDOW (window, w);
7176 SET_TEXT_POS (start, BEG, BEG_BYTE);
7177 try_window (window, start);
7178
7179 return window_height_changed_p;
7180 }
7181
7182
7183 /* Resize the echo area window to exactly the size needed for the
7184 currently displayed message, if there is one. If a mini-buffer
7185 is active, don't shrink it. */
7186
7187 void
7188 resize_echo_area_exactly ()
7189 {
7190 if (BUFFERP (echo_area_buffer[0])
7191 && WINDOWP (echo_area_window))
7192 {
7193 struct window *w = XWINDOW (echo_area_window);
7194 int resized_p;
7195 Lisp_Object resize_exactly;
7196
7197 if (minibuf_level == 0)
7198 resize_exactly = Qt;
7199 else
7200 resize_exactly = Qnil;
7201
7202 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7203 (EMACS_INT) w, resize_exactly, 0, 0);
7204 if (resized_p)
7205 {
7206 ++windows_or_buffers_changed;
7207 ++update_mode_lines;
7208 redisplay_internal (0);
7209 }
7210 }
7211 }
7212
7213
7214 /* Callback function for with_echo_area_buffer, when used from
7215 resize_echo_area_exactly. A1 contains a pointer to the window to
7216 resize, EXACTLY non-nil means resize the mini-window exactly to the
7217 size of the text displayed. A3 and A4 are not used. Value is what
7218 resize_mini_window returns. */
7219
7220 static int
7221 resize_mini_window_1 (a1, exactly, a3, a4)
7222 EMACS_INT a1;
7223 Lisp_Object exactly;
7224 EMACS_INT a3, a4;
7225 {
7226 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7227 }
7228
7229
7230 /* Resize mini-window W to fit the size of its contents. EXACT:P
7231 means size the window exactly to the size needed. Otherwise, it's
7232 only enlarged until W's buffer is empty. Value is non-zero if
7233 the window height has been changed. */
7234
7235 int
7236 resize_mini_window (w, exact_p)
7237 struct window *w;
7238 int exact_p;
7239 {
7240 struct frame *f = XFRAME (w->frame);
7241 int window_height_changed_p = 0;
7242
7243 xassert (MINI_WINDOW_P (w));
7244
7245 /* Don't resize windows while redisplaying a window; it would
7246 confuse redisplay functions when the size of the window they are
7247 displaying changes from under them. Such a resizing can happen,
7248 for instance, when which-func prints a long message while
7249 we are running fontification-functions. We're running these
7250 functions with safe_call which binds inhibit-redisplay to t. */
7251 if (!NILP (Vinhibit_redisplay))
7252 return 0;
7253
7254 /* Nil means don't try to resize. */
7255 if (NILP (Vresize_mini_windows)
7256 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7257 return 0;
7258
7259 if (!FRAME_MINIBUF_ONLY_P (f))
7260 {
7261 struct it it;
7262 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7263 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7264 int height, max_height;
7265 int unit = FRAME_LINE_HEIGHT (f);
7266 struct text_pos start;
7267 struct buffer *old_current_buffer = NULL;
7268
7269 if (current_buffer != XBUFFER (w->buffer))
7270 {
7271 old_current_buffer = current_buffer;
7272 set_buffer_internal (XBUFFER (w->buffer));
7273 }
7274
7275 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7276
7277 /* Compute the max. number of lines specified by the user. */
7278 if (FLOATP (Vmax_mini_window_height))
7279 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7280 else if (INTEGERP (Vmax_mini_window_height))
7281 max_height = XINT (Vmax_mini_window_height);
7282 else
7283 max_height = total_height / 4;
7284
7285 /* Correct that max. height if it's bogus. */
7286 max_height = max (1, max_height);
7287 max_height = min (total_height, max_height);
7288
7289 /* Find out the height of the text in the window. */
7290 if (it.truncate_lines_p)
7291 height = 1;
7292 else
7293 {
7294 last_height = 0;
7295 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7296 if (it.max_ascent == 0 && it.max_descent == 0)
7297 height = it.current_y + last_height;
7298 else
7299 height = it.current_y + it.max_ascent + it.max_descent;
7300 height -= it.extra_line_spacing;
7301 height = (height + unit - 1) / unit;
7302 }
7303
7304 /* Compute a suitable window start. */
7305 if (height > max_height)
7306 {
7307 height = max_height;
7308 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7309 move_it_vertically_backward (&it, (height - 1) * unit);
7310 start = it.current.pos;
7311 }
7312 else
7313 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7314 SET_MARKER_FROM_TEXT_POS (w->start, start);
7315
7316 if (EQ (Vresize_mini_windows, Qgrow_only))
7317 {
7318 /* Let it grow only, until we display an empty message, in which
7319 case the window shrinks again. */
7320 if (height > WINDOW_TOTAL_LINES (w))
7321 {
7322 int old_height = WINDOW_TOTAL_LINES (w);
7323 freeze_window_starts (f, 1);
7324 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7325 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7326 }
7327 else if (height < WINDOW_TOTAL_LINES (w)
7328 && (exact_p || BEGV == ZV))
7329 {
7330 int old_height = WINDOW_TOTAL_LINES (w);
7331 freeze_window_starts (f, 0);
7332 shrink_mini_window (w);
7333 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7334 }
7335 }
7336 else
7337 {
7338 /* Always resize to exact size needed. */
7339 if (height > WINDOW_TOTAL_LINES (w))
7340 {
7341 int old_height = WINDOW_TOTAL_LINES (w);
7342 freeze_window_starts (f, 1);
7343 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7344 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7345 }
7346 else if (height < WINDOW_TOTAL_LINES (w))
7347 {
7348 int old_height = WINDOW_TOTAL_LINES (w);
7349 freeze_window_starts (f, 0);
7350 shrink_mini_window (w);
7351
7352 if (height)
7353 {
7354 freeze_window_starts (f, 1);
7355 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7356 }
7357
7358 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7359 }
7360 }
7361
7362 if (old_current_buffer)
7363 set_buffer_internal (old_current_buffer);
7364 }
7365
7366 return window_height_changed_p;
7367 }
7368
7369
7370 /* Value is the current message, a string, or nil if there is no
7371 current message. */
7372
7373 Lisp_Object
7374 current_message ()
7375 {
7376 Lisp_Object msg;
7377
7378 if (NILP (echo_area_buffer[0]))
7379 msg = Qnil;
7380 else
7381 {
7382 with_echo_area_buffer (0, 0, current_message_1,
7383 (EMACS_INT) &msg, Qnil, 0, 0);
7384 if (NILP (msg))
7385 echo_area_buffer[0] = Qnil;
7386 }
7387
7388 return msg;
7389 }
7390
7391
7392 static int
7393 current_message_1 (a1, a2, a3, a4)
7394 EMACS_INT a1;
7395 Lisp_Object a2;
7396 EMACS_INT a3, a4;
7397 {
7398 Lisp_Object *msg = (Lisp_Object *) a1;
7399
7400 if (Z > BEG)
7401 *msg = make_buffer_string (BEG, Z, 1);
7402 else
7403 *msg = Qnil;
7404 return 0;
7405 }
7406
7407
7408 /* Push the current message on Vmessage_stack for later restauration
7409 by restore_message. Value is non-zero if the current message isn't
7410 empty. This is a relatively infrequent operation, so it's not
7411 worth optimizing. */
7412
7413 int
7414 push_message ()
7415 {
7416 Lisp_Object msg;
7417 msg = current_message ();
7418 Vmessage_stack = Fcons (msg, Vmessage_stack);
7419 return STRINGP (msg);
7420 }
7421
7422
7423 /* Restore message display from the top of Vmessage_stack. */
7424
7425 void
7426 restore_message ()
7427 {
7428 Lisp_Object msg;
7429
7430 xassert (CONSP (Vmessage_stack));
7431 msg = XCAR (Vmessage_stack);
7432 if (STRINGP (msg))
7433 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7434 else
7435 message3_nolog (msg, 0, 0);
7436 }
7437
7438
7439 /* Handler for record_unwind_protect calling pop_message. */
7440
7441 Lisp_Object
7442 pop_message_unwind (dummy)
7443 Lisp_Object dummy;
7444 {
7445 pop_message ();
7446 return Qnil;
7447 }
7448
7449 /* Pop the top-most entry off Vmessage_stack. */
7450
7451 void
7452 pop_message ()
7453 {
7454 xassert (CONSP (Vmessage_stack));
7455 Vmessage_stack = XCDR (Vmessage_stack);
7456 }
7457
7458
7459 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7460 exits. If the stack is not empty, we have a missing pop_message
7461 somewhere. */
7462
7463 void
7464 check_message_stack ()
7465 {
7466 if (!NILP (Vmessage_stack))
7467 abort ();
7468 }
7469
7470
7471 /* Truncate to NCHARS what will be displayed in the echo area the next
7472 time we display it---but don't redisplay it now. */
7473
7474 void
7475 truncate_echo_area (nchars)
7476 int nchars;
7477 {
7478 if (nchars == 0)
7479 echo_area_buffer[0] = Qnil;
7480 /* A null message buffer means that the frame hasn't really been
7481 initialized yet. Error messages get reported properly by
7482 cmd_error, so this must be just an informative message; toss it. */
7483 else if (!noninteractive
7484 && INTERACTIVE
7485 && !NILP (echo_area_buffer[0]))
7486 {
7487 struct frame *sf = SELECTED_FRAME ();
7488 if (FRAME_MESSAGE_BUF (sf))
7489 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7490 }
7491 }
7492
7493
7494 /* Helper function for truncate_echo_area. Truncate the current
7495 message to at most NCHARS characters. */
7496
7497 static int
7498 truncate_message_1 (nchars, a2, a3, a4)
7499 EMACS_INT nchars;
7500 Lisp_Object a2;
7501 EMACS_INT a3, a4;
7502 {
7503 if (BEG + nchars < Z)
7504 del_range (BEG + nchars, Z);
7505 if (Z == BEG)
7506 echo_area_buffer[0] = Qnil;
7507 return 0;
7508 }
7509
7510
7511 /* Set the current message to a substring of S or STRING.
7512
7513 If STRING is a Lisp string, set the message to the first NBYTES
7514 bytes from STRING. NBYTES zero means use the whole string. If
7515 STRING is multibyte, the message will be displayed multibyte.
7516
7517 If S is not null, set the message to the first LEN bytes of S. LEN
7518 zero means use the whole string. MULTIBYTE_P non-zero means S is
7519 multibyte. Display the message multibyte in that case. */
7520
7521 void
7522 set_message (s, string, nbytes, multibyte_p)
7523 const char *s;
7524 Lisp_Object string;
7525 int nbytes, multibyte_p;
7526 {
7527 message_enable_multibyte
7528 = ((s && multibyte_p)
7529 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7530
7531 with_echo_area_buffer (0, -1, set_message_1,
7532 (EMACS_INT) s, string, nbytes, multibyte_p);
7533 message_buf_print = 0;
7534 help_echo_showing_p = 0;
7535 }
7536
7537
7538 /* Helper function for set_message. Arguments have the same meaning
7539 as there, with A1 corresponding to S and A2 corresponding to STRING
7540 This function is called with the echo area buffer being
7541 current. */
7542
7543 static int
7544 set_message_1 (a1, a2, nbytes, multibyte_p)
7545 EMACS_INT a1;
7546 Lisp_Object a2;
7547 EMACS_INT nbytes, multibyte_p;
7548 {
7549 const char *s = (const char *) a1;
7550 Lisp_Object string = a2;
7551
7552 xassert (BEG == Z);
7553
7554 /* Change multibyteness of the echo buffer appropriately. */
7555 if (message_enable_multibyte
7556 != !NILP (current_buffer->enable_multibyte_characters))
7557 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7558
7559 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7560
7561 /* Insert new message at BEG. */
7562 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7563
7564 if (STRINGP (string))
7565 {
7566 int nchars;
7567
7568 if (nbytes == 0)
7569 nbytes = SBYTES (string);
7570 nchars = string_byte_to_char (string, nbytes);
7571
7572 /* This function takes care of single/multibyte conversion. We
7573 just have to ensure that the echo area buffer has the right
7574 setting of enable_multibyte_characters. */
7575 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7576 }
7577 else if (s)
7578 {
7579 if (nbytes == 0)
7580 nbytes = strlen (s);
7581
7582 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7583 {
7584 /* Convert from multi-byte to single-byte. */
7585 int i, c, n;
7586 unsigned char work[1];
7587
7588 /* Convert a multibyte string to single-byte. */
7589 for (i = 0; i < nbytes; i += n)
7590 {
7591 c = string_char_and_length (s + i, nbytes - i, &n);
7592 work[0] = (ASCII_CHAR_P (c)
7593 ? c
7594 : multibyte_char_to_unibyte (c, Qnil));
7595 insert_1_both (work, 1, 1, 1, 0, 0);
7596 }
7597 }
7598 else if (!multibyte_p
7599 && !NILP (current_buffer->enable_multibyte_characters))
7600 {
7601 /* Convert from single-byte to multi-byte. */
7602 int i, c, n;
7603 const unsigned char *msg = (const unsigned char *) s;
7604 unsigned char str[MAX_MULTIBYTE_LENGTH];
7605
7606 /* Convert a single-byte string to multibyte. */
7607 for (i = 0; i < nbytes; i++)
7608 {
7609 c = unibyte_char_to_multibyte (msg[i]);
7610 n = CHAR_STRING (c, str);
7611 insert_1_both (str, 1, n, 1, 0, 0);
7612 }
7613 }
7614 else
7615 insert_1 (s, nbytes, 1, 0, 0);
7616 }
7617
7618 return 0;
7619 }
7620
7621
7622 /* Clear messages. CURRENT_P non-zero means clear the current
7623 message. LAST_DISPLAYED_P non-zero means clear the message
7624 last displayed. */
7625
7626 void
7627 clear_message (current_p, last_displayed_p)
7628 int current_p, last_displayed_p;
7629 {
7630 if (current_p)
7631 {
7632 echo_area_buffer[0] = Qnil;
7633 message_cleared_p = 1;
7634 }
7635
7636 if (last_displayed_p)
7637 echo_area_buffer[1] = Qnil;
7638
7639 message_buf_print = 0;
7640 }
7641
7642 /* Clear garbaged frames.
7643
7644 This function is used where the old redisplay called
7645 redraw_garbaged_frames which in turn called redraw_frame which in
7646 turn called clear_frame. The call to clear_frame was a source of
7647 flickering. I believe a clear_frame is not necessary. It should
7648 suffice in the new redisplay to invalidate all current matrices,
7649 and ensure a complete redisplay of all windows. */
7650
7651 static void
7652 clear_garbaged_frames ()
7653 {
7654 if (frame_garbaged)
7655 {
7656 Lisp_Object tail, frame;
7657 int changed_count = 0;
7658
7659 FOR_EACH_FRAME (tail, frame)
7660 {
7661 struct frame *f = XFRAME (frame);
7662
7663 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7664 {
7665 if (f->resized_p)
7666 Fredraw_frame (frame);
7667 clear_current_matrices (f);
7668 changed_count++;
7669 f->garbaged = 0;
7670 f->resized_p = 0;
7671 }
7672 }
7673
7674 frame_garbaged = 0;
7675 if (changed_count)
7676 ++windows_or_buffers_changed;
7677 }
7678 }
7679
7680
7681 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7682 is non-zero update selected_frame. Value is non-zero if the
7683 mini-windows height has been changed. */
7684
7685 static int
7686 echo_area_display (update_frame_p)
7687 int update_frame_p;
7688 {
7689 Lisp_Object mini_window;
7690 struct window *w;
7691 struct frame *f;
7692 int window_height_changed_p = 0;
7693 struct frame *sf = SELECTED_FRAME ();
7694
7695 mini_window = FRAME_MINIBUF_WINDOW (sf);
7696 w = XWINDOW (mini_window);
7697 f = XFRAME (WINDOW_FRAME (w));
7698
7699 /* Don't display if frame is invisible or not yet initialized. */
7700 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7701 return 0;
7702
7703 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7704 #ifndef MAC_OS8
7705 #ifdef HAVE_WINDOW_SYSTEM
7706 /* When Emacs starts, selected_frame may be a visible terminal
7707 frame, even if we run under a window system. If we let this
7708 through, a message would be displayed on the terminal. */
7709 if (EQ (selected_frame, Vterminal_frame)
7710 && !NILP (Vwindow_system))
7711 return 0;
7712 #endif /* HAVE_WINDOW_SYSTEM */
7713 #endif
7714
7715 /* Redraw garbaged frames. */
7716 if (frame_garbaged)
7717 clear_garbaged_frames ();
7718
7719 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7720 {
7721 echo_area_window = mini_window;
7722 window_height_changed_p = display_echo_area (w);
7723 w->must_be_updated_p = 1;
7724
7725 /* Update the display, unless called from redisplay_internal.
7726 Also don't update the screen during redisplay itself. The
7727 update will happen at the end of redisplay, and an update
7728 here could cause confusion. */
7729 if (update_frame_p && !redisplaying_p)
7730 {
7731 int n = 0;
7732
7733 /* If the display update has been interrupted by pending
7734 input, update mode lines in the frame. Due to the
7735 pending input, it might have been that redisplay hasn't
7736 been called, so that mode lines above the echo area are
7737 garbaged. This looks odd, so we prevent it here. */
7738 if (!display_completed)
7739 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7740
7741 if (window_height_changed_p
7742 /* Don't do this if Emacs is shutting down. Redisplay
7743 needs to run hooks. */
7744 && !NILP (Vrun_hooks))
7745 {
7746 /* Must update other windows. Likewise as in other
7747 cases, don't let this update be interrupted by
7748 pending input. */
7749 int count = SPECPDL_INDEX ();
7750 specbind (Qredisplay_dont_pause, Qt);
7751 windows_or_buffers_changed = 1;
7752 redisplay_internal (0);
7753 unbind_to (count, Qnil);
7754 }
7755 else if (FRAME_WINDOW_P (f) && n == 0)
7756 {
7757 /* Window configuration is the same as before.
7758 Can do with a display update of the echo area,
7759 unless we displayed some mode lines. */
7760 update_single_window (w, 1);
7761 rif->flush_display (f);
7762 }
7763 else
7764 update_frame (f, 1, 1);
7765
7766 /* If cursor is in the echo area, make sure that the next
7767 redisplay displays the minibuffer, so that the cursor will
7768 be replaced with what the minibuffer wants. */
7769 if (cursor_in_echo_area)
7770 ++windows_or_buffers_changed;
7771 }
7772 }
7773 else if (!EQ (mini_window, selected_window))
7774 windows_or_buffers_changed++;
7775
7776 /* Last displayed message is now the current message. */
7777 echo_area_buffer[1] = echo_area_buffer[0];
7778
7779 /* Prevent redisplay optimization in redisplay_internal by resetting
7780 this_line_start_pos. This is done because the mini-buffer now
7781 displays the message instead of its buffer text. */
7782 if (EQ (mini_window, selected_window))
7783 CHARPOS (this_line_start_pos) = 0;
7784
7785 return window_height_changed_p;
7786 }
7787
7788
7789 \f
7790 /***********************************************************************
7791 Frame Titles
7792 ***********************************************************************/
7793
7794
7795 /* The frame title buffering code is also used by Fformat_mode_line.
7796 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7797
7798 /* A buffer for constructing frame titles in it; allocated from the
7799 heap in init_xdisp and resized as needed in store_frame_title_char. */
7800
7801 static char *frame_title_buf;
7802
7803 /* The buffer's end, and a current output position in it. */
7804
7805 static char *frame_title_buf_end;
7806 static char *frame_title_ptr;
7807
7808
7809 /* Store a single character C for the frame title in frame_title_buf.
7810 Re-allocate frame_title_buf if necessary. */
7811
7812 static void
7813 #ifdef PROTOTYPES
7814 store_frame_title_char (char c)
7815 #else
7816 store_frame_title_char (c)
7817 char c;
7818 #endif
7819 {
7820 /* If output position has reached the end of the allocated buffer,
7821 double the buffer's size. */
7822 if (frame_title_ptr == frame_title_buf_end)
7823 {
7824 int len = frame_title_ptr - frame_title_buf;
7825 int new_size = 2 * len * sizeof *frame_title_buf;
7826 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7827 frame_title_buf_end = frame_title_buf + new_size;
7828 frame_title_ptr = frame_title_buf + len;
7829 }
7830
7831 *frame_title_ptr++ = c;
7832 }
7833
7834
7835 /* Store part of a frame title in frame_title_buf, beginning at
7836 frame_title_ptr. STR is the string to store. Do not copy
7837 characters that yield more columns than PRECISION; PRECISION <= 0
7838 means copy the whole string. Pad with spaces until FIELD_WIDTH
7839 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7840 pad. Called from display_mode_element when it is used to build a
7841 frame title. */
7842
7843 static int
7844 store_frame_title (str, field_width, precision)
7845 const unsigned char *str;
7846 int field_width, precision;
7847 {
7848 int n = 0;
7849 int dummy, nbytes;
7850
7851 /* Copy at most PRECISION chars from STR. */
7852 nbytes = strlen (str);
7853 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7854 while (nbytes--)
7855 store_frame_title_char (*str++);
7856
7857 /* Fill up with spaces until FIELD_WIDTH reached. */
7858 while (field_width > 0
7859 && n < field_width)
7860 {
7861 store_frame_title_char (' ');
7862 ++n;
7863 }
7864
7865 return n;
7866 }
7867
7868 #ifdef HAVE_WINDOW_SYSTEM
7869
7870 /* Set the title of FRAME, if it has changed. The title format is
7871 Vicon_title_format if FRAME is iconified, otherwise it is
7872 frame_title_format. */
7873
7874 static void
7875 x_consider_frame_title (frame)
7876 Lisp_Object frame;
7877 {
7878 struct frame *f = XFRAME (frame);
7879
7880 if (FRAME_WINDOW_P (f)
7881 || FRAME_MINIBUF_ONLY_P (f)
7882 || f->explicit_name)
7883 {
7884 /* Do we have more than one visible frame on this X display? */
7885 Lisp_Object tail;
7886 Lisp_Object fmt;
7887 struct buffer *obuf;
7888 int len;
7889 struct it it;
7890
7891 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7892 {
7893 Lisp_Object other_frame = XCAR (tail);
7894 struct frame *tf = XFRAME (other_frame);
7895
7896 if (tf != f
7897 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7898 && !FRAME_MINIBUF_ONLY_P (tf)
7899 && !EQ (other_frame, tip_frame)
7900 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7901 break;
7902 }
7903
7904 /* Set global variable indicating that multiple frames exist. */
7905 multiple_frames = CONSP (tail);
7906
7907 /* Switch to the buffer of selected window of the frame. Set up
7908 frame_title_ptr so that display_mode_element will output into it;
7909 then display the title. */
7910 obuf = current_buffer;
7911 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7912 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7913 frame_title_ptr = frame_title_buf;
7914 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7915 NULL, DEFAULT_FACE_ID);
7916 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7917 len = frame_title_ptr - frame_title_buf;
7918 frame_title_ptr = NULL;
7919 set_buffer_internal_1 (obuf);
7920
7921 /* Set the title only if it's changed. This avoids consing in
7922 the common case where it hasn't. (If it turns out that we've
7923 already wasted too much time by walking through the list with
7924 display_mode_element, then we might need to optimize at a
7925 higher level than this.) */
7926 if (! STRINGP (f->name)
7927 || SBYTES (f->name) != len
7928 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7929 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7930 }
7931 }
7932
7933 #endif /* not HAVE_WINDOW_SYSTEM */
7934
7935
7936
7937 \f
7938 /***********************************************************************
7939 Menu Bars
7940 ***********************************************************************/
7941
7942
7943 /* Prepare for redisplay by updating menu-bar item lists when
7944 appropriate. This can call eval. */
7945
7946 void
7947 prepare_menu_bars ()
7948 {
7949 int all_windows;
7950 struct gcpro gcpro1, gcpro2;
7951 struct frame *f;
7952 Lisp_Object tooltip_frame;
7953
7954 #ifdef HAVE_WINDOW_SYSTEM
7955 tooltip_frame = tip_frame;
7956 #else
7957 tooltip_frame = Qnil;
7958 #endif
7959
7960 /* Update all frame titles based on their buffer names, etc. We do
7961 this before the menu bars so that the buffer-menu will show the
7962 up-to-date frame titles. */
7963 #ifdef HAVE_WINDOW_SYSTEM
7964 if (windows_or_buffers_changed || update_mode_lines)
7965 {
7966 Lisp_Object tail, frame;
7967
7968 FOR_EACH_FRAME (tail, frame)
7969 {
7970 f = XFRAME (frame);
7971 if (!EQ (frame, tooltip_frame)
7972 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
7973 x_consider_frame_title (frame);
7974 }
7975 }
7976 #endif /* HAVE_WINDOW_SYSTEM */
7977
7978 /* Update the menu bar item lists, if appropriate. This has to be
7979 done before any actual redisplay or generation of display lines. */
7980 all_windows = (update_mode_lines
7981 || buffer_shared > 1
7982 || windows_or_buffers_changed);
7983 if (all_windows)
7984 {
7985 Lisp_Object tail, frame;
7986 int count = SPECPDL_INDEX ();
7987
7988 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7989
7990 FOR_EACH_FRAME (tail, frame)
7991 {
7992 f = XFRAME (frame);
7993
7994 /* Ignore tooltip frame. */
7995 if (EQ (frame, tooltip_frame))
7996 continue;
7997
7998 /* If a window on this frame changed size, report that to
7999 the user and clear the size-change flag. */
8000 if (FRAME_WINDOW_SIZES_CHANGED (f))
8001 {
8002 Lisp_Object functions;
8003
8004 /* Clear flag first in case we get an error below. */
8005 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8006 functions = Vwindow_size_change_functions;
8007 GCPRO2 (tail, functions);
8008
8009 while (CONSP (functions))
8010 {
8011 call1 (XCAR (functions), frame);
8012 functions = XCDR (functions);
8013 }
8014 UNGCPRO;
8015 }
8016
8017 GCPRO1 (tail);
8018 update_menu_bar (f, 0);
8019 #ifdef HAVE_WINDOW_SYSTEM
8020 update_tool_bar (f, 0);
8021 #endif
8022 UNGCPRO;
8023 }
8024
8025 unbind_to (count, Qnil);
8026 }
8027 else
8028 {
8029 struct frame *sf = SELECTED_FRAME ();
8030 update_menu_bar (sf, 1);
8031 #ifdef HAVE_WINDOW_SYSTEM
8032 update_tool_bar (sf, 1);
8033 #endif
8034 }
8035
8036 /* Motif needs this. See comment in xmenu.c. Turn it off when
8037 pending_menu_activation is not defined. */
8038 #ifdef USE_X_TOOLKIT
8039 pending_menu_activation = 0;
8040 #endif
8041 }
8042
8043
8044 /* Update the menu bar item list for frame F. This has to be done
8045 before we start to fill in any display lines, because it can call
8046 eval.
8047
8048 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8049
8050 static void
8051 update_menu_bar (f, save_match_data)
8052 struct frame *f;
8053 int save_match_data;
8054 {
8055 Lisp_Object window;
8056 register struct window *w;
8057
8058 /* If called recursively during a menu update, do nothing. This can
8059 happen when, for instance, an activate-menubar-hook causes a
8060 redisplay. */
8061 if (inhibit_menubar_update)
8062 return;
8063
8064 window = FRAME_SELECTED_WINDOW (f);
8065 w = XWINDOW (window);
8066
8067 #if 0 /* The if statement below this if statement used to include the
8068 condition !NILP (w->update_mode_line), rather than using
8069 update_mode_lines directly, and this if statement may have
8070 been added to make that condition work. Now the if
8071 statement below matches its comment, this isn't needed. */
8072 if (update_mode_lines)
8073 w->update_mode_line = Qt;
8074 #endif
8075
8076 if (FRAME_WINDOW_P (f)
8077 ?
8078 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8079 || defined (USE_GTK)
8080 FRAME_EXTERNAL_MENU_BAR (f)
8081 #else
8082 FRAME_MENU_BAR_LINES (f) > 0
8083 #endif
8084 : FRAME_MENU_BAR_LINES (f) > 0)
8085 {
8086 /* If the user has switched buffers or windows, we need to
8087 recompute to reflect the new bindings. But we'll
8088 recompute when update_mode_lines is set too; that means
8089 that people can use force-mode-line-update to request
8090 that the menu bar be recomputed. The adverse effect on
8091 the rest of the redisplay algorithm is about the same as
8092 windows_or_buffers_changed anyway. */
8093 if (windows_or_buffers_changed
8094 /* This used to test w->update_mode_line, but we believe
8095 there is no need to recompute the menu in that case. */
8096 || update_mode_lines
8097 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8098 < BUF_MODIFF (XBUFFER (w->buffer)))
8099 != !NILP (w->last_had_star))
8100 || ((!NILP (Vtransient_mark_mode)
8101 && !NILP (XBUFFER (w->buffer)->mark_active))
8102 != !NILP (w->region_showing)))
8103 {
8104 struct buffer *prev = current_buffer;
8105 int count = SPECPDL_INDEX ();
8106
8107 specbind (Qinhibit_menubar_update, Qt);
8108
8109 set_buffer_internal_1 (XBUFFER (w->buffer));
8110 if (save_match_data)
8111 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8112 if (NILP (Voverriding_local_map_menu_flag))
8113 {
8114 specbind (Qoverriding_terminal_local_map, Qnil);
8115 specbind (Qoverriding_local_map, Qnil);
8116 }
8117
8118 /* Run the Lucid hook. */
8119 safe_run_hooks (Qactivate_menubar_hook);
8120
8121 /* If it has changed current-menubar from previous value,
8122 really recompute the menu-bar from the value. */
8123 if (! NILP (Vlucid_menu_bar_dirty_flag))
8124 call0 (Qrecompute_lucid_menubar);
8125
8126 safe_run_hooks (Qmenu_bar_update_hook);
8127 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8128
8129 /* Redisplay the menu bar in case we changed it. */
8130 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8131 || defined (USE_GTK)
8132 if (FRAME_WINDOW_P (f)
8133 #if defined (MAC_OS)
8134 /* All frames on Mac OS share the same menubar. So only the
8135 selected frame should be allowed to set it. */
8136 && f == SELECTED_FRAME ()
8137 #endif
8138 )
8139 set_frame_menubar (f, 0, 0);
8140 else
8141 /* On a terminal screen, the menu bar is an ordinary screen
8142 line, and this makes it get updated. */
8143 w->update_mode_line = Qt;
8144 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8145 /* In the non-toolkit version, the menu bar is an ordinary screen
8146 line, and this makes it get updated. */
8147 w->update_mode_line = Qt;
8148 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8149
8150 unbind_to (count, Qnil);
8151 set_buffer_internal_1 (prev);
8152 }
8153 }
8154 }
8155
8156
8157 \f
8158 /***********************************************************************
8159 Output Cursor
8160 ***********************************************************************/
8161
8162 #ifdef HAVE_WINDOW_SYSTEM
8163
8164 /* EXPORT:
8165 Nominal cursor position -- where to draw output.
8166 HPOS and VPOS are window relative glyph matrix coordinates.
8167 X and Y are window relative pixel coordinates. */
8168
8169 struct cursor_pos output_cursor;
8170
8171
8172 /* EXPORT:
8173 Set the global variable output_cursor to CURSOR. All cursor
8174 positions are relative to updated_window. */
8175
8176 void
8177 set_output_cursor (cursor)
8178 struct cursor_pos *cursor;
8179 {
8180 output_cursor.hpos = cursor->hpos;
8181 output_cursor.vpos = cursor->vpos;
8182 output_cursor.x = cursor->x;
8183 output_cursor.y = cursor->y;
8184 }
8185
8186
8187 /* EXPORT for RIF:
8188 Set a nominal cursor position.
8189
8190 HPOS and VPOS are column/row positions in a window glyph matrix. X
8191 and Y are window text area relative pixel positions.
8192
8193 If this is done during an update, updated_window will contain the
8194 window that is being updated and the position is the future output
8195 cursor position for that window. If updated_window is null, use
8196 selected_window and display the cursor at the given position. */
8197
8198 void
8199 x_cursor_to (vpos, hpos, y, x)
8200 int vpos, hpos, y, x;
8201 {
8202 struct window *w;
8203
8204 /* If updated_window is not set, work on selected_window. */
8205 if (updated_window)
8206 w = updated_window;
8207 else
8208 w = XWINDOW (selected_window);
8209
8210 /* Set the output cursor. */
8211 output_cursor.hpos = hpos;
8212 output_cursor.vpos = vpos;
8213 output_cursor.x = x;
8214 output_cursor.y = y;
8215
8216 /* If not called as part of an update, really display the cursor.
8217 This will also set the cursor position of W. */
8218 if (updated_window == NULL)
8219 {
8220 BLOCK_INPUT;
8221 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8222 if (rif->flush_display_optional)
8223 rif->flush_display_optional (SELECTED_FRAME ());
8224 UNBLOCK_INPUT;
8225 }
8226 }
8227
8228 #endif /* HAVE_WINDOW_SYSTEM */
8229
8230 \f
8231 /***********************************************************************
8232 Tool-bars
8233 ***********************************************************************/
8234
8235 #ifdef HAVE_WINDOW_SYSTEM
8236
8237 /* Where the mouse was last time we reported a mouse event. */
8238
8239 FRAME_PTR last_mouse_frame;
8240
8241 /* Tool-bar item index of the item on which a mouse button was pressed
8242 or -1. */
8243
8244 int last_tool_bar_item;
8245
8246
8247 /* Update the tool-bar item list for frame F. This has to be done
8248 before we start to fill in any display lines. Called from
8249 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8250 and restore it here. */
8251
8252 static void
8253 update_tool_bar (f, save_match_data)
8254 struct frame *f;
8255 int save_match_data;
8256 {
8257 #ifdef USE_GTK
8258 int do_update = FRAME_EXTERNAL_TOOL_BAR(f);
8259 #else
8260 int do_update = WINDOWP (f->tool_bar_window)
8261 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8262 #endif
8263
8264 if (do_update)
8265 {
8266 Lisp_Object window;
8267 struct window *w;
8268
8269 window = FRAME_SELECTED_WINDOW (f);
8270 w = XWINDOW (window);
8271
8272 /* If the user has switched buffers or windows, we need to
8273 recompute to reflect the new bindings. But we'll
8274 recompute when update_mode_lines is set too; that means
8275 that people can use force-mode-line-update to request
8276 that the menu bar be recomputed. The adverse effect on
8277 the rest of the redisplay algorithm is about the same as
8278 windows_or_buffers_changed anyway. */
8279 if (windows_or_buffers_changed
8280 || !NILP (w->update_mode_line)
8281 || update_mode_lines
8282 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8283 < BUF_MODIFF (XBUFFER (w->buffer)))
8284 != !NILP (w->last_had_star))
8285 || ((!NILP (Vtransient_mark_mode)
8286 && !NILP (XBUFFER (w->buffer)->mark_active))
8287 != !NILP (w->region_showing)))
8288 {
8289 struct buffer *prev = current_buffer;
8290 int count = SPECPDL_INDEX ();
8291 Lisp_Object old_tool_bar;
8292 struct gcpro gcpro1;
8293
8294 /* Set current_buffer to the buffer of the selected
8295 window of the frame, so that we get the right local
8296 keymaps. */
8297 set_buffer_internal_1 (XBUFFER (w->buffer));
8298
8299 /* Save match data, if we must. */
8300 if (save_match_data)
8301 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8302
8303 /* Make sure that we don't accidentally use bogus keymaps. */
8304 if (NILP (Voverriding_local_map_menu_flag))
8305 {
8306 specbind (Qoverriding_terminal_local_map, Qnil);
8307 specbind (Qoverriding_local_map, Qnil);
8308 }
8309
8310 old_tool_bar = f->tool_bar_items;
8311 GCPRO1 (old_tool_bar);
8312
8313 /* Build desired tool-bar items from keymaps. */
8314 BLOCK_INPUT;
8315 f->tool_bar_items
8316 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8317 UNBLOCK_INPUT;
8318
8319 /* Redisplay the tool-bar if we changed it. */
8320 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8321 w->update_mode_line = Qt;
8322
8323 UNGCPRO;
8324
8325 unbind_to (count, Qnil);
8326 set_buffer_internal_1 (prev);
8327 }
8328 }
8329 }
8330
8331
8332 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8333 F's desired tool-bar contents. F->tool_bar_items must have
8334 been set up previously by calling prepare_menu_bars. */
8335
8336 static void
8337 build_desired_tool_bar_string (f)
8338 struct frame *f;
8339 {
8340 int i, size, size_needed;
8341 struct gcpro gcpro1, gcpro2, gcpro3;
8342 Lisp_Object image, plist, props;
8343
8344 image = plist = props = Qnil;
8345 GCPRO3 (image, plist, props);
8346
8347 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8348 Otherwise, make a new string. */
8349
8350 /* The size of the string we might be able to reuse. */
8351 size = (STRINGP (f->desired_tool_bar_string)
8352 ? SCHARS (f->desired_tool_bar_string)
8353 : 0);
8354
8355 /* We need one space in the string for each image. */
8356 size_needed = f->n_tool_bar_items;
8357
8358 /* Reuse f->desired_tool_bar_string, if possible. */
8359 if (size < size_needed || NILP (f->desired_tool_bar_string))
8360 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8361 make_number (' '));
8362 else
8363 {
8364 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8365 Fremove_text_properties (make_number (0), make_number (size),
8366 props, f->desired_tool_bar_string);
8367 }
8368
8369 /* Put a `display' property on the string for the images to display,
8370 put a `menu_item' property on tool-bar items with a value that
8371 is the index of the item in F's tool-bar item vector. */
8372 for (i = 0; i < f->n_tool_bar_items; ++i)
8373 {
8374 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8375
8376 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8377 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8378 int hmargin, vmargin, relief, idx, end;
8379 extern Lisp_Object QCrelief, QCmargin, QCconversion, Qimage;
8380
8381 /* If image is a vector, choose the image according to the
8382 button state. */
8383 image = PROP (TOOL_BAR_ITEM_IMAGES);
8384 if (VECTORP (image))
8385 {
8386 if (enabled_p)
8387 idx = (selected_p
8388 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8389 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8390 else
8391 idx = (selected_p
8392 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8393 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8394
8395 xassert (ASIZE (image) >= idx);
8396 image = AREF (image, idx);
8397 }
8398 else
8399 idx = -1;
8400
8401 /* Ignore invalid image specifications. */
8402 if (!valid_image_p (image))
8403 continue;
8404
8405 /* Display the tool-bar button pressed, or depressed. */
8406 plist = Fcopy_sequence (XCDR (image));
8407
8408 /* Compute margin and relief to draw. */
8409 relief = (tool_bar_button_relief >= 0
8410 ? tool_bar_button_relief
8411 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8412 hmargin = vmargin = relief;
8413
8414 if (INTEGERP (Vtool_bar_button_margin)
8415 && XINT (Vtool_bar_button_margin) > 0)
8416 {
8417 hmargin += XFASTINT (Vtool_bar_button_margin);
8418 vmargin += XFASTINT (Vtool_bar_button_margin);
8419 }
8420 else if (CONSP (Vtool_bar_button_margin))
8421 {
8422 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8423 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8424 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8425
8426 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8427 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8428 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8429 }
8430
8431 if (auto_raise_tool_bar_buttons_p)
8432 {
8433 /* Add a `:relief' property to the image spec if the item is
8434 selected. */
8435 if (selected_p)
8436 {
8437 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8438 hmargin -= relief;
8439 vmargin -= relief;
8440 }
8441 }
8442 else
8443 {
8444 /* If image is selected, display it pressed, i.e. with a
8445 negative relief. If it's not selected, display it with a
8446 raised relief. */
8447 plist = Fplist_put (plist, QCrelief,
8448 (selected_p
8449 ? make_number (-relief)
8450 : make_number (relief)));
8451 hmargin -= relief;
8452 vmargin -= relief;
8453 }
8454
8455 /* Put a margin around the image. */
8456 if (hmargin || vmargin)
8457 {
8458 if (hmargin == vmargin)
8459 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8460 else
8461 plist = Fplist_put (plist, QCmargin,
8462 Fcons (make_number (hmargin),
8463 make_number (vmargin)));
8464 }
8465
8466 /* If button is not enabled, and we don't have special images
8467 for the disabled state, make the image appear disabled by
8468 applying an appropriate algorithm to it. */
8469 if (!enabled_p && idx < 0)
8470 plist = Fplist_put (plist, QCconversion, Qdisabled);
8471
8472 /* Put a `display' text property on the string for the image to
8473 display. Put a `menu-item' property on the string that gives
8474 the start of this item's properties in the tool-bar items
8475 vector. */
8476 image = Fcons (Qimage, plist);
8477 props = list4 (Qdisplay, image,
8478 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8479
8480 /* Let the last image hide all remaining spaces in the tool bar
8481 string. The string can be longer than needed when we reuse a
8482 previous string. */
8483 if (i + 1 == f->n_tool_bar_items)
8484 end = SCHARS (f->desired_tool_bar_string);
8485 else
8486 end = i + 1;
8487 Fadd_text_properties (make_number (i), make_number (end),
8488 props, f->desired_tool_bar_string);
8489 #undef PROP
8490 }
8491
8492 UNGCPRO;
8493 }
8494
8495
8496 /* Display one line of the tool-bar of frame IT->f. */
8497
8498 static void
8499 display_tool_bar_line (it)
8500 struct it *it;
8501 {
8502 struct glyph_row *row = it->glyph_row;
8503 int max_x = it->last_visible_x;
8504 struct glyph *last;
8505
8506 prepare_desired_row (row);
8507 row->y = it->current_y;
8508
8509 /* Note that this isn't made use of if the face hasn't a box,
8510 so there's no need to check the face here. */
8511 it->start_of_box_run_p = 1;
8512
8513 while (it->current_x < max_x)
8514 {
8515 int x_before, x, n_glyphs_before, i, nglyphs;
8516
8517 /* Get the next display element. */
8518 if (!get_next_display_element (it))
8519 break;
8520
8521 /* Produce glyphs. */
8522 x_before = it->current_x;
8523 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8524 PRODUCE_GLYPHS (it);
8525
8526 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8527 i = 0;
8528 x = x_before;
8529 while (i < nglyphs)
8530 {
8531 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8532
8533 if (x + glyph->pixel_width > max_x)
8534 {
8535 /* Glyph doesn't fit on line. */
8536 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8537 it->current_x = x;
8538 goto out;
8539 }
8540
8541 ++it->hpos;
8542 x += glyph->pixel_width;
8543 ++i;
8544 }
8545
8546 /* Stop at line ends. */
8547 if (ITERATOR_AT_END_OF_LINE_P (it))
8548 break;
8549
8550 set_iterator_to_next (it, 1);
8551 }
8552
8553 out:;
8554
8555 row->displays_text_p = row->used[TEXT_AREA] != 0;
8556 extend_face_to_end_of_line (it);
8557 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8558 last->right_box_line_p = 1;
8559 if (last == row->glyphs[TEXT_AREA])
8560 last->left_box_line_p = 1;
8561 compute_line_metrics (it);
8562
8563 /* If line is empty, make it occupy the rest of the tool-bar. */
8564 if (!row->displays_text_p)
8565 {
8566 row->height = row->phys_height = it->last_visible_y - row->y;
8567 row->ascent = row->phys_ascent = 0;
8568 }
8569
8570 row->full_width_p = 1;
8571 row->continued_p = 0;
8572 row->truncated_on_left_p = 0;
8573 row->truncated_on_right_p = 0;
8574
8575 it->current_x = it->hpos = 0;
8576 it->current_y += row->height;
8577 ++it->vpos;
8578 ++it->glyph_row;
8579 }
8580
8581
8582 /* Value is the number of screen lines needed to make all tool-bar
8583 items of frame F visible. */
8584
8585 static int
8586 tool_bar_lines_needed (f)
8587 struct frame *f;
8588 {
8589 struct window *w = XWINDOW (f->tool_bar_window);
8590 struct it it;
8591
8592 /* Initialize an iterator for iteration over
8593 F->desired_tool_bar_string in the tool-bar window of frame F. */
8594 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8595 it.first_visible_x = 0;
8596 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8597 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8598
8599 while (!ITERATOR_AT_END_P (&it))
8600 {
8601 it.glyph_row = w->desired_matrix->rows;
8602 clear_glyph_row (it.glyph_row);
8603 display_tool_bar_line (&it);
8604 }
8605
8606 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8607 }
8608
8609
8610 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8611 0, 1, 0,
8612 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8613 (frame)
8614 Lisp_Object frame;
8615 {
8616 struct frame *f;
8617 struct window *w;
8618 int nlines = 0;
8619
8620 if (NILP (frame))
8621 frame = selected_frame;
8622 else
8623 CHECK_FRAME (frame);
8624 f = XFRAME (frame);
8625
8626 if (WINDOWP (f->tool_bar_window)
8627 || (w = XWINDOW (f->tool_bar_window),
8628 WINDOW_TOTAL_LINES (w) > 0))
8629 {
8630 update_tool_bar (f, 1);
8631 if (f->n_tool_bar_items)
8632 {
8633 build_desired_tool_bar_string (f);
8634 nlines = tool_bar_lines_needed (f);
8635 }
8636 }
8637
8638 return make_number (nlines);
8639 }
8640
8641
8642 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8643 height should be changed. */
8644
8645 static int
8646 redisplay_tool_bar (f)
8647 struct frame *f;
8648 {
8649 struct window *w;
8650 struct it it;
8651 struct glyph_row *row;
8652 int change_height_p = 0;
8653
8654 #ifdef USE_GTK
8655 if (FRAME_EXTERNAL_TOOL_BAR(f))
8656 update_frame_tool_bar (f);
8657 return 0;
8658 #endif
8659
8660 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8661 do anything. This means you must start with tool-bar-lines
8662 non-zero to get the auto-sizing effect. Or in other words, you
8663 can turn off tool-bars by specifying tool-bar-lines zero. */
8664 if (!WINDOWP (f->tool_bar_window)
8665 || (w = XWINDOW (f->tool_bar_window),
8666 WINDOW_TOTAL_LINES (w) == 0))
8667 return 0;
8668
8669 /* Set up an iterator for the tool-bar window. */
8670 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8671 it.first_visible_x = 0;
8672 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8673 row = it.glyph_row;
8674
8675 /* Build a string that represents the contents of the tool-bar. */
8676 build_desired_tool_bar_string (f);
8677 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8678
8679 /* Display as many lines as needed to display all tool-bar items. */
8680 while (it.current_y < it.last_visible_y)
8681 display_tool_bar_line (&it);
8682
8683 /* It doesn't make much sense to try scrolling in the tool-bar
8684 window, so don't do it. */
8685 w->desired_matrix->no_scrolling_p = 1;
8686 w->must_be_updated_p = 1;
8687
8688 if (auto_resize_tool_bars_p)
8689 {
8690 int nlines;
8691
8692 /* If we couldn't display everything, change the tool-bar's
8693 height. */
8694 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8695 change_height_p = 1;
8696
8697 /* If there are blank lines at the end, except for a partially
8698 visible blank line at the end that is smaller than
8699 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8700 row = it.glyph_row - 1;
8701 if (!row->displays_text_p
8702 && row->height >= FRAME_LINE_HEIGHT (f))
8703 change_height_p = 1;
8704
8705 /* If row displays tool-bar items, but is partially visible,
8706 change the tool-bar's height. */
8707 if (row->displays_text_p
8708 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8709 change_height_p = 1;
8710
8711 /* Resize windows as needed by changing the `tool-bar-lines'
8712 frame parameter. */
8713 if (change_height_p
8714 && (nlines = tool_bar_lines_needed (f),
8715 nlines != WINDOW_TOTAL_LINES (w)))
8716 {
8717 extern Lisp_Object Qtool_bar_lines;
8718 Lisp_Object frame;
8719 int old_height = WINDOW_TOTAL_LINES (w);
8720
8721 XSETFRAME (frame, f);
8722 clear_glyph_matrix (w->desired_matrix);
8723 Fmodify_frame_parameters (frame,
8724 Fcons (Fcons (Qtool_bar_lines,
8725 make_number (nlines)),
8726 Qnil));
8727 if (WINDOW_TOTAL_LINES (w) != old_height)
8728 fonts_changed_p = 1;
8729 }
8730 }
8731
8732 return change_height_p;
8733 }
8734
8735
8736 /* Get information about the tool-bar item which is displayed in GLYPH
8737 on frame F. Return in *PROP_IDX the index where tool-bar item
8738 properties start in F->tool_bar_items. Value is zero if
8739 GLYPH doesn't display a tool-bar item. */
8740
8741 static int
8742 tool_bar_item_info (f, glyph, prop_idx)
8743 struct frame *f;
8744 struct glyph *glyph;
8745 int *prop_idx;
8746 {
8747 Lisp_Object prop;
8748 int success_p;
8749 int charpos;
8750
8751 /* This function can be called asynchronously, which means we must
8752 exclude any possibility that Fget_text_property signals an
8753 error. */
8754 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8755 charpos = max (0, charpos);
8756
8757 /* Get the text property `menu-item' at pos. The value of that
8758 property is the start index of this item's properties in
8759 F->tool_bar_items. */
8760 prop = Fget_text_property (make_number (charpos),
8761 Qmenu_item, f->current_tool_bar_string);
8762 if (INTEGERP (prop))
8763 {
8764 *prop_idx = XINT (prop);
8765 success_p = 1;
8766 }
8767 else
8768 success_p = 0;
8769
8770 return success_p;
8771 }
8772
8773 \f
8774 /* Get information about the tool-bar item at position X/Y on frame F.
8775 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8776 the current matrix of the tool-bar window of F, or NULL if not
8777 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8778 item in F->tool_bar_items. Value is
8779
8780 -1 if X/Y is not on a tool-bar item
8781 0 if X/Y is on the same item that was highlighted before.
8782 1 otherwise. */
8783
8784 static int
8785 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8786 struct frame *f;
8787 int x, y;
8788 struct glyph **glyph;
8789 int *hpos, *vpos, *prop_idx;
8790 {
8791 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8792 struct window *w = XWINDOW (f->tool_bar_window);
8793 int area;
8794
8795 /* Find the glyph under X/Y. */
8796 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area, 0);
8797 if (*glyph == NULL)
8798 return -1;
8799
8800 /* Get the start of this tool-bar item's properties in
8801 f->tool_bar_items. */
8802 if (!tool_bar_item_info (f, *glyph, prop_idx))
8803 return -1;
8804
8805 /* Is mouse on the highlighted item? */
8806 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8807 && *vpos >= dpyinfo->mouse_face_beg_row
8808 && *vpos <= dpyinfo->mouse_face_end_row
8809 && (*vpos > dpyinfo->mouse_face_beg_row
8810 || *hpos >= dpyinfo->mouse_face_beg_col)
8811 && (*vpos < dpyinfo->mouse_face_end_row
8812 || *hpos < dpyinfo->mouse_face_end_col
8813 || dpyinfo->mouse_face_past_end))
8814 return 0;
8815
8816 return 1;
8817 }
8818
8819
8820 /* EXPORT:
8821 Handle mouse button event on the tool-bar of frame F, at
8822 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8823 0 for button release. MODIFIERS is event modifiers for button
8824 release. */
8825
8826 void
8827 handle_tool_bar_click (f, x, y, down_p, modifiers)
8828 struct frame *f;
8829 int x, y, down_p;
8830 unsigned int modifiers;
8831 {
8832 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8833 struct window *w = XWINDOW (f->tool_bar_window);
8834 int hpos, vpos, prop_idx;
8835 struct glyph *glyph;
8836 Lisp_Object enabled_p;
8837
8838 /* If not on the highlighted tool-bar item, return. */
8839 frame_to_window_pixel_xy (w, &x, &y);
8840 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8841 return;
8842
8843 /* If item is disabled, do nothing. */
8844 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8845 if (NILP (enabled_p))
8846 return;
8847
8848 if (down_p)
8849 {
8850 /* Show item in pressed state. */
8851 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8852 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8853 last_tool_bar_item = prop_idx;
8854 }
8855 else
8856 {
8857 Lisp_Object key, frame;
8858 struct input_event event;
8859 EVENT_INIT (event);
8860
8861 /* Show item in released state. */
8862 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8863 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8864
8865 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8866
8867 XSETFRAME (frame, f);
8868 event.kind = TOOL_BAR_EVENT;
8869 event.frame_or_window = frame;
8870 event.arg = frame;
8871 kbd_buffer_store_event (&event);
8872
8873 event.kind = TOOL_BAR_EVENT;
8874 event.frame_or_window = frame;
8875 event.arg = key;
8876 event.modifiers = modifiers;
8877 kbd_buffer_store_event (&event);
8878 last_tool_bar_item = -1;
8879 }
8880 }
8881
8882
8883 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8884 tool-bar window-relative coordinates X/Y. Called from
8885 note_mouse_highlight. */
8886
8887 static void
8888 note_tool_bar_highlight (f, x, y)
8889 struct frame *f;
8890 int x, y;
8891 {
8892 Lisp_Object window = f->tool_bar_window;
8893 struct window *w = XWINDOW (window);
8894 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8895 int hpos, vpos;
8896 struct glyph *glyph;
8897 struct glyph_row *row;
8898 int i;
8899 Lisp_Object enabled_p;
8900 int prop_idx;
8901 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8902 int mouse_down_p, rc;
8903
8904 /* Function note_mouse_highlight is called with negative x(y
8905 values when mouse moves outside of the frame. */
8906 if (x <= 0 || y <= 0)
8907 {
8908 clear_mouse_face (dpyinfo);
8909 return;
8910 }
8911
8912 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8913 if (rc < 0)
8914 {
8915 /* Not on tool-bar item. */
8916 clear_mouse_face (dpyinfo);
8917 return;
8918 }
8919 else if (rc == 0)
8920 /* On same tool-bar item as before. */
8921 goto set_help_echo;
8922
8923 clear_mouse_face (dpyinfo);
8924
8925 /* Mouse is down, but on different tool-bar item? */
8926 mouse_down_p = (dpyinfo->grabbed
8927 && f == last_mouse_frame
8928 && FRAME_LIVE_P (f));
8929 if (mouse_down_p
8930 && last_tool_bar_item != prop_idx)
8931 return;
8932
8933 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8934 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8935
8936 /* If tool-bar item is not enabled, don't highlight it. */
8937 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8938 if (!NILP (enabled_p))
8939 {
8940 /* Compute the x-position of the glyph. In front and past the
8941 image is a space. We include this in the highlighted area. */
8942 row = MATRIX_ROW (w->current_matrix, vpos);
8943 for (i = x = 0; i < hpos; ++i)
8944 x += row->glyphs[TEXT_AREA][i].pixel_width;
8945
8946 /* Record this as the current active region. */
8947 dpyinfo->mouse_face_beg_col = hpos;
8948 dpyinfo->mouse_face_beg_row = vpos;
8949 dpyinfo->mouse_face_beg_x = x;
8950 dpyinfo->mouse_face_beg_y = row->y;
8951 dpyinfo->mouse_face_past_end = 0;
8952
8953 dpyinfo->mouse_face_end_col = hpos + 1;
8954 dpyinfo->mouse_face_end_row = vpos;
8955 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8956 dpyinfo->mouse_face_end_y = row->y;
8957 dpyinfo->mouse_face_window = window;
8958 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8959
8960 /* Display it as active. */
8961 show_mouse_face (dpyinfo, draw);
8962 dpyinfo->mouse_face_image_state = draw;
8963 }
8964
8965 set_help_echo:
8966
8967 /* Set help_echo_string to a help string to display for this tool-bar item.
8968 XTread_socket does the rest. */
8969 help_echo_object = help_echo_window = Qnil;
8970 help_echo_pos = -1;
8971 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8972 if (NILP (help_echo_string))
8973 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8974 }
8975
8976 #endif /* HAVE_WINDOW_SYSTEM */
8977
8978
8979 \f
8980 /***********************************************************************
8981 Fringes
8982 ***********************************************************************/
8983
8984 #ifdef HAVE_WINDOW_SYSTEM
8985
8986 /* An arrow like this: `<-'. */
8987 static unsigned char left_bits[] = {
8988 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
8989
8990 /* Right truncation arrow bitmap `->'. */
8991 static unsigned char right_bits[] = {
8992 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
8993
8994 /* Marker for continued lines. */
8995 static unsigned char continued_bits[] = {
8996 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
8997
8998 /* Marker for continuation lines. */
8999 static unsigned char continuation_bits[] = {
9000 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
9001
9002 /* Overlay arrow bitmap. A triangular arrow. */
9003 static unsigned char ov_bits[] = {
9004 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
9005
9006 /* Bitmap drawn to indicate lines not displaying text if
9007 `indicate-empty-lines' is non-nil. */
9008 static unsigned char zv_bits[] = {
9009 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9010 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9011 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9012 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9013 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9014 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9015 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
9016 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
9017
9018 struct fringe_bitmap fringe_bitmaps[MAX_FRINGE_BITMAPS] =
9019 {
9020 { 0, 0, 0, NULL /* NO_FRINGE_BITMAP */ },
9021 { 8, sizeof (left_bits), 0, left_bits },
9022 { 8, sizeof (right_bits), 0, right_bits },
9023 { 8, sizeof (continued_bits), 0, continued_bits },
9024 { 8, sizeof (continuation_bits), 0, continuation_bits },
9025 { 8, sizeof (ov_bits), 0, ov_bits },
9026 { 8, sizeof (zv_bits), 3, zv_bits }
9027 };
9028
9029
9030 /* Draw the bitmap WHICH in one of the left or right fringes of
9031 window W. ROW is the glyph row for which to display the bitmap; it
9032 determines the vertical position at which the bitmap has to be
9033 drawn. */
9034
9035 static void
9036 draw_fringe_bitmap (w, row, which, left_p)
9037 struct window *w;
9038 struct glyph_row *row;
9039 enum fringe_bitmap_type which;
9040 int left_p;
9041 {
9042 struct frame *f = XFRAME (WINDOW_FRAME (w));
9043 struct draw_fringe_bitmap_params p;
9044
9045 /* Convert row to frame coordinates. */
9046 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
9047
9048 p.which = which;
9049 p.wd = fringe_bitmaps[which].width;
9050
9051 p.h = fringe_bitmaps[which].height;
9052 p.dh = (fringe_bitmaps[which].period
9053 ? (p.y % fringe_bitmaps[which].period)
9054 : 0);
9055 p.h -= p.dh;
9056 /* Clip bitmap if too high. */
9057 if (p.h > row->height)
9058 p.h = row->height;
9059
9060 p.face = FACE_FROM_ID (f, FRINGE_FACE_ID);
9061 PREPARE_FACE_FOR_DISPLAY (f, p.face);
9062
9063 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill
9064 the fringe. */
9065 p.bx = -1;
9066 if (left_p)
9067 {
9068 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
9069 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
9070 ? LEFT_MARGIN_AREA
9071 : TEXT_AREA));
9072 if (p.wd > wd)
9073 p.wd = wd;
9074 p.x = x - p.wd - (wd - p.wd) / 2;
9075
9076 if (p.wd < wd || row->height > p.h)
9077 {
9078 /* If W has a vertical border to its left, don't draw over it. */
9079 wd -= ((!WINDOW_LEFTMOST_P (w)
9080 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
9081 ? 1 : 0);
9082 p.bx = x - wd;
9083 p.nx = wd;
9084 }
9085 }
9086 else
9087 {
9088 int x = window_box_right (w,
9089 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
9090 ? RIGHT_MARGIN_AREA
9091 : TEXT_AREA));
9092 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
9093 if (p.wd > wd)
9094 p.wd = wd;
9095 p.x = x + (wd - p.wd) / 2;
9096 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill
9097 the fringe. */
9098 if (p.wd < wd || row->height > p.h)
9099 {
9100 p.bx = x;
9101 p.nx = wd;
9102 }
9103 }
9104
9105 if (p.bx >= 0)
9106 {
9107 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
9108
9109 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
9110 p.ny = row->visible_height;
9111 }
9112
9113 /* Adjust y to the offset in the row to start drawing the bitmap. */
9114 p.y += (row->height - p.h) / 2;
9115
9116 rif->draw_fringe_bitmap (w, row, &p);
9117 }
9118
9119 /* Draw fringe bitmaps for glyph row ROW on window W. Call this
9120 function with input blocked. */
9121
9122 void
9123 draw_row_fringe_bitmaps (w, row)
9124 struct window *w;
9125 struct glyph_row *row;
9126 {
9127 enum fringe_bitmap_type bitmap;
9128
9129 xassert (interrupt_input_blocked);
9130
9131 /* If row is completely invisible, because of vscrolling, we
9132 don't have to draw anything. */
9133 if (row->visible_height <= 0)
9134 return;
9135
9136 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
9137 {
9138 /* Decide which bitmap to draw in the left fringe. */
9139 if (row->overlay_arrow_p)
9140 bitmap = OVERLAY_ARROW_BITMAP;
9141 else if (row->truncated_on_left_p)
9142 bitmap = LEFT_TRUNCATION_BITMAP;
9143 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
9144 bitmap = CONTINUATION_LINE_BITMAP;
9145 else if (row->indicate_empty_line_p)
9146 bitmap = ZV_LINE_BITMAP;
9147 else
9148 bitmap = NO_FRINGE_BITMAP;
9149
9150 draw_fringe_bitmap (w, row, bitmap, 1);
9151 }
9152
9153 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
9154 {
9155 /* Decide which bitmap to draw in the right fringe. */
9156 if (row->truncated_on_right_p)
9157 bitmap = RIGHT_TRUNCATION_BITMAP;
9158 else if (row->continued_p)
9159 bitmap = CONTINUED_LINE_BITMAP;
9160 else if (row->indicate_empty_line_p && WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
9161 bitmap = ZV_LINE_BITMAP;
9162 else
9163 bitmap = NO_FRINGE_BITMAP;
9164
9165 draw_fringe_bitmap (w, row, bitmap, 0);
9166 }
9167 }
9168
9169
9170 /* Compute actual fringe widths */
9171
9172 void
9173 compute_fringe_widths (f, redraw)
9174 struct frame *f;
9175 int redraw;
9176 {
9177 int o_left = FRAME_LEFT_FRINGE_WIDTH (f);
9178 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f);
9179 int o_cols = FRAME_FRINGE_COLS (f);
9180
9181 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist);
9182 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist);
9183 int left_fringe_width, right_fringe_width;
9184
9185 if (!NILP (left_fringe))
9186 left_fringe = Fcdr (left_fringe);
9187 if (!NILP (right_fringe))
9188 right_fringe = Fcdr (right_fringe);
9189
9190 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 :
9191 XINT (left_fringe));
9192 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 :
9193 XINT (right_fringe));
9194
9195 if (left_fringe_width || right_fringe_width)
9196 {
9197 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width;
9198 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width;
9199 int conf_wid = left_wid + right_wid;
9200 int font_wid = FRAME_COLUMN_WIDTH (f);
9201 int cols = (left_wid + right_wid + font_wid-1) / font_wid;
9202 int real_wid = cols * font_wid;
9203 if (left_wid && right_wid)
9204 {
9205 if (left_fringe_width < 0)
9206 {
9207 /* Left fringe width is fixed, adjust right fringe if necessary */
9208 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid;
9209 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid;
9210 }
9211 else if (right_fringe_width < 0)
9212 {
9213 /* Right fringe width is fixed, adjust left fringe if necessary */
9214 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid;
9215 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid;
9216 }
9217 else
9218 {
9219 /* Adjust both fringes with an equal amount.
9220 Note that we are doing integer arithmetic here, so don't
9221 lose a pixel if the total width is an odd number. */
9222 int fill = real_wid - conf_wid;
9223 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2;
9224 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2;
9225 }
9226 }
9227 else if (left_fringe_width)
9228 {
9229 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid;
9230 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9231 }
9232 else
9233 {
9234 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9235 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid;
9236 }
9237 FRAME_FRINGE_COLS (f) = cols;
9238 }
9239 else
9240 {
9241 FRAME_LEFT_FRINGE_WIDTH (f) = 0;
9242 FRAME_RIGHT_FRINGE_WIDTH (f) = 0;
9243 FRAME_FRINGE_COLS (f) = 0;
9244 }
9245
9246 if (redraw && FRAME_VISIBLE_P (f))
9247 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) ||
9248 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) ||
9249 o_cols != FRAME_FRINGE_COLS (f))
9250 redraw_frame (f);
9251 }
9252
9253 #endif /* HAVE_WINDOW_SYSTEM */
9254
9255
9256 \f
9257 /************************************************************************
9258 Horizontal scrolling
9259 ************************************************************************/
9260
9261 static int hscroll_window_tree P_ ((Lisp_Object));
9262 static int hscroll_windows P_ ((Lisp_Object));
9263
9264 /* For all leaf windows in the window tree rooted at WINDOW, set their
9265 hscroll value so that PT is (i) visible in the window, and (ii) so
9266 that it is not within a certain margin at the window's left and
9267 right border. Value is non-zero if any window's hscroll has been
9268 changed. */
9269
9270 static int
9271 hscroll_window_tree (window)
9272 Lisp_Object window;
9273 {
9274 int hscrolled_p = 0;
9275 int hscroll_relative_p = FLOATP (Vhscroll_step);
9276 int hscroll_step_abs = 0;
9277 double hscroll_step_rel = 0;
9278
9279 if (hscroll_relative_p)
9280 {
9281 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9282 if (hscroll_step_rel < 0)
9283 {
9284 hscroll_relative_p = 0;
9285 hscroll_step_abs = 0;
9286 }
9287 }
9288 else if (INTEGERP (Vhscroll_step))
9289 {
9290 hscroll_step_abs = XINT (Vhscroll_step);
9291 if (hscroll_step_abs < 0)
9292 hscroll_step_abs = 0;
9293 }
9294 else
9295 hscroll_step_abs = 0;
9296
9297 while (WINDOWP (window))
9298 {
9299 struct window *w = XWINDOW (window);
9300
9301 if (WINDOWP (w->hchild))
9302 hscrolled_p |= hscroll_window_tree (w->hchild);
9303 else if (WINDOWP (w->vchild))
9304 hscrolled_p |= hscroll_window_tree (w->vchild);
9305 else if (w->cursor.vpos >= 0)
9306 {
9307 int h_margin;
9308 int text_area_width;
9309 struct glyph_row *current_cursor_row
9310 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9311 struct glyph_row *desired_cursor_row
9312 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9313 struct glyph_row *cursor_row
9314 = (desired_cursor_row->enabled_p
9315 ? desired_cursor_row
9316 : current_cursor_row);
9317
9318 text_area_width = window_box_width (w, TEXT_AREA);
9319
9320 /* Scroll when cursor is inside this scroll margin. */
9321 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9322
9323 if ((XFASTINT (w->hscroll)
9324 && w->cursor.x <= h_margin)
9325 || (cursor_row->enabled_p
9326 && cursor_row->truncated_on_right_p
9327 && (w->cursor.x >= text_area_width - h_margin)))
9328 {
9329 struct it it;
9330 int hscroll;
9331 struct buffer *saved_current_buffer;
9332 int pt;
9333 int wanted_x;
9334
9335 /* Find point in a display of infinite width. */
9336 saved_current_buffer = current_buffer;
9337 current_buffer = XBUFFER (w->buffer);
9338
9339 if (w == XWINDOW (selected_window))
9340 pt = BUF_PT (current_buffer);
9341 else
9342 {
9343 pt = marker_position (w->pointm);
9344 pt = max (BEGV, pt);
9345 pt = min (ZV, pt);
9346 }
9347
9348 /* Move iterator to pt starting at cursor_row->start in
9349 a line with infinite width. */
9350 init_to_row_start (&it, w, cursor_row);
9351 it.last_visible_x = INFINITY;
9352 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9353 current_buffer = saved_current_buffer;
9354
9355 /* Position cursor in window. */
9356 if (!hscroll_relative_p && hscroll_step_abs == 0)
9357 hscroll = max (0, it.current_x - text_area_width / 2)
9358 / FRAME_COLUMN_WIDTH (it.f);
9359 else if (w->cursor.x >= text_area_width - h_margin)
9360 {
9361 if (hscroll_relative_p)
9362 wanted_x = text_area_width * (1 - hscroll_step_rel)
9363 - h_margin;
9364 else
9365 wanted_x = text_area_width
9366 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9367 - h_margin;
9368 hscroll
9369 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9370 }
9371 else
9372 {
9373 if (hscroll_relative_p)
9374 wanted_x = text_area_width * hscroll_step_rel
9375 + h_margin;
9376 else
9377 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9378 + h_margin;
9379 hscroll
9380 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9381 }
9382 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9383
9384 /* Don't call Fset_window_hscroll if value hasn't
9385 changed because it will prevent redisplay
9386 optimizations. */
9387 if (XFASTINT (w->hscroll) != hscroll)
9388 {
9389 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9390 w->hscroll = make_number (hscroll);
9391 hscrolled_p = 1;
9392 }
9393 }
9394 }
9395
9396 window = w->next;
9397 }
9398
9399 /* Value is non-zero if hscroll of any leaf window has been changed. */
9400 return hscrolled_p;
9401 }
9402
9403
9404 /* Set hscroll so that cursor is visible and not inside horizontal
9405 scroll margins for all windows in the tree rooted at WINDOW. See
9406 also hscroll_window_tree above. Value is non-zero if any window's
9407 hscroll has been changed. If it has, desired matrices on the frame
9408 of WINDOW are cleared. */
9409
9410 static int
9411 hscroll_windows (window)
9412 Lisp_Object window;
9413 {
9414 int hscrolled_p;
9415
9416 if (automatic_hscrolling_p)
9417 {
9418 hscrolled_p = hscroll_window_tree (window);
9419 if (hscrolled_p)
9420 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9421 }
9422 else
9423 hscrolled_p = 0;
9424 return hscrolled_p;
9425 }
9426
9427
9428 \f
9429 /************************************************************************
9430 Redisplay
9431 ************************************************************************/
9432
9433 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9434 to a non-zero value. This is sometimes handy to have in a debugger
9435 session. */
9436
9437 #if GLYPH_DEBUG
9438
9439 /* First and last unchanged row for try_window_id. */
9440
9441 int debug_first_unchanged_at_end_vpos;
9442 int debug_last_unchanged_at_beg_vpos;
9443
9444 /* Delta vpos and y. */
9445
9446 int debug_dvpos, debug_dy;
9447
9448 /* Delta in characters and bytes for try_window_id. */
9449
9450 int debug_delta, debug_delta_bytes;
9451
9452 /* Values of window_end_pos and window_end_vpos at the end of
9453 try_window_id. */
9454
9455 EMACS_INT debug_end_pos, debug_end_vpos;
9456
9457 /* Append a string to W->desired_matrix->method. FMT is a printf
9458 format string. A1...A9 are a supplement for a variable-length
9459 argument list. If trace_redisplay_p is non-zero also printf the
9460 resulting string to stderr. */
9461
9462 static void
9463 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9464 struct window *w;
9465 char *fmt;
9466 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9467 {
9468 char buffer[512];
9469 char *method = w->desired_matrix->method;
9470 int len = strlen (method);
9471 int size = sizeof w->desired_matrix->method;
9472 int remaining = size - len - 1;
9473
9474 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9475 if (len && remaining)
9476 {
9477 method[len] = '|';
9478 --remaining, ++len;
9479 }
9480
9481 strncpy (method + len, buffer, remaining);
9482
9483 if (trace_redisplay_p)
9484 fprintf (stderr, "%p (%s): %s\n",
9485 w,
9486 ((BUFFERP (w->buffer)
9487 && STRINGP (XBUFFER (w->buffer)->name))
9488 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9489 : "no buffer"),
9490 buffer);
9491 }
9492
9493 #endif /* GLYPH_DEBUG */
9494
9495
9496 /* Value is non-zero if all changes in window W, which displays
9497 current_buffer, are in the text between START and END. START is a
9498 buffer position, END is given as a distance from Z. Used in
9499 redisplay_internal for display optimization. */
9500
9501 static INLINE int
9502 text_outside_line_unchanged_p (w, start, end)
9503 struct window *w;
9504 int start, end;
9505 {
9506 int unchanged_p = 1;
9507
9508 /* If text or overlays have changed, see where. */
9509 if (XFASTINT (w->last_modified) < MODIFF
9510 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9511 {
9512 /* Gap in the line? */
9513 if (GPT < start || Z - GPT < end)
9514 unchanged_p = 0;
9515
9516 /* Changes start in front of the line, or end after it? */
9517 if (unchanged_p
9518 && (BEG_UNCHANGED < start - 1
9519 || END_UNCHANGED < end))
9520 unchanged_p = 0;
9521
9522 /* If selective display, can't optimize if changes start at the
9523 beginning of the line. */
9524 if (unchanged_p
9525 && INTEGERP (current_buffer->selective_display)
9526 && XINT (current_buffer->selective_display) > 0
9527 && (BEG_UNCHANGED < start || GPT <= start))
9528 unchanged_p = 0;
9529
9530 /* If there are overlays at the start or end of the line, these
9531 may have overlay strings with newlines in them. A change at
9532 START, for instance, may actually concern the display of such
9533 overlay strings as well, and they are displayed on different
9534 lines. So, quickly rule out this case. (For the future, it
9535 might be desirable to implement something more telling than
9536 just BEG/END_UNCHANGED.) */
9537 if (unchanged_p)
9538 {
9539 if (BEG + BEG_UNCHANGED == start
9540 && overlay_touches_p (start))
9541 unchanged_p = 0;
9542 if (END_UNCHANGED == end
9543 && overlay_touches_p (Z - end))
9544 unchanged_p = 0;
9545 }
9546 }
9547
9548 return unchanged_p;
9549 }
9550
9551
9552 /* Do a frame update, taking possible shortcuts into account. This is
9553 the main external entry point for redisplay.
9554
9555 If the last redisplay displayed an echo area message and that message
9556 is no longer requested, we clear the echo area or bring back the
9557 mini-buffer if that is in use. */
9558
9559 void
9560 redisplay ()
9561 {
9562 redisplay_internal (0);
9563 }
9564
9565
9566 /* Return 1 if point moved out of or into a composition. Otherwise
9567 return 0. PREV_BUF and PREV_PT are the last point buffer and
9568 position. BUF and PT are the current point buffer and position. */
9569
9570 int
9571 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9572 struct buffer *prev_buf, *buf;
9573 int prev_pt, pt;
9574 {
9575 EMACS_INT start, end;
9576 Lisp_Object prop;
9577 Lisp_Object buffer;
9578
9579 XSETBUFFER (buffer, buf);
9580 /* Check a composition at the last point if point moved within the
9581 same buffer. */
9582 if (prev_buf == buf)
9583 {
9584 if (prev_pt == pt)
9585 /* Point didn't move. */
9586 return 0;
9587
9588 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9589 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9590 && COMPOSITION_VALID_P (start, end, prop)
9591 && start < prev_pt && end > prev_pt)
9592 /* The last point was within the composition. Return 1 iff
9593 point moved out of the composition. */
9594 return (pt <= start || pt >= end);
9595 }
9596
9597 /* Check a composition at the current point. */
9598 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9599 && find_composition (pt, -1, &start, &end, &prop, buffer)
9600 && COMPOSITION_VALID_P (start, end, prop)
9601 && start < pt && end > pt);
9602 }
9603
9604
9605 /* Reconsider the setting of B->clip_changed which is displayed
9606 in window W. */
9607
9608 static INLINE void
9609 reconsider_clip_changes (w, b)
9610 struct window *w;
9611 struct buffer *b;
9612 {
9613 if (b->clip_changed
9614 && !NILP (w->window_end_valid)
9615 && w->current_matrix->buffer == b
9616 && w->current_matrix->zv == BUF_ZV (b)
9617 && w->current_matrix->begv == BUF_BEGV (b))
9618 b->clip_changed = 0;
9619
9620 /* If display wasn't paused, and W is not a tool bar window, see if
9621 point has been moved into or out of a composition. In that case,
9622 we set b->clip_changed to 1 to force updating the screen. If
9623 b->clip_changed has already been set to 1, we can skip this
9624 check. */
9625 if (!b->clip_changed
9626 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9627 {
9628 int pt;
9629
9630 if (w == XWINDOW (selected_window))
9631 pt = BUF_PT (current_buffer);
9632 else
9633 pt = marker_position (w->pointm);
9634
9635 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9636 || pt != XINT (w->last_point))
9637 && check_point_in_composition (w->current_matrix->buffer,
9638 XINT (w->last_point),
9639 XBUFFER (w->buffer), pt))
9640 b->clip_changed = 1;
9641 }
9642 }
9643 \f
9644 #define STOP_POLLING \
9645 do { if (! polling_stopped_here) stop_polling (); \
9646 polling_stopped_here = 1; } while (0)
9647
9648 #define RESUME_POLLING \
9649 do { if (polling_stopped_here) start_polling (); \
9650 polling_stopped_here = 0; } while (0)
9651
9652
9653 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9654 response to any user action; therefore, we should preserve the echo
9655 area. (Actually, our caller does that job.) Perhaps in the future
9656 avoid recentering windows if it is not necessary; currently that
9657 causes some problems. */
9658
9659 static void
9660 redisplay_internal (preserve_echo_area)
9661 int preserve_echo_area;
9662 {
9663 struct window *w = XWINDOW (selected_window);
9664 struct frame *f = XFRAME (w->frame);
9665 int pause;
9666 int must_finish = 0;
9667 struct text_pos tlbufpos, tlendpos;
9668 int number_of_visible_frames;
9669 int count;
9670 struct frame *sf = SELECTED_FRAME ();
9671 int polling_stopped_here = 0;
9672
9673 /* Non-zero means redisplay has to consider all windows on all
9674 frames. Zero means, only selected_window is considered. */
9675 int consider_all_windows_p;
9676
9677 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9678
9679 /* No redisplay if running in batch mode or frame is not yet fully
9680 initialized, or redisplay is explicitly turned off by setting
9681 Vinhibit_redisplay. */
9682 if (noninteractive
9683 || !NILP (Vinhibit_redisplay)
9684 || !f->glyphs_initialized_p)
9685 return;
9686
9687 /* The flag redisplay_performed_directly_p is set by
9688 direct_output_for_insert when it already did the whole screen
9689 update necessary. */
9690 if (redisplay_performed_directly_p)
9691 {
9692 redisplay_performed_directly_p = 0;
9693 if (!hscroll_windows (selected_window))
9694 return;
9695 }
9696
9697 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9698 if (popup_activated ())
9699 return;
9700 #endif
9701
9702 /* I don't think this happens but let's be paranoid. */
9703 if (redisplaying_p)
9704 return;
9705
9706 /* Record a function that resets redisplaying_p to its old value
9707 when we leave this function. */
9708 count = SPECPDL_INDEX ();
9709 record_unwind_protect (unwind_redisplay, make_number (redisplaying_p));
9710 ++redisplaying_p;
9711 specbind (Qinhibit_free_realized_faces, Qnil);
9712
9713 retry:
9714 pause = 0;
9715 reconsider_clip_changes (w, current_buffer);
9716
9717 /* If new fonts have been loaded that make a glyph matrix adjustment
9718 necessary, do it. */
9719 if (fonts_changed_p)
9720 {
9721 adjust_glyphs (NULL);
9722 ++windows_or_buffers_changed;
9723 fonts_changed_p = 0;
9724 }
9725
9726 /* If face_change_count is non-zero, init_iterator will free all
9727 realized faces, which includes the faces referenced from current
9728 matrices. So, we can't reuse current matrices in this case. */
9729 if (face_change_count)
9730 ++windows_or_buffers_changed;
9731
9732 if (! FRAME_WINDOW_P (sf)
9733 && previous_terminal_frame != sf)
9734 {
9735 /* Since frames on an ASCII terminal share the same display
9736 area, displaying a different frame means redisplay the whole
9737 thing. */
9738 windows_or_buffers_changed++;
9739 SET_FRAME_GARBAGED (sf);
9740 XSETFRAME (Vterminal_frame, sf);
9741 }
9742 previous_terminal_frame = sf;
9743
9744 /* Set the visible flags for all frames. Do this before checking
9745 for resized or garbaged frames; they want to know if their frames
9746 are visible. See the comment in frame.h for
9747 FRAME_SAMPLE_VISIBILITY. */
9748 {
9749 Lisp_Object tail, frame;
9750
9751 number_of_visible_frames = 0;
9752
9753 FOR_EACH_FRAME (tail, frame)
9754 {
9755 struct frame *f = XFRAME (frame);
9756
9757 FRAME_SAMPLE_VISIBILITY (f);
9758 if (FRAME_VISIBLE_P (f))
9759 ++number_of_visible_frames;
9760 clear_desired_matrices (f);
9761 }
9762 }
9763
9764 /* Notice any pending interrupt request to change frame size. */
9765 do_pending_window_change (1);
9766
9767 /* Clear frames marked as garbaged. */
9768 if (frame_garbaged)
9769 clear_garbaged_frames ();
9770
9771 /* Build menubar and tool-bar items. */
9772 prepare_menu_bars ();
9773
9774 if (windows_or_buffers_changed)
9775 update_mode_lines++;
9776
9777 /* Detect case that we need to write or remove a star in the mode line. */
9778 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9779 {
9780 w->update_mode_line = Qt;
9781 if (buffer_shared > 1)
9782 update_mode_lines++;
9783 }
9784
9785 /* If %c is in the mode line, update it if needed. */
9786 if (!NILP (w->column_number_displayed)
9787 /* This alternative quickly identifies a common case
9788 where no change is needed. */
9789 && !(PT == XFASTINT (w->last_point)
9790 && XFASTINT (w->last_modified) >= MODIFF
9791 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9792 && (XFASTINT (w->column_number_displayed)
9793 != (int) current_column ())) /* iftc */
9794 w->update_mode_line = Qt;
9795
9796 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9797
9798 /* The variable buffer_shared is set in redisplay_window and
9799 indicates that we redisplay a buffer in different windows. See
9800 there. */
9801 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9802 || cursor_type_changed);
9803
9804 /* If specs for an arrow have changed, do thorough redisplay
9805 to ensure we remove any arrow that should no longer exist. */
9806 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
9807 || ! EQ (Voverlay_arrow_string, last_arrow_string))
9808 consider_all_windows_p = windows_or_buffers_changed = 1;
9809
9810 /* Normally the message* functions will have already displayed and
9811 updated the echo area, but the frame may have been trashed, or
9812 the update may have been preempted, so display the echo area
9813 again here. Checking message_cleared_p captures the case that
9814 the echo area should be cleared. */
9815 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9816 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9817 || (message_cleared_p
9818 && minibuf_level == 0
9819 /* If the mini-window is currently selected, this means the
9820 echo-area doesn't show through. */
9821 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9822 {
9823 int window_height_changed_p = echo_area_display (0);
9824 must_finish = 1;
9825
9826 /* If we don't display the current message, don't clear the
9827 message_cleared_p flag, because, if we did, we wouldn't clear
9828 the echo area in the next redisplay which doesn't preserve
9829 the echo area. */
9830 if (!display_last_displayed_message_p)
9831 message_cleared_p = 0;
9832
9833 if (fonts_changed_p)
9834 goto retry;
9835 else if (window_height_changed_p)
9836 {
9837 consider_all_windows_p = 1;
9838 ++update_mode_lines;
9839 ++windows_or_buffers_changed;
9840
9841 /* If window configuration was changed, frames may have been
9842 marked garbaged. Clear them or we will experience
9843 surprises wrt scrolling. */
9844 if (frame_garbaged)
9845 clear_garbaged_frames ();
9846 }
9847 }
9848 else if (EQ (selected_window, minibuf_window)
9849 && (current_buffer->clip_changed
9850 || XFASTINT (w->last_modified) < MODIFF
9851 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9852 && resize_mini_window (w, 0))
9853 {
9854 /* Resized active mini-window to fit the size of what it is
9855 showing if its contents might have changed. */
9856 must_finish = 1;
9857 consider_all_windows_p = 1;
9858 ++windows_or_buffers_changed;
9859 ++update_mode_lines;
9860
9861 /* If window configuration was changed, frames may have been
9862 marked garbaged. Clear them or we will experience
9863 surprises wrt scrolling. */
9864 if (frame_garbaged)
9865 clear_garbaged_frames ();
9866 }
9867
9868
9869 /* If showing the region, and mark has changed, we must redisplay
9870 the whole window. The assignment to this_line_start_pos prevents
9871 the optimization directly below this if-statement. */
9872 if (((!NILP (Vtransient_mark_mode)
9873 && !NILP (XBUFFER (w->buffer)->mark_active))
9874 != !NILP (w->region_showing))
9875 || (!NILP (w->region_showing)
9876 && !EQ (w->region_showing,
9877 Fmarker_position (XBUFFER (w->buffer)->mark))))
9878 CHARPOS (this_line_start_pos) = 0;
9879
9880 /* Optimize the case that only the line containing the cursor in the
9881 selected window has changed. Variables starting with this_ are
9882 set in display_line and record information about the line
9883 containing the cursor. */
9884 tlbufpos = this_line_start_pos;
9885 tlendpos = this_line_end_pos;
9886 if (!consider_all_windows_p
9887 && CHARPOS (tlbufpos) > 0
9888 && NILP (w->update_mode_line)
9889 && !current_buffer->clip_changed
9890 && !current_buffer->prevent_redisplay_optimizations_p
9891 && FRAME_VISIBLE_P (XFRAME (w->frame))
9892 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9893 /* Make sure recorded data applies to current buffer, etc. */
9894 && this_line_buffer == current_buffer
9895 && current_buffer == XBUFFER (w->buffer)
9896 && NILP (w->force_start)
9897 && NILP (w->optional_new_start)
9898 /* Point must be on the line that we have info recorded about. */
9899 && PT >= CHARPOS (tlbufpos)
9900 && PT <= Z - CHARPOS (tlendpos)
9901 /* All text outside that line, including its final newline,
9902 must be unchanged */
9903 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9904 CHARPOS (tlendpos)))
9905 {
9906 if (CHARPOS (tlbufpos) > BEGV
9907 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9908 && (CHARPOS (tlbufpos) == ZV
9909 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9910 /* Former continuation line has disappeared by becoming empty */
9911 goto cancel;
9912 else if (XFASTINT (w->last_modified) < MODIFF
9913 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9914 || MINI_WINDOW_P (w))
9915 {
9916 /* We have to handle the case of continuation around a
9917 wide-column character (See the comment in indent.c around
9918 line 885).
9919
9920 For instance, in the following case:
9921
9922 -------- Insert --------
9923 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9924 J_I_ ==> J_I_ `^^' are cursors.
9925 ^^ ^^
9926 -------- --------
9927
9928 As we have to redraw the line above, we should goto cancel. */
9929
9930 struct it it;
9931 int line_height_before = this_line_pixel_height;
9932
9933 /* Note that start_display will handle the case that the
9934 line starting at tlbufpos is a continuation lines. */
9935 start_display (&it, w, tlbufpos);
9936
9937 /* Implementation note: It this still necessary? */
9938 if (it.current_x != this_line_start_x)
9939 goto cancel;
9940
9941 TRACE ((stderr, "trying display optimization 1\n"));
9942 w->cursor.vpos = -1;
9943 overlay_arrow_seen = 0;
9944 it.vpos = this_line_vpos;
9945 it.current_y = this_line_y;
9946 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9947 display_line (&it);
9948
9949 /* If line contains point, is not continued,
9950 and ends at same distance from eob as before, we win */
9951 if (w->cursor.vpos >= 0
9952 /* Line is not continued, otherwise this_line_start_pos
9953 would have been set to 0 in display_line. */
9954 && CHARPOS (this_line_start_pos)
9955 /* Line ends as before. */
9956 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9957 /* Line has same height as before. Otherwise other lines
9958 would have to be shifted up or down. */
9959 && this_line_pixel_height == line_height_before)
9960 {
9961 /* If this is not the window's last line, we must adjust
9962 the charstarts of the lines below. */
9963 if (it.current_y < it.last_visible_y)
9964 {
9965 struct glyph_row *row
9966 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9967 int delta, delta_bytes;
9968
9969 if (Z - CHARPOS (tlendpos) == ZV)
9970 {
9971 /* This line ends at end of (accessible part of)
9972 buffer. There is no newline to count. */
9973 delta = (Z
9974 - CHARPOS (tlendpos)
9975 - MATRIX_ROW_START_CHARPOS (row));
9976 delta_bytes = (Z_BYTE
9977 - BYTEPOS (tlendpos)
9978 - MATRIX_ROW_START_BYTEPOS (row));
9979 }
9980 else
9981 {
9982 /* This line ends in a newline. Must take
9983 account of the newline and the rest of the
9984 text that follows. */
9985 delta = (Z
9986 - CHARPOS (tlendpos)
9987 - MATRIX_ROW_START_CHARPOS (row));
9988 delta_bytes = (Z_BYTE
9989 - BYTEPOS (tlendpos)
9990 - MATRIX_ROW_START_BYTEPOS (row));
9991 }
9992
9993 increment_matrix_positions (w->current_matrix,
9994 this_line_vpos + 1,
9995 w->current_matrix->nrows,
9996 delta, delta_bytes);
9997 }
9998
9999 /* If this row displays text now but previously didn't,
10000 or vice versa, w->window_end_vpos may have to be
10001 adjusted. */
10002 if ((it.glyph_row - 1)->displays_text_p)
10003 {
10004 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10005 XSETINT (w->window_end_vpos, this_line_vpos);
10006 }
10007 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10008 && this_line_vpos > 0)
10009 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10010 w->window_end_valid = Qnil;
10011
10012 /* Update hint: No need to try to scroll in update_window. */
10013 w->desired_matrix->no_scrolling_p = 1;
10014
10015 #if GLYPH_DEBUG
10016 *w->desired_matrix->method = 0;
10017 debug_method_add (w, "optimization 1");
10018 #endif
10019 goto update;
10020 }
10021 else
10022 goto cancel;
10023 }
10024 else if (/* Cursor position hasn't changed. */
10025 PT == XFASTINT (w->last_point)
10026 /* Make sure the cursor was last displayed
10027 in this window. Otherwise we have to reposition it. */
10028 && 0 <= w->cursor.vpos
10029 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10030 {
10031 if (!must_finish)
10032 {
10033 do_pending_window_change (1);
10034
10035 /* We used to always goto end_of_redisplay here, but this
10036 isn't enough if we have a blinking cursor. */
10037 if (w->cursor_off_p == w->last_cursor_off_p)
10038 goto end_of_redisplay;
10039 }
10040 goto update;
10041 }
10042 /* If highlighting the region, or if the cursor is in the echo area,
10043 then we can't just move the cursor. */
10044 else if (! (!NILP (Vtransient_mark_mode)
10045 && !NILP (current_buffer->mark_active))
10046 && (EQ (selected_window, current_buffer->last_selected_window)
10047 || highlight_nonselected_windows)
10048 && NILP (w->region_showing)
10049 && NILP (Vshow_trailing_whitespace)
10050 && !cursor_in_echo_area)
10051 {
10052 struct it it;
10053 struct glyph_row *row;
10054
10055 /* Skip from tlbufpos to PT and see where it is. Note that
10056 PT may be in invisible text. If so, we will end at the
10057 next visible position. */
10058 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10059 NULL, DEFAULT_FACE_ID);
10060 it.current_x = this_line_start_x;
10061 it.current_y = this_line_y;
10062 it.vpos = this_line_vpos;
10063
10064 /* The call to move_it_to stops in front of PT, but
10065 moves over before-strings. */
10066 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10067
10068 if (it.vpos == this_line_vpos
10069 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10070 row->enabled_p))
10071 {
10072 xassert (this_line_vpos == it.vpos);
10073 xassert (this_line_y == it.current_y);
10074 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10075 #if GLYPH_DEBUG
10076 *w->desired_matrix->method = 0;
10077 debug_method_add (w, "optimization 3");
10078 #endif
10079 goto update;
10080 }
10081 else
10082 goto cancel;
10083 }
10084
10085 cancel:
10086 /* Text changed drastically or point moved off of line. */
10087 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10088 }
10089
10090 CHARPOS (this_line_start_pos) = 0;
10091 consider_all_windows_p |= buffer_shared > 1;
10092 ++clear_face_cache_count;
10093
10094
10095 /* Build desired matrices, and update the display. If
10096 consider_all_windows_p is non-zero, do it for all windows on all
10097 frames. Otherwise do it for selected_window, only. */
10098
10099 if (consider_all_windows_p)
10100 {
10101 Lisp_Object tail, frame;
10102 int i, n = 0, size = 50;
10103 struct frame **updated
10104 = (struct frame **) alloca (size * sizeof *updated);
10105
10106 /* Clear the face cache eventually. */
10107 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10108 {
10109 clear_face_cache (0);
10110 clear_face_cache_count = 0;
10111 }
10112
10113 /* Recompute # windows showing selected buffer. This will be
10114 incremented each time such a window is displayed. */
10115 buffer_shared = 0;
10116
10117 FOR_EACH_FRAME (tail, frame)
10118 {
10119 struct frame *f = XFRAME (frame);
10120
10121 if (FRAME_WINDOW_P (f) || f == sf)
10122 {
10123 #ifdef HAVE_WINDOW_SYSTEM
10124 if (clear_face_cache_count % 50 == 0
10125 && FRAME_WINDOW_P (f))
10126 clear_image_cache (f, 0);
10127 #endif /* HAVE_WINDOW_SYSTEM */
10128
10129 /* Mark all the scroll bars to be removed; we'll redeem
10130 the ones we want when we redisplay their windows. */
10131 if (condemn_scroll_bars_hook)
10132 condemn_scroll_bars_hook (f);
10133
10134 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10135 redisplay_windows (FRAME_ROOT_WINDOW (f));
10136
10137 /* Any scroll bars which redisplay_windows should have
10138 nuked should now go away. */
10139 if (judge_scroll_bars_hook)
10140 judge_scroll_bars_hook (f);
10141
10142 /* If fonts changed, display again. */
10143 /* ??? rms: I suspect it is a mistake to jump all the way
10144 back to retry here. It should just retry this frame. */
10145 if (fonts_changed_p)
10146 goto retry;
10147
10148 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10149 {
10150 /* See if we have to hscroll. */
10151 if (hscroll_windows (f->root_window))
10152 goto retry;
10153
10154 /* Prevent various kinds of signals during display
10155 update. stdio is not robust about handling
10156 signals, which can cause an apparent I/O
10157 error. */
10158 if (interrupt_input)
10159 unrequest_sigio ();
10160 STOP_POLLING;
10161
10162 /* Update the display. */
10163 set_window_update_flags (XWINDOW (f->root_window), 1);
10164 pause |= update_frame (f, 0, 0);
10165 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10166 if (pause)
10167 break;
10168 #endif
10169
10170 if (n == size)
10171 {
10172 int nbytes = size * sizeof *updated;
10173 struct frame **p = (struct frame **) alloca (2 * nbytes);
10174 bcopy (updated, p, nbytes);
10175 size *= 2;
10176 }
10177
10178 updated[n++] = f;
10179 }
10180 }
10181 }
10182
10183 /* Do the mark_window_display_accurate after all windows have
10184 been redisplayed because this call resets flags in buffers
10185 which are needed for proper redisplay. */
10186 for (i = 0; i < n; ++i)
10187 {
10188 struct frame *f = updated[i];
10189 mark_window_display_accurate (f->root_window, 1);
10190 if (frame_up_to_date_hook)
10191 frame_up_to_date_hook (f);
10192 }
10193 }
10194 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10195 {
10196 Lisp_Object mini_window;
10197 struct frame *mini_frame;
10198
10199 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10200 /* Use list_of_error, not Qerror, so that
10201 we catch only errors and don't run the debugger. */
10202 internal_condition_case_1 (redisplay_window_1, selected_window,
10203 list_of_error,
10204 redisplay_window_error);
10205
10206 /* Compare desired and current matrices, perform output. */
10207
10208 update:
10209 /* If fonts changed, display again. */
10210 if (fonts_changed_p)
10211 goto retry;
10212
10213 /* Prevent various kinds of signals during display update.
10214 stdio is not robust about handling signals,
10215 which can cause an apparent I/O error. */
10216 if (interrupt_input)
10217 unrequest_sigio ();
10218 STOP_POLLING;
10219
10220 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10221 {
10222 if (hscroll_windows (selected_window))
10223 goto retry;
10224
10225 XWINDOW (selected_window)->must_be_updated_p = 1;
10226 pause = update_frame (sf, 0, 0);
10227 }
10228
10229 /* We may have called echo_area_display at the top of this
10230 function. If the echo area is on another frame, that may
10231 have put text on a frame other than the selected one, so the
10232 above call to update_frame would not have caught it. Catch
10233 it here. */
10234 mini_window = FRAME_MINIBUF_WINDOW (sf);
10235 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10236
10237 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10238 {
10239 XWINDOW (mini_window)->must_be_updated_p = 1;
10240 pause |= update_frame (mini_frame, 0, 0);
10241 if (!pause && hscroll_windows (mini_window))
10242 goto retry;
10243 }
10244 }
10245
10246 /* If display was paused because of pending input, make sure we do a
10247 thorough update the next time. */
10248 if (pause)
10249 {
10250 /* Prevent the optimization at the beginning of
10251 redisplay_internal that tries a single-line update of the
10252 line containing the cursor in the selected window. */
10253 CHARPOS (this_line_start_pos) = 0;
10254
10255 /* Let the overlay arrow be updated the next time. */
10256 if (!NILP (last_arrow_position))
10257 {
10258 last_arrow_position = Qt;
10259 last_arrow_string = Qt;
10260 }
10261
10262 /* If we pause after scrolling, some rows in the current
10263 matrices of some windows are not valid. */
10264 if (!WINDOW_FULL_WIDTH_P (w)
10265 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10266 update_mode_lines = 1;
10267 }
10268 else
10269 {
10270 if (!consider_all_windows_p)
10271 {
10272 /* This has already been done above if
10273 consider_all_windows_p is set. */
10274 mark_window_display_accurate_1 (w, 1);
10275
10276 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10277 last_arrow_string = Voverlay_arrow_string;
10278
10279 if (frame_up_to_date_hook != 0)
10280 frame_up_to_date_hook (sf);
10281 }
10282
10283 update_mode_lines = 0;
10284 windows_or_buffers_changed = 0;
10285 cursor_type_changed = 0;
10286 }
10287
10288 /* Start SIGIO interrupts coming again. Having them off during the
10289 code above makes it less likely one will discard output, but not
10290 impossible, since there might be stuff in the system buffer here.
10291 But it is much hairier to try to do anything about that. */
10292 if (interrupt_input)
10293 request_sigio ();
10294 RESUME_POLLING;
10295
10296 /* If a frame has become visible which was not before, redisplay
10297 again, so that we display it. Expose events for such a frame
10298 (which it gets when becoming visible) don't call the parts of
10299 redisplay constructing glyphs, so simply exposing a frame won't
10300 display anything in this case. So, we have to display these
10301 frames here explicitly. */
10302 if (!pause)
10303 {
10304 Lisp_Object tail, frame;
10305 int new_count = 0;
10306
10307 FOR_EACH_FRAME (tail, frame)
10308 {
10309 int this_is_visible = 0;
10310
10311 if (XFRAME (frame)->visible)
10312 this_is_visible = 1;
10313 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10314 if (XFRAME (frame)->visible)
10315 this_is_visible = 1;
10316
10317 if (this_is_visible)
10318 new_count++;
10319 }
10320
10321 if (new_count != number_of_visible_frames)
10322 windows_or_buffers_changed++;
10323 }
10324
10325 /* Change frame size now if a change is pending. */
10326 do_pending_window_change (1);
10327
10328 /* If we just did a pending size change, or have additional
10329 visible frames, redisplay again. */
10330 if (windows_or_buffers_changed && !pause)
10331 goto retry;
10332
10333 end_of_redisplay:
10334 unbind_to (count, Qnil);
10335 RESUME_POLLING;
10336 }
10337
10338
10339 /* Redisplay, but leave alone any recent echo area message unless
10340 another message has been requested in its place.
10341
10342 This is useful in situations where you need to redisplay but no
10343 user action has occurred, making it inappropriate for the message
10344 area to be cleared. See tracking_off and
10345 wait_reading_process_input for examples of these situations.
10346
10347 FROM_WHERE is an integer saying from where this function was
10348 called. This is useful for debugging. */
10349
10350 void
10351 redisplay_preserve_echo_area (from_where)
10352 int from_where;
10353 {
10354 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10355
10356 if (!NILP (echo_area_buffer[1]))
10357 {
10358 /* We have a previously displayed message, but no current
10359 message. Redisplay the previous message. */
10360 display_last_displayed_message_p = 1;
10361 redisplay_internal (1);
10362 display_last_displayed_message_p = 0;
10363 }
10364 else
10365 redisplay_internal (1);
10366 }
10367
10368
10369 /* Function registered with record_unwind_protect in
10370 redisplay_internal. Reset redisplaying_p to the value it had
10371 before redisplay_internal was called, and clear
10372 prevent_freeing_realized_faces_p. */
10373
10374 static Lisp_Object
10375 unwind_redisplay (old_redisplaying_p)
10376 Lisp_Object old_redisplaying_p;
10377 {
10378 redisplaying_p = XFASTINT (old_redisplaying_p);
10379 return Qnil;
10380 }
10381
10382
10383 /* Mark the display of window W as accurate or inaccurate. If
10384 ACCURATE_P is non-zero mark display of W as accurate. If
10385 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10386 redisplay_internal is called. */
10387
10388 static void
10389 mark_window_display_accurate_1 (w, accurate_p)
10390 struct window *w;
10391 int accurate_p;
10392 {
10393 if (BUFFERP (w->buffer))
10394 {
10395 struct buffer *b = XBUFFER (w->buffer);
10396
10397 w->last_modified
10398 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10399 w->last_overlay_modified
10400 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10401 w->last_had_star
10402 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10403
10404 if (accurate_p)
10405 {
10406 b->clip_changed = 0;
10407 b->prevent_redisplay_optimizations_p = 0;
10408
10409 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10410 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10411 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10412 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10413
10414 w->current_matrix->buffer = b;
10415 w->current_matrix->begv = BUF_BEGV (b);
10416 w->current_matrix->zv = BUF_ZV (b);
10417
10418 w->last_cursor = w->cursor;
10419 w->last_cursor_off_p = w->cursor_off_p;
10420
10421 if (w == XWINDOW (selected_window))
10422 w->last_point = make_number (BUF_PT (b));
10423 else
10424 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10425 }
10426 }
10427
10428 if (accurate_p)
10429 {
10430 w->window_end_valid = w->buffer;
10431 #if 0 /* This is incorrect with variable-height lines. */
10432 xassert (XINT (w->window_end_vpos)
10433 < (WINDOW_TOTAL_LINES (w)
10434 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10435 #endif
10436 w->update_mode_line = Qnil;
10437 }
10438 }
10439
10440
10441 /* Mark the display of windows in the window tree rooted at WINDOW as
10442 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10443 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10444 be redisplayed the next time redisplay_internal is called. */
10445
10446 void
10447 mark_window_display_accurate (window, accurate_p)
10448 Lisp_Object window;
10449 int accurate_p;
10450 {
10451 struct window *w;
10452
10453 for (; !NILP (window); window = w->next)
10454 {
10455 w = XWINDOW (window);
10456 mark_window_display_accurate_1 (w, accurate_p);
10457
10458 if (!NILP (w->vchild))
10459 mark_window_display_accurate (w->vchild, accurate_p);
10460 if (!NILP (w->hchild))
10461 mark_window_display_accurate (w->hchild, accurate_p);
10462 }
10463
10464 if (accurate_p)
10465 {
10466 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10467 last_arrow_string = Voverlay_arrow_string;
10468 }
10469 else
10470 {
10471 /* Force a thorough redisplay the next time by setting
10472 last_arrow_position and last_arrow_string to t, which is
10473 unequal to any useful value of Voverlay_arrow_... */
10474 last_arrow_position = Qt;
10475 last_arrow_string = Qt;
10476 }
10477 }
10478
10479
10480 /* Return value in display table DP (Lisp_Char_Table *) for character
10481 C. Since a display table doesn't have any parent, we don't have to
10482 follow parent. Do not call this function directly but use the
10483 macro DISP_CHAR_VECTOR. */
10484
10485 Lisp_Object
10486 disp_char_vector (dp, c)
10487 struct Lisp_Char_Table *dp;
10488 int c;
10489 {
10490 Lisp_Object val;
10491
10492 if (ASCII_CHAR_P (c))
10493 {
10494 val = dp->ascii;
10495 if (SUB_CHAR_TABLE_P (val))
10496 val = XSUB_CHAR_TABLE (val)->contents[c];
10497 }
10498 else
10499 {
10500 Lisp_Object table;
10501
10502 XSETCHAR_TABLE (table, dp);
10503 val = char_table_ref (table, c);
10504 }
10505 if (NILP (val))
10506 val = dp->defalt;
10507 return val;
10508 }
10509
10510
10511 \f
10512 /***********************************************************************
10513 Window Redisplay
10514 ***********************************************************************/
10515
10516 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10517
10518 static void
10519 redisplay_windows (window)
10520 Lisp_Object window;
10521 {
10522 while (!NILP (window))
10523 {
10524 struct window *w = XWINDOW (window);
10525
10526 if (!NILP (w->hchild))
10527 redisplay_windows (w->hchild);
10528 else if (!NILP (w->vchild))
10529 redisplay_windows (w->vchild);
10530 else
10531 {
10532 displayed_buffer = XBUFFER (w->buffer);
10533 /* Use list_of_error, not Qerror, so that
10534 we catch only errors and don't run the debugger. */
10535 internal_condition_case_1 (redisplay_window_0, window,
10536 list_of_error,
10537 redisplay_window_error);
10538 }
10539
10540 window = w->next;
10541 }
10542 }
10543
10544 static Lisp_Object
10545 redisplay_window_error ()
10546 {
10547 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10548 return Qnil;
10549 }
10550
10551 static Lisp_Object
10552 redisplay_window_0 (window)
10553 Lisp_Object window;
10554 {
10555 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10556 redisplay_window (window, 0);
10557 return Qnil;
10558 }
10559
10560 static Lisp_Object
10561 redisplay_window_1 (window)
10562 Lisp_Object window;
10563 {
10564 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10565 redisplay_window (window, 1);
10566 return Qnil;
10567 }
10568 \f
10569
10570 /* Increment GLYPH until it reaches END or CONDITION fails while
10571 adding (GLYPH)->pixel_width to X. */
10572
10573 #define SKIP_GLYPHS(glyph, end, x, condition) \
10574 do \
10575 { \
10576 (x) += (glyph)->pixel_width; \
10577 ++(glyph); \
10578 } \
10579 while ((glyph) < (end) && (condition))
10580
10581
10582 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10583 DELTA is the number of bytes by which positions recorded in ROW
10584 differ from current buffer positions. */
10585
10586 void
10587 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10588 struct window *w;
10589 struct glyph_row *row;
10590 struct glyph_matrix *matrix;
10591 int delta, delta_bytes, dy, dvpos;
10592 {
10593 struct glyph *glyph = row->glyphs[TEXT_AREA];
10594 struct glyph *end = glyph + row->used[TEXT_AREA];
10595 /* The first glyph that starts a sequence of glyphs from string. */
10596 struct glyph *string_start;
10597 /* The X coordinate of string_start. */
10598 int string_start_x;
10599 /* The last known character position. */
10600 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10601 /* The last known character position before string_start. */
10602 int string_before_pos;
10603 int x = row->x;
10604 int pt_old = PT - delta;
10605
10606 /* Skip over glyphs not having an object at the start of the row.
10607 These are special glyphs like truncation marks on terminal
10608 frames. */
10609 if (row->displays_text_p)
10610 while (glyph < end
10611 && INTEGERP (glyph->object)
10612 && glyph->charpos < 0)
10613 {
10614 x += glyph->pixel_width;
10615 ++glyph;
10616 }
10617
10618 string_start = NULL;
10619 while (glyph < end
10620 && !INTEGERP (glyph->object)
10621 && (!BUFFERP (glyph->object)
10622 || (last_pos = glyph->charpos) < pt_old))
10623 {
10624 if (! STRINGP (glyph->object))
10625 {
10626 string_start = NULL;
10627 x += glyph->pixel_width;
10628 ++glyph;
10629 }
10630 else
10631 {
10632 string_before_pos = last_pos;
10633 string_start = glyph;
10634 string_start_x = x;
10635 /* Skip all glyphs from string. */
10636 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10637 }
10638 }
10639
10640 if (string_start
10641 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10642 {
10643 /* We may have skipped over point because the previous glyphs
10644 are from string. As there's no easy way to know the
10645 character position of the current glyph, find the correct
10646 glyph on point by scanning from string_start again. */
10647 Lisp_Object limit;
10648 Lisp_Object string;
10649 int pos;
10650
10651 limit = make_number (pt_old + 1);
10652 end = glyph;
10653 glyph = string_start;
10654 x = string_start_x;
10655 string = glyph->object;
10656 pos = string_buffer_position (w, string, string_before_pos);
10657 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10658 because we always put cursor after overlay strings. */
10659 while (pos == 0 && glyph < end)
10660 {
10661 string = glyph->object;
10662 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10663 if (glyph < end)
10664 pos = string_buffer_position (w, glyph->object, string_before_pos);
10665 }
10666
10667 while (glyph < end)
10668 {
10669 pos = XINT (Fnext_single_char_property_change
10670 (make_number (pos), Qdisplay, Qnil, limit));
10671 if (pos > pt_old)
10672 break;
10673 /* Skip glyphs from the same string. */
10674 string = glyph->object;
10675 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10676 /* Skip glyphs from an overlay. */
10677 while (glyph < end
10678 && ! string_buffer_position (w, glyph->object, pos))
10679 {
10680 string = glyph->object;
10681 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10682 }
10683 }
10684 }
10685
10686 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10687 w->cursor.x = x;
10688 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10689 w->cursor.y = row->y + dy;
10690
10691 if (w == XWINDOW (selected_window))
10692 {
10693 if (!row->continued_p
10694 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10695 && row->x == 0)
10696 {
10697 this_line_buffer = XBUFFER (w->buffer);
10698
10699 CHARPOS (this_line_start_pos)
10700 = MATRIX_ROW_START_CHARPOS (row) + delta;
10701 BYTEPOS (this_line_start_pos)
10702 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10703
10704 CHARPOS (this_line_end_pos)
10705 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10706 BYTEPOS (this_line_end_pos)
10707 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10708
10709 this_line_y = w->cursor.y;
10710 this_line_pixel_height = row->height;
10711 this_line_vpos = w->cursor.vpos;
10712 this_line_start_x = row->x;
10713 }
10714 else
10715 CHARPOS (this_line_start_pos) = 0;
10716 }
10717 }
10718
10719
10720 /* Run window scroll functions, if any, for WINDOW with new window
10721 start STARTP. Sets the window start of WINDOW to that position.
10722
10723 We assume that the window's buffer is really current. */
10724
10725 static INLINE struct text_pos
10726 run_window_scroll_functions (window, startp)
10727 Lisp_Object window;
10728 struct text_pos startp;
10729 {
10730 struct window *w = XWINDOW (window);
10731 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10732
10733 if (current_buffer != XBUFFER (w->buffer))
10734 abort ();
10735
10736 if (!NILP (Vwindow_scroll_functions))
10737 {
10738 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10739 make_number (CHARPOS (startp)));
10740 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10741 /* In case the hook functions switch buffers. */
10742 if (current_buffer != XBUFFER (w->buffer))
10743 set_buffer_internal_1 (XBUFFER (w->buffer));
10744 }
10745
10746 return startp;
10747 }
10748
10749
10750 /* Make sure the line containing the cursor is fully visible.
10751 A value of 1 means there is nothing to be done.
10752 (Either the line is fully visible, or it cannot be made so,
10753 or we cannot tell.)
10754 A value of 0 means the caller should do scrolling
10755 as if point had gone off the screen. */
10756
10757 static int
10758 make_cursor_line_fully_visible (w)
10759 struct window *w;
10760 {
10761 struct glyph_matrix *matrix;
10762 struct glyph_row *row;
10763 int window_height;
10764
10765 /* It's not always possible to find the cursor, e.g, when a window
10766 is full of overlay strings. Don't do anything in that case. */
10767 if (w->cursor.vpos < 0)
10768 return 1;
10769
10770 matrix = w->desired_matrix;
10771 row = MATRIX_ROW (matrix, w->cursor.vpos);
10772
10773 /* If the cursor row is not partially visible, there's nothing to do. */
10774 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10775 return 1;
10776
10777 /* If the row the cursor is in is taller than the window's height,
10778 it's not clear what to do, so do nothing. */
10779 window_height = window_box_height (w);
10780 if (row->height >= window_height)
10781 return 1;
10782
10783 return 0;
10784
10785 #if 0
10786 /* This code used to try to scroll the window just enough to make
10787 the line visible. It returned 0 to say that the caller should
10788 allocate larger glyph matrices. */
10789
10790 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10791 {
10792 int dy = row->height - row->visible_height;
10793 w->vscroll = 0;
10794 w->cursor.y += dy;
10795 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10796 }
10797 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10798 {
10799 int dy = - (row->height - row->visible_height);
10800 w->vscroll = dy;
10801 w->cursor.y += dy;
10802 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10803 }
10804
10805 /* When we change the cursor y-position of the selected window,
10806 change this_line_y as well so that the display optimization for
10807 the cursor line of the selected window in redisplay_internal uses
10808 the correct y-position. */
10809 if (w == XWINDOW (selected_window))
10810 this_line_y = w->cursor.y;
10811
10812 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10813 redisplay with larger matrices. */
10814 if (matrix->nrows < required_matrix_height (w))
10815 {
10816 fonts_changed_p = 1;
10817 return 0;
10818 }
10819
10820 return 1;
10821 #endif /* 0 */
10822 }
10823
10824
10825 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10826 non-zero means only WINDOW is redisplayed in redisplay_internal.
10827 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10828 in redisplay_window to bring a partially visible line into view in
10829 the case that only the cursor has moved.
10830
10831 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10832 last screen line's vertical height extends past the end of the screen.
10833
10834 Value is
10835
10836 1 if scrolling succeeded
10837
10838 0 if scrolling didn't find point.
10839
10840 -1 if new fonts have been loaded so that we must interrupt
10841 redisplay, adjust glyph matrices, and try again. */
10842
10843 enum
10844 {
10845 SCROLLING_SUCCESS,
10846 SCROLLING_FAILED,
10847 SCROLLING_NEED_LARGER_MATRICES
10848 };
10849
10850 static int
10851 try_scrolling (window, just_this_one_p, scroll_conservatively,
10852 scroll_step, temp_scroll_step, last_line_misfit)
10853 Lisp_Object window;
10854 int just_this_one_p;
10855 EMACS_INT scroll_conservatively, scroll_step;
10856 int temp_scroll_step;
10857 int last_line_misfit;
10858 {
10859 struct window *w = XWINDOW (window);
10860 struct frame *f = XFRAME (w->frame);
10861 struct text_pos scroll_margin_pos;
10862 struct text_pos pos;
10863 struct text_pos startp;
10864 struct it it;
10865 Lisp_Object window_end;
10866 int this_scroll_margin;
10867 int dy = 0;
10868 int scroll_max;
10869 int rc;
10870 int amount_to_scroll = 0;
10871 Lisp_Object aggressive;
10872 int height;
10873 int end_scroll_margin;
10874
10875 #if GLYPH_DEBUG
10876 debug_method_add (w, "try_scrolling");
10877 #endif
10878
10879 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10880
10881 /* Compute scroll margin height in pixels. We scroll when point is
10882 within this distance from the top or bottom of the window. */
10883 if (scroll_margin > 0)
10884 {
10885 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10886 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10887 }
10888 else
10889 this_scroll_margin = 0;
10890
10891 /* Compute how much we should try to scroll maximally to bring point
10892 into view. */
10893 if (scroll_step || scroll_conservatively || temp_scroll_step)
10894 scroll_max = max (scroll_step,
10895 max (scroll_conservatively, temp_scroll_step));
10896 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10897 || NUMBERP (current_buffer->scroll_up_aggressively))
10898 /* We're trying to scroll because of aggressive scrolling
10899 but no scroll_step is set. Choose an arbitrary one. Maybe
10900 there should be a variable for this. */
10901 scroll_max = 10;
10902 else
10903 scroll_max = 0;
10904 scroll_max *= FRAME_LINE_HEIGHT (f);
10905
10906 /* Decide whether we have to scroll down. Start at the window end
10907 and move this_scroll_margin up to find the position of the scroll
10908 margin. */
10909 window_end = Fwindow_end (window, Qt);
10910
10911 too_near_end:
10912
10913 CHARPOS (scroll_margin_pos) = XINT (window_end);
10914 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10915
10916 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10917 if (end_scroll_margin)
10918 {
10919 start_display (&it, w, scroll_margin_pos);
10920 move_it_vertically (&it, - end_scroll_margin);
10921 scroll_margin_pos = it.current.pos;
10922 }
10923
10924 if (PT >= CHARPOS (scroll_margin_pos))
10925 {
10926 int y0;
10927
10928 /* Point is in the scroll margin at the bottom of the window, or
10929 below. Compute a new window start that makes point visible. */
10930
10931 /* Compute the distance from the scroll margin to PT.
10932 Give up if the distance is greater than scroll_max. */
10933 start_display (&it, w, scroll_margin_pos);
10934 y0 = it.current_y;
10935 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10936 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10937
10938 /* To make point visible, we have to move the window start
10939 down so that the line the cursor is in is visible, which
10940 means we have to add in the height of the cursor line. */
10941 dy = line_bottom_y (&it) - y0;
10942
10943 if (dy > scroll_max)
10944 return SCROLLING_FAILED;
10945
10946 /* Move the window start down. If scrolling conservatively,
10947 move it just enough down to make point visible. If
10948 scroll_step is set, move it down by scroll_step. */
10949 start_display (&it, w, startp);
10950
10951 if (scroll_conservatively)
10952 /* Set AMOUNT_TO_SCROLL to at least one line,
10953 and at most scroll_conservatively lines. */
10954 amount_to_scroll
10955 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10956 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10957 else if (scroll_step || temp_scroll_step)
10958 amount_to_scroll = scroll_max;
10959 else
10960 {
10961 aggressive = current_buffer->scroll_up_aggressively;
10962 height = WINDOW_BOX_TEXT_HEIGHT (w);
10963 if (NUMBERP (aggressive))
10964 amount_to_scroll = XFLOATINT (aggressive) * height;
10965 }
10966
10967 if (amount_to_scroll <= 0)
10968 return SCROLLING_FAILED;
10969
10970 /* If moving by amount_to_scroll leaves STARTP unchanged,
10971 move it down one screen line. */
10972
10973 move_it_vertically (&it, amount_to_scroll);
10974 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10975 move_it_by_lines (&it, 1, 1);
10976 startp = it.current.pos;
10977 }
10978 else
10979 {
10980 /* See if point is inside the scroll margin at the top of the
10981 window. */
10982 scroll_margin_pos = startp;
10983 if (this_scroll_margin)
10984 {
10985 start_display (&it, w, startp);
10986 move_it_vertically (&it, this_scroll_margin);
10987 scroll_margin_pos = it.current.pos;
10988 }
10989
10990 if (PT < CHARPOS (scroll_margin_pos))
10991 {
10992 /* Point is in the scroll margin at the top of the window or
10993 above what is displayed in the window. */
10994 int y0;
10995
10996 /* Compute the vertical distance from PT to the scroll
10997 margin position. Give up if distance is greater than
10998 scroll_max. */
10999 SET_TEXT_POS (pos, PT, PT_BYTE);
11000 start_display (&it, w, pos);
11001 y0 = it.current_y;
11002 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11003 it.last_visible_y, -1,
11004 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11005 dy = it.current_y - y0;
11006 if (dy > scroll_max)
11007 return SCROLLING_FAILED;
11008
11009 /* Compute new window start. */
11010 start_display (&it, w, startp);
11011
11012 if (scroll_conservatively)
11013 amount_to_scroll =
11014 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11015 else if (scroll_step || temp_scroll_step)
11016 amount_to_scroll = scroll_max;
11017 else
11018 {
11019 aggressive = current_buffer->scroll_down_aggressively;
11020 height = WINDOW_BOX_TEXT_HEIGHT (w);
11021 if (NUMBERP (aggressive))
11022 amount_to_scroll = XFLOATINT (aggressive) * height;
11023 }
11024
11025 if (amount_to_scroll <= 0)
11026 return SCROLLING_FAILED;
11027
11028 move_it_vertically (&it, - amount_to_scroll);
11029 startp = it.current.pos;
11030 }
11031 }
11032
11033 /* Run window scroll functions. */
11034 startp = run_window_scroll_functions (window, startp);
11035
11036 /* Display the window. Give up if new fonts are loaded, or if point
11037 doesn't appear. */
11038 if (!try_window (window, startp))
11039 rc = SCROLLING_NEED_LARGER_MATRICES;
11040 else if (w->cursor.vpos < 0)
11041 {
11042 clear_glyph_matrix (w->desired_matrix);
11043 rc = SCROLLING_FAILED;
11044 }
11045 else
11046 {
11047 /* Maybe forget recorded base line for line number display. */
11048 if (!just_this_one_p
11049 || current_buffer->clip_changed
11050 || BEG_UNCHANGED < CHARPOS (startp))
11051 w->base_line_number = Qnil;
11052
11053 /* If cursor ends up on a partially visible line,
11054 treat that as being off the bottom of the screen. */
11055 if (! make_cursor_line_fully_visible (w))
11056 {
11057 clear_glyph_matrix (w->desired_matrix);
11058 last_line_misfit = 1;
11059 goto too_near_end;
11060 }
11061 rc = SCROLLING_SUCCESS;
11062 }
11063
11064 return rc;
11065 }
11066
11067
11068 /* Compute a suitable window start for window W if display of W starts
11069 on a continuation line. Value is non-zero if a new window start
11070 was computed.
11071
11072 The new window start will be computed, based on W's width, starting
11073 from the start of the continued line. It is the start of the
11074 screen line with the minimum distance from the old start W->start. */
11075
11076 static int
11077 compute_window_start_on_continuation_line (w)
11078 struct window *w;
11079 {
11080 struct text_pos pos, start_pos;
11081 int window_start_changed_p = 0;
11082
11083 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11084
11085 /* If window start is on a continuation line... Window start may be
11086 < BEGV in case there's invisible text at the start of the
11087 buffer (M-x rmail, for example). */
11088 if (CHARPOS (start_pos) > BEGV
11089 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11090 {
11091 struct it it;
11092 struct glyph_row *row;
11093
11094 /* Handle the case that the window start is out of range. */
11095 if (CHARPOS (start_pos) < BEGV)
11096 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11097 else if (CHARPOS (start_pos) > ZV)
11098 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11099
11100 /* Find the start of the continued line. This should be fast
11101 because scan_buffer is fast (newline cache). */
11102 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11103 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11104 row, DEFAULT_FACE_ID);
11105 reseat_at_previous_visible_line_start (&it);
11106
11107 /* If the line start is "too far" away from the window start,
11108 say it takes too much time to compute a new window start. */
11109 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11110 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11111 {
11112 int min_distance, distance;
11113
11114 /* Move forward by display lines to find the new window
11115 start. If window width was enlarged, the new start can
11116 be expected to be > the old start. If window width was
11117 decreased, the new window start will be < the old start.
11118 So, we're looking for the display line start with the
11119 minimum distance from the old window start. */
11120 pos = it.current.pos;
11121 min_distance = INFINITY;
11122 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11123 distance < min_distance)
11124 {
11125 min_distance = distance;
11126 pos = it.current.pos;
11127 move_it_by_lines (&it, 1, 0);
11128 }
11129
11130 /* Set the window start there. */
11131 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11132 window_start_changed_p = 1;
11133 }
11134 }
11135
11136 return window_start_changed_p;
11137 }
11138
11139
11140 /* Try cursor movement in case text has not changed in window WINDOW,
11141 with window start STARTP. Value is
11142
11143 CURSOR_MOVEMENT_SUCCESS if successful
11144
11145 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11146
11147 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11148 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11149 we want to scroll as if scroll-step were set to 1. See the code.
11150
11151 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11152 which case we have to abort this redisplay, and adjust matrices
11153 first. */
11154
11155 enum
11156 {
11157 CURSOR_MOVEMENT_SUCCESS,
11158 CURSOR_MOVEMENT_CANNOT_BE_USED,
11159 CURSOR_MOVEMENT_MUST_SCROLL,
11160 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11161 };
11162
11163 static int
11164 try_cursor_movement (window, startp, scroll_step)
11165 Lisp_Object window;
11166 struct text_pos startp;
11167 int *scroll_step;
11168 {
11169 struct window *w = XWINDOW (window);
11170 struct frame *f = XFRAME (w->frame);
11171 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11172
11173 #if GLYPH_DEBUG
11174 if (inhibit_try_cursor_movement)
11175 return rc;
11176 #endif
11177
11178 /* Handle case where text has not changed, only point, and it has
11179 not moved off the frame. */
11180 if (/* Point may be in this window. */
11181 PT >= CHARPOS (startp)
11182 /* Selective display hasn't changed. */
11183 && !current_buffer->clip_changed
11184 /* Function force-mode-line-update is used to force a thorough
11185 redisplay. It sets either windows_or_buffers_changed or
11186 update_mode_lines. So don't take a shortcut here for these
11187 cases. */
11188 && !update_mode_lines
11189 && !windows_or_buffers_changed
11190 && !cursor_type_changed
11191 /* Can't use this case if highlighting a region. When a
11192 region exists, cursor movement has to do more than just
11193 set the cursor. */
11194 && !(!NILP (Vtransient_mark_mode)
11195 && !NILP (current_buffer->mark_active))
11196 && NILP (w->region_showing)
11197 && NILP (Vshow_trailing_whitespace)
11198 /* Right after splitting windows, last_point may be nil. */
11199 && INTEGERP (w->last_point)
11200 /* This code is not used for mini-buffer for the sake of the case
11201 of redisplaying to replace an echo area message; since in
11202 that case the mini-buffer contents per se are usually
11203 unchanged. This code is of no real use in the mini-buffer
11204 since the handling of this_line_start_pos, etc., in redisplay
11205 handles the same cases. */
11206 && !EQ (window, minibuf_window)
11207 /* When splitting windows or for new windows, it happens that
11208 redisplay is called with a nil window_end_vpos or one being
11209 larger than the window. This should really be fixed in
11210 window.c. I don't have this on my list, now, so we do
11211 approximately the same as the old redisplay code. --gerd. */
11212 && INTEGERP (w->window_end_vpos)
11213 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11214 && (FRAME_WINDOW_P (f)
11215 || !MARKERP (Voverlay_arrow_position)
11216 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11217 {
11218 int this_scroll_margin;
11219 struct glyph_row *row = NULL;
11220
11221 #if GLYPH_DEBUG
11222 debug_method_add (w, "cursor movement");
11223 #endif
11224
11225 /* Scroll if point within this distance from the top or bottom
11226 of the window. This is a pixel value. */
11227 this_scroll_margin = max (0, scroll_margin);
11228 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11229 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11230
11231 /* Start with the row the cursor was displayed during the last
11232 not paused redisplay. Give up if that row is not valid. */
11233 if (w->last_cursor.vpos < 0
11234 || w->last_cursor.vpos >= w->current_matrix->nrows)
11235 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11236 else
11237 {
11238 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11239 if (row->mode_line_p)
11240 ++row;
11241 if (!row->enabled_p)
11242 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11243 }
11244
11245 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11246 {
11247 int scroll_p = 0;
11248 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11249
11250 if (PT > XFASTINT (w->last_point))
11251 {
11252 /* Point has moved forward. */
11253 while (MATRIX_ROW_END_CHARPOS (row) < PT
11254 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11255 {
11256 xassert (row->enabled_p);
11257 ++row;
11258 }
11259
11260 /* The end position of a row equals the start position
11261 of the next row. If PT is there, we would rather
11262 display it in the next line. */
11263 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11264 && MATRIX_ROW_END_CHARPOS (row) == PT
11265 && !cursor_row_p (w, row))
11266 ++row;
11267
11268 /* If within the scroll margin, scroll. Note that
11269 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11270 the next line would be drawn, and that
11271 this_scroll_margin can be zero. */
11272 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11273 || PT > MATRIX_ROW_END_CHARPOS (row)
11274 /* Line is completely visible last line in window
11275 and PT is to be set in the next line. */
11276 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11277 && PT == MATRIX_ROW_END_CHARPOS (row)
11278 && !row->ends_at_zv_p
11279 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11280 scroll_p = 1;
11281 }
11282 else if (PT < XFASTINT (w->last_point))
11283 {
11284 /* Cursor has to be moved backward. Note that PT >=
11285 CHARPOS (startp) because of the outer
11286 if-statement. */
11287 while (!row->mode_line_p
11288 && (MATRIX_ROW_START_CHARPOS (row) > PT
11289 || (MATRIX_ROW_START_CHARPOS (row) == PT
11290 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11291 && (row->y > this_scroll_margin
11292 || CHARPOS (startp) == BEGV))
11293 {
11294 xassert (row->enabled_p);
11295 --row;
11296 }
11297
11298 /* Consider the following case: Window starts at BEGV,
11299 there is invisible, intangible text at BEGV, so that
11300 display starts at some point START > BEGV. It can
11301 happen that we are called with PT somewhere between
11302 BEGV and START. Try to handle that case. */
11303 if (row < w->current_matrix->rows
11304 || row->mode_line_p)
11305 {
11306 row = w->current_matrix->rows;
11307 if (row->mode_line_p)
11308 ++row;
11309 }
11310
11311 /* Due to newlines in overlay strings, we may have to
11312 skip forward over overlay strings. */
11313 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11314 && MATRIX_ROW_END_CHARPOS (row) == PT
11315 && !cursor_row_p (w, row))
11316 ++row;
11317
11318 /* If within the scroll margin, scroll. */
11319 if (row->y < this_scroll_margin
11320 && CHARPOS (startp) != BEGV)
11321 scroll_p = 1;
11322 }
11323
11324 if (PT < MATRIX_ROW_START_CHARPOS (row)
11325 || PT > MATRIX_ROW_END_CHARPOS (row))
11326 {
11327 /* if PT is not in the glyph row, give up. */
11328 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11329 }
11330 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11331 {
11332 if (PT == MATRIX_ROW_END_CHARPOS (row)
11333 && !row->ends_at_zv_p
11334 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11335 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11336 else if (row->height > window_box_height (w))
11337 {
11338 /* If we end up in a partially visible line, let's
11339 make it fully visible, except when it's taller
11340 than the window, in which case we can't do much
11341 about it. */
11342 *scroll_step = 1;
11343 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11344 }
11345 else
11346 {
11347 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11348 if (!make_cursor_line_fully_visible (w))
11349 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11350 else
11351 rc = CURSOR_MOVEMENT_SUCCESS;
11352 }
11353 }
11354 else if (scroll_p)
11355 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11356 else
11357 {
11358 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11359 rc = CURSOR_MOVEMENT_SUCCESS;
11360 }
11361 }
11362 }
11363
11364 return rc;
11365 }
11366
11367 void
11368 set_vertical_scroll_bar (w)
11369 struct window *w;
11370 {
11371 int start, end, whole;
11372
11373 /* Calculate the start and end positions for the current window.
11374 At some point, it would be nice to choose between scrollbars
11375 which reflect the whole buffer size, with special markers
11376 indicating narrowing, and scrollbars which reflect only the
11377 visible region.
11378
11379 Note that mini-buffers sometimes aren't displaying any text. */
11380 if (!MINI_WINDOW_P (w)
11381 || (w == XWINDOW (minibuf_window)
11382 && NILP (echo_area_buffer[0])))
11383 {
11384 struct buffer *buf = XBUFFER (w->buffer);
11385 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11386 start = marker_position (w->start) - BUF_BEGV (buf);
11387 /* I don't think this is guaranteed to be right. For the
11388 moment, we'll pretend it is. */
11389 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11390
11391 if (end < start)
11392 end = start;
11393 if (whole < (end - start))
11394 whole = end - start;
11395 }
11396 else
11397 start = end = whole = 0;
11398
11399 /* Indicate what this scroll bar ought to be displaying now. */
11400 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11401 }
11402
11403 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11404 selected_window is redisplayed.
11405
11406 We can return without actually redisplaying the window if
11407 fonts_changed_p is nonzero. In that case, redisplay_internal will
11408 retry. */
11409
11410 static void
11411 redisplay_window (window, just_this_one_p)
11412 Lisp_Object window;
11413 int just_this_one_p;
11414 {
11415 struct window *w = XWINDOW (window);
11416 struct frame *f = XFRAME (w->frame);
11417 struct buffer *buffer = XBUFFER (w->buffer);
11418 struct buffer *old = current_buffer;
11419 struct text_pos lpoint, opoint, startp;
11420 int update_mode_line;
11421 int tem;
11422 struct it it;
11423 /* Record it now because it's overwritten. */
11424 int current_matrix_up_to_date_p = 0;
11425 /* This is less strict than current_matrix_up_to_date_p.
11426 It indictes that the buffer contents and narrowing are unchanged. */
11427 int buffer_unchanged_p = 0;
11428 int temp_scroll_step = 0;
11429 int count = SPECPDL_INDEX ();
11430 int rc;
11431 int centering_position;
11432 int last_line_misfit = 0;
11433
11434 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11435 opoint = lpoint;
11436
11437 /* W must be a leaf window here. */
11438 xassert (!NILP (w->buffer));
11439 #if GLYPH_DEBUG
11440 *w->desired_matrix->method = 0;
11441 #endif
11442
11443 specbind (Qinhibit_point_motion_hooks, Qt);
11444
11445 reconsider_clip_changes (w, buffer);
11446
11447 /* Has the mode line to be updated? */
11448 update_mode_line = (!NILP (w->update_mode_line)
11449 || update_mode_lines
11450 || buffer->clip_changed
11451 || buffer->prevent_redisplay_optimizations_p);
11452
11453 if (MINI_WINDOW_P (w))
11454 {
11455 if (w == XWINDOW (echo_area_window)
11456 && !NILP (echo_area_buffer[0]))
11457 {
11458 if (update_mode_line)
11459 /* We may have to update a tty frame's menu bar or a
11460 tool-bar. Example `M-x C-h C-h C-g'. */
11461 goto finish_menu_bars;
11462 else
11463 /* We've already displayed the echo area glyphs in this window. */
11464 goto finish_scroll_bars;
11465 }
11466 else if ((w != XWINDOW (minibuf_window)
11467 || minibuf_level == 0)
11468 /* When buffer is nonempty, redisplay window normally. */
11469 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11470 /* Quail displays non-mini buffers in minibuffer window.
11471 In that case, redisplay the window normally. */
11472 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11473 {
11474 /* W is a mini-buffer window, but it's not active, so clear
11475 it. */
11476 int yb = window_text_bottom_y (w);
11477 struct glyph_row *row;
11478 int y;
11479
11480 for (y = 0, row = w->desired_matrix->rows;
11481 y < yb;
11482 y += row->height, ++row)
11483 blank_row (w, row, y);
11484 goto finish_scroll_bars;
11485 }
11486
11487 clear_glyph_matrix (w->desired_matrix);
11488 }
11489
11490 /* Otherwise set up data on this window; select its buffer and point
11491 value. */
11492 /* Really select the buffer, for the sake of buffer-local
11493 variables. */
11494 set_buffer_internal_1 (XBUFFER (w->buffer));
11495 SET_TEXT_POS (opoint, PT, PT_BYTE);
11496
11497 current_matrix_up_to_date_p
11498 = (!NILP (w->window_end_valid)
11499 && !current_buffer->clip_changed
11500 && !current_buffer->prevent_redisplay_optimizations_p
11501 && XFASTINT (w->last_modified) >= MODIFF
11502 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11503
11504 buffer_unchanged_p
11505 = (!NILP (w->window_end_valid)
11506 && !current_buffer->clip_changed
11507 && XFASTINT (w->last_modified) >= MODIFF
11508 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11509
11510 /* When windows_or_buffers_changed is non-zero, we can't rely on
11511 the window end being valid, so set it to nil there. */
11512 if (windows_or_buffers_changed)
11513 {
11514 /* If window starts on a continuation line, maybe adjust the
11515 window start in case the window's width changed. */
11516 if (XMARKER (w->start)->buffer == current_buffer)
11517 compute_window_start_on_continuation_line (w);
11518
11519 w->window_end_valid = Qnil;
11520 }
11521
11522 /* Some sanity checks. */
11523 CHECK_WINDOW_END (w);
11524 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11525 abort ();
11526 if (BYTEPOS (opoint) < CHARPOS (opoint))
11527 abort ();
11528
11529 /* If %c is in mode line, update it if needed. */
11530 if (!NILP (w->column_number_displayed)
11531 /* This alternative quickly identifies a common case
11532 where no change is needed. */
11533 && !(PT == XFASTINT (w->last_point)
11534 && XFASTINT (w->last_modified) >= MODIFF
11535 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11536 && (XFASTINT (w->column_number_displayed)
11537 != (int) current_column ())) /* iftc */
11538 update_mode_line = 1;
11539
11540 /* Count number of windows showing the selected buffer. An indirect
11541 buffer counts as its base buffer. */
11542 if (!just_this_one_p)
11543 {
11544 struct buffer *current_base, *window_base;
11545 current_base = current_buffer;
11546 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11547 if (current_base->base_buffer)
11548 current_base = current_base->base_buffer;
11549 if (window_base->base_buffer)
11550 window_base = window_base->base_buffer;
11551 if (current_base == window_base)
11552 buffer_shared++;
11553 }
11554
11555 /* Point refers normally to the selected window. For any other
11556 window, set up appropriate value. */
11557 if (!EQ (window, selected_window))
11558 {
11559 int new_pt = XMARKER (w->pointm)->charpos;
11560 int new_pt_byte = marker_byte_position (w->pointm);
11561 if (new_pt < BEGV)
11562 {
11563 new_pt = BEGV;
11564 new_pt_byte = BEGV_BYTE;
11565 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11566 }
11567 else if (new_pt > (ZV - 1))
11568 {
11569 new_pt = ZV;
11570 new_pt_byte = ZV_BYTE;
11571 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11572 }
11573
11574 /* We don't use SET_PT so that the point-motion hooks don't run. */
11575 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11576 }
11577
11578 /* If any of the character widths specified in the display table
11579 have changed, invalidate the width run cache. It's true that
11580 this may be a bit late to catch such changes, but the rest of
11581 redisplay goes (non-fatally) haywire when the display table is
11582 changed, so why should we worry about doing any better? */
11583 if (current_buffer->width_run_cache)
11584 {
11585 struct Lisp_Char_Table *disptab = buffer_display_table ();
11586
11587 if (! disptab_matches_widthtab (disptab,
11588 XVECTOR (current_buffer->width_table)))
11589 {
11590 invalidate_region_cache (current_buffer,
11591 current_buffer->width_run_cache,
11592 BEG, Z);
11593 recompute_width_table (current_buffer, disptab);
11594 }
11595 }
11596
11597 /* If window-start is screwed up, choose a new one. */
11598 if (XMARKER (w->start)->buffer != current_buffer)
11599 goto recenter;
11600
11601 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11602
11603 /* If someone specified a new starting point but did not insist,
11604 check whether it can be used. */
11605 if (!NILP (w->optional_new_start)
11606 && CHARPOS (startp) >= BEGV
11607 && CHARPOS (startp) <= ZV)
11608 {
11609 w->optional_new_start = Qnil;
11610 start_display (&it, w, startp);
11611 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11612 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11613 if (IT_CHARPOS (it) == PT)
11614 w->force_start = Qt;
11615 }
11616
11617 /* Handle case where place to start displaying has been specified,
11618 unless the specified location is outside the accessible range. */
11619 if (!NILP (w->force_start)
11620 || w->frozen_window_start_p)
11621 {
11622 /* We set this later on if we have to adjust point. */
11623 int new_vpos = -1;
11624
11625 w->force_start = Qnil;
11626 w->vscroll = 0;
11627 w->window_end_valid = Qnil;
11628
11629 /* Forget any recorded base line for line number display. */
11630 if (!buffer_unchanged_p)
11631 w->base_line_number = Qnil;
11632
11633 /* Redisplay the mode line. Select the buffer properly for that.
11634 Also, run the hook window-scroll-functions
11635 because we have scrolled. */
11636 /* Note, we do this after clearing force_start because
11637 if there's an error, it is better to forget about force_start
11638 than to get into an infinite loop calling the hook functions
11639 and having them get more errors. */
11640 if (!update_mode_line
11641 || ! NILP (Vwindow_scroll_functions))
11642 {
11643 update_mode_line = 1;
11644 w->update_mode_line = Qt;
11645 startp = run_window_scroll_functions (window, startp);
11646 }
11647
11648 w->last_modified = make_number (0);
11649 w->last_overlay_modified = make_number (0);
11650 if (CHARPOS (startp) < BEGV)
11651 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11652 else if (CHARPOS (startp) > ZV)
11653 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11654
11655 /* Redisplay, then check if cursor has been set during the
11656 redisplay. Give up if new fonts were loaded. */
11657 if (!try_window (window, startp))
11658 {
11659 w->force_start = Qt;
11660 clear_glyph_matrix (w->desired_matrix);
11661 goto need_larger_matrices;
11662 }
11663
11664 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11665 {
11666 /* If point does not appear, try to move point so it does
11667 appear. The desired matrix has been built above, so we
11668 can use it here. */
11669 new_vpos = window_box_height (w) / 2;
11670 }
11671
11672 if (!make_cursor_line_fully_visible (w))
11673 {
11674 /* Point does appear, but on a line partly visible at end of window.
11675 Move it back to a fully-visible line. */
11676 new_vpos = window_box_height (w);
11677 }
11678
11679 /* If we need to move point for either of the above reasons,
11680 now actually do it. */
11681 if (new_vpos >= 0)
11682 {
11683 struct glyph_row *row;
11684
11685 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11686 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11687 ++row;
11688
11689 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11690 MATRIX_ROW_START_BYTEPOS (row));
11691
11692 if (w != XWINDOW (selected_window))
11693 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11694 else if (current_buffer == old)
11695 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11696
11697 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11698
11699 /* If we are highlighting the region, then we just changed
11700 the region, so redisplay to show it. */
11701 if (!NILP (Vtransient_mark_mode)
11702 && !NILP (current_buffer->mark_active))
11703 {
11704 clear_glyph_matrix (w->desired_matrix);
11705 if (!try_window (window, startp))
11706 goto need_larger_matrices;
11707 }
11708 }
11709
11710 #if GLYPH_DEBUG
11711 debug_method_add (w, "forced window start");
11712 #endif
11713 goto done;
11714 }
11715
11716 /* Handle case where text has not changed, only point, and it has
11717 not moved off the frame, and we are not retrying after hscroll.
11718 (current_matrix_up_to_date_p is nonzero when retrying.) */
11719 if (current_matrix_up_to_date_p
11720 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11721 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11722 {
11723 switch (rc)
11724 {
11725 case CURSOR_MOVEMENT_SUCCESS:
11726 goto done;
11727
11728 #if 0 /* try_cursor_movement never returns this value. */
11729 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11730 goto need_larger_matrices;
11731 #endif
11732
11733 case CURSOR_MOVEMENT_MUST_SCROLL:
11734 goto try_to_scroll;
11735
11736 default:
11737 abort ();
11738 }
11739 }
11740 /* If current starting point was originally the beginning of a line
11741 but no longer is, find a new starting point. */
11742 else if (!NILP (w->start_at_line_beg)
11743 && !(CHARPOS (startp) <= BEGV
11744 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11745 {
11746 #if GLYPH_DEBUG
11747 debug_method_add (w, "recenter 1");
11748 #endif
11749 goto recenter;
11750 }
11751
11752 /* Try scrolling with try_window_id. Value is > 0 if update has
11753 been done, it is -1 if we know that the same window start will
11754 not work. It is 0 if unsuccessful for some other reason. */
11755 else if ((tem = try_window_id (w)) != 0)
11756 {
11757 #if GLYPH_DEBUG
11758 debug_method_add (w, "try_window_id %d", tem);
11759 #endif
11760
11761 if (fonts_changed_p)
11762 goto need_larger_matrices;
11763 if (tem > 0)
11764 goto done;
11765
11766 /* Otherwise try_window_id has returned -1 which means that we
11767 don't want the alternative below this comment to execute. */
11768 }
11769 else if (CHARPOS (startp) >= BEGV
11770 && CHARPOS (startp) <= ZV
11771 && PT >= CHARPOS (startp)
11772 && (CHARPOS (startp) < ZV
11773 /* Avoid starting at end of buffer. */
11774 || CHARPOS (startp) == BEGV
11775 || (XFASTINT (w->last_modified) >= MODIFF
11776 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11777 {
11778 #if GLYPH_DEBUG
11779 debug_method_add (w, "same window start");
11780 #endif
11781
11782 /* Try to redisplay starting at same place as before.
11783 If point has not moved off frame, accept the results. */
11784 if (!current_matrix_up_to_date_p
11785 /* Don't use try_window_reusing_current_matrix in this case
11786 because a window scroll function can have changed the
11787 buffer. */
11788 || !NILP (Vwindow_scroll_functions)
11789 || MINI_WINDOW_P (w)
11790 || !try_window_reusing_current_matrix (w))
11791 {
11792 IF_DEBUG (debug_method_add (w, "1"));
11793 try_window (window, startp);
11794 }
11795
11796 if (fonts_changed_p)
11797 goto need_larger_matrices;
11798
11799 if (w->cursor.vpos >= 0)
11800 {
11801 if (!just_this_one_p
11802 || current_buffer->clip_changed
11803 || BEG_UNCHANGED < CHARPOS (startp))
11804 /* Forget any recorded base line for line number display. */
11805 w->base_line_number = Qnil;
11806
11807 if (!make_cursor_line_fully_visible (w))
11808 {
11809 clear_glyph_matrix (w->desired_matrix);
11810 last_line_misfit = 1;
11811 }
11812 /* Drop through and scroll. */
11813 else
11814 goto done;
11815 }
11816 else
11817 clear_glyph_matrix (w->desired_matrix);
11818 }
11819
11820 try_to_scroll:
11821
11822 w->last_modified = make_number (0);
11823 w->last_overlay_modified = make_number (0);
11824
11825 /* Redisplay the mode line. Select the buffer properly for that. */
11826 if (!update_mode_line)
11827 {
11828 update_mode_line = 1;
11829 w->update_mode_line = Qt;
11830 }
11831
11832 /* Try to scroll by specified few lines. */
11833 if ((scroll_conservatively
11834 || scroll_step
11835 || temp_scroll_step
11836 || NUMBERP (current_buffer->scroll_up_aggressively)
11837 || NUMBERP (current_buffer->scroll_down_aggressively))
11838 && !current_buffer->clip_changed
11839 && CHARPOS (startp) >= BEGV
11840 && CHARPOS (startp) <= ZV)
11841 {
11842 /* The function returns -1 if new fonts were loaded, 1 if
11843 successful, 0 if not successful. */
11844 int rc = try_scrolling (window, just_this_one_p,
11845 scroll_conservatively,
11846 scroll_step,
11847 temp_scroll_step, last_line_misfit);
11848 switch (rc)
11849 {
11850 case SCROLLING_SUCCESS:
11851 goto done;
11852
11853 case SCROLLING_NEED_LARGER_MATRICES:
11854 goto need_larger_matrices;
11855
11856 case SCROLLING_FAILED:
11857 break;
11858
11859 default:
11860 abort ();
11861 }
11862 }
11863
11864 /* Finally, just choose place to start which centers point */
11865
11866 recenter:
11867 centering_position = window_box_height (w) / 2;
11868
11869 point_at_top:
11870 /* Jump here with centering_position already set to 0. */
11871
11872 #if GLYPH_DEBUG
11873 debug_method_add (w, "recenter");
11874 #endif
11875
11876 /* w->vscroll = 0; */
11877
11878 /* Forget any previously recorded base line for line number display. */
11879 if (!buffer_unchanged_p)
11880 w->base_line_number = Qnil;
11881
11882 /* Move backward half the height of the window. */
11883 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11884 it.current_y = it.last_visible_y;
11885 move_it_vertically_backward (&it, centering_position);
11886 xassert (IT_CHARPOS (it) >= BEGV);
11887
11888 /* The function move_it_vertically_backward may move over more
11889 than the specified y-distance. If it->w is small, e.g. a
11890 mini-buffer window, we may end up in front of the window's
11891 display area. Start displaying at the start of the line
11892 containing PT in this case. */
11893 if (it.current_y <= 0)
11894 {
11895 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11896 move_it_vertically (&it, 0);
11897 xassert (IT_CHARPOS (it) <= PT);
11898 it.current_y = 0;
11899 }
11900
11901 it.current_x = it.hpos = 0;
11902
11903 /* Set startp here explicitly in case that helps avoid an infinite loop
11904 in case the window-scroll-functions functions get errors. */
11905 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11906
11907 /* Run scroll hooks. */
11908 startp = run_window_scroll_functions (window, it.current.pos);
11909
11910 /* Redisplay the window. */
11911 if (!current_matrix_up_to_date_p
11912 || windows_or_buffers_changed
11913 || cursor_type_changed
11914 /* Don't use try_window_reusing_current_matrix in this case
11915 because it can have changed the buffer. */
11916 || !NILP (Vwindow_scroll_functions)
11917 || !just_this_one_p
11918 || MINI_WINDOW_P (w)
11919 || !try_window_reusing_current_matrix (w))
11920 try_window (window, startp);
11921
11922 /* If new fonts have been loaded (due to fontsets), give up. We
11923 have to start a new redisplay since we need to re-adjust glyph
11924 matrices. */
11925 if (fonts_changed_p)
11926 goto need_larger_matrices;
11927
11928 /* If cursor did not appear assume that the middle of the window is
11929 in the first line of the window. Do it again with the next line.
11930 (Imagine a window of height 100, displaying two lines of height
11931 60. Moving back 50 from it->last_visible_y will end in the first
11932 line.) */
11933 if (w->cursor.vpos < 0)
11934 {
11935 if (!NILP (w->window_end_valid)
11936 && PT >= Z - XFASTINT (w->window_end_pos))
11937 {
11938 clear_glyph_matrix (w->desired_matrix);
11939 move_it_by_lines (&it, 1, 0);
11940 try_window (window, it.current.pos);
11941 }
11942 else if (PT < IT_CHARPOS (it))
11943 {
11944 clear_glyph_matrix (w->desired_matrix);
11945 move_it_by_lines (&it, -1, 0);
11946 try_window (window, it.current.pos);
11947 }
11948 else
11949 {
11950 /* Not much we can do about it. */
11951 }
11952 }
11953
11954 /* Consider the following case: Window starts at BEGV, there is
11955 invisible, intangible text at BEGV, so that display starts at
11956 some point START > BEGV. It can happen that we are called with
11957 PT somewhere between BEGV and START. Try to handle that case. */
11958 if (w->cursor.vpos < 0)
11959 {
11960 struct glyph_row *row = w->current_matrix->rows;
11961 if (row->mode_line_p)
11962 ++row;
11963 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11964 }
11965
11966 if (!make_cursor_line_fully_visible (w))
11967 {
11968 /* If vscroll is enabled, disable it and try again. */
11969 if (w->vscroll)
11970 {
11971 w->vscroll = 0;
11972 clear_glyph_matrix (w->desired_matrix);
11973 goto recenter;
11974 }
11975
11976 /* If centering point failed to make the whole line visible,
11977 put point at the top instead. That has to make the whole line
11978 visible, if it can be done. */
11979 centering_position = 0;
11980 goto point_at_top;
11981 }
11982
11983 done:
11984
11985 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11986 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11987 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11988 ? Qt : Qnil);
11989
11990 /* Display the mode line, if we must. */
11991 if ((update_mode_line
11992 /* If window not full width, must redo its mode line
11993 if (a) the window to its side is being redone and
11994 (b) we do a frame-based redisplay. This is a consequence
11995 of how inverted lines are drawn in frame-based redisplay. */
11996 || (!just_this_one_p
11997 && !FRAME_WINDOW_P (f)
11998 && !WINDOW_FULL_WIDTH_P (w))
11999 /* Line number to display. */
12000 || INTEGERP (w->base_line_pos)
12001 /* Column number is displayed and different from the one displayed. */
12002 || (!NILP (w->column_number_displayed)
12003 && (XFASTINT (w->column_number_displayed)
12004 != (int) current_column ()))) /* iftc */
12005 /* This means that the window has a mode line. */
12006 && (WINDOW_WANTS_MODELINE_P (w)
12007 || WINDOW_WANTS_HEADER_LINE_P (w)))
12008 {
12009 display_mode_lines (w);
12010
12011 /* If mode line height has changed, arrange for a thorough
12012 immediate redisplay using the correct mode line height. */
12013 if (WINDOW_WANTS_MODELINE_P (w)
12014 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12015 {
12016 fonts_changed_p = 1;
12017 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12018 = DESIRED_MODE_LINE_HEIGHT (w);
12019 }
12020
12021 /* If top line height has changed, arrange for a thorough
12022 immediate redisplay using the correct mode line height. */
12023 if (WINDOW_WANTS_HEADER_LINE_P (w)
12024 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12025 {
12026 fonts_changed_p = 1;
12027 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12028 = DESIRED_HEADER_LINE_HEIGHT (w);
12029 }
12030
12031 if (fonts_changed_p)
12032 goto need_larger_matrices;
12033 }
12034
12035 if (!line_number_displayed
12036 && !BUFFERP (w->base_line_pos))
12037 {
12038 w->base_line_pos = Qnil;
12039 w->base_line_number = Qnil;
12040 }
12041
12042 finish_menu_bars:
12043
12044 /* When we reach a frame's selected window, redo the frame's menu bar. */
12045 if (update_mode_line
12046 && EQ (FRAME_SELECTED_WINDOW (f), window))
12047 {
12048 int redisplay_menu_p = 0;
12049 int redisplay_tool_bar_p = 0;
12050
12051 if (FRAME_WINDOW_P (f))
12052 {
12053 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12054 || defined (USE_GTK)
12055 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12056 #else
12057 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12058 #endif
12059 }
12060 else
12061 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12062
12063 if (redisplay_menu_p)
12064 display_menu_bar (w);
12065
12066 #ifdef HAVE_WINDOW_SYSTEM
12067 #ifdef USE_GTK
12068 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12069 #else
12070 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12071 && (FRAME_TOOL_BAR_LINES (f) > 0
12072 || auto_resize_tool_bars_p);
12073
12074 #endif
12075
12076 if (redisplay_tool_bar_p)
12077 redisplay_tool_bar (f);
12078 #endif
12079 }
12080
12081 /* We go to this label, with fonts_changed_p nonzero,
12082 if it is necessary to try again using larger glyph matrices.
12083 We have to redeem the scroll bar even in this case,
12084 because the loop in redisplay_internal expects that. */
12085 need_larger_matrices:
12086 ;
12087 finish_scroll_bars:
12088
12089 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12090 {
12091 /* Set the thumb's position and size. */
12092 set_vertical_scroll_bar (w);
12093
12094 /* Note that we actually used the scroll bar attached to this
12095 window, so it shouldn't be deleted at the end of redisplay. */
12096 redeem_scroll_bar_hook (w);
12097 }
12098
12099 /* Restore current_buffer and value of point in it. */
12100 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12101 set_buffer_internal_1 (old);
12102 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12103
12104 unbind_to (count, Qnil);
12105 }
12106
12107
12108 /* Build the complete desired matrix of WINDOW with a window start
12109 buffer position POS. Value is non-zero if successful. It is zero
12110 if fonts were loaded during redisplay which makes re-adjusting
12111 glyph matrices necessary. */
12112
12113 int
12114 try_window (window, pos)
12115 Lisp_Object window;
12116 struct text_pos pos;
12117 {
12118 struct window *w = XWINDOW (window);
12119 struct it it;
12120 struct glyph_row *last_text_row = NULL;
12121
12122 /* Make POS the new window start. */
12123 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12124
12125 /* Mark cursor position as unknown. No overlay arrow seen. */
12126 w->cursor.vpos = -1;
12127 overlay_arrow_seen = 0;
12128
12129 /* Initialize iterator and info to start at POS. */
12130 start_display (&it, w, pos);
12131
12132 /* Display all lines of W. */
12133 while (it.current_y < it.last_visible_y)
12134 {
12135 if (display_line (&it))
12136 last_text_row = it.glyph_row - 1;
12137 if (fonts_changed_p)
12138 return 0;
12139 }
12140
12141 /* If bottom moved off end of frame, change mode line percentage. */
12142 if (XFASTINT (w->window_end_pos) <= 0
12143 && Z != IT_CHARPOS (it))
12144 w->update_mode_line = Qt;
12145
12146 /* Set window_end_pos to the offset of the last character displayed
12147 on the window from the end of current_buffer. Set
12148 window_end_vpos to its row number. */
12149 if (last_text_row)
12150 {
12151 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12152 w->window_end_bytepos
12153 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12154 w->window_end_pos
12155 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12156 w->window_end_vpos
12157 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12158 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12159 ->displays_text_p);
12160 }
12161 else
12162 {
12163 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12164 w->window_end_pos = make_number (Z - ZV);
12165 w->window_end_vpos = make_number (0);
12166 }
12167
12168 /* But that is not valid info until redisplay finishes. */
12169 w->window_end_valid = Qnil;
12170 return 1;
12171 }
12172
12173
12174 \f
12175 /************************************************************************
12176 Window redisplay reusing current matrix when buffer has not changed
12177 ************************************************************************/
12178
12179 /* Try redisplay of window W showing an unchanged buffer with a
12180 different window start than the last time it was displayed by
12181 reusing its current matrix. Value is non-zero if successful.
12182 W->start is the new window start. */
12183
12184 static int
12185 try_window_reusing_current_matrix (w)
12186 struct window *w;
12187 {
12188 struct frame *f = XFRAME (w->frame);
12189 struct glyph_row *row, *bottom_row;
12190 struct it it;
12191 struct run run;
12192 struct text_pos start, new_start;
12193 int nrows_scrolled, i;
12194 struct glyph_row *last_text_row;
12195 struct glyph_row *last_reused_text_row;
12196 struct glyph_row *start_row;
12197 int start_vpos, min_y, max_y;
12198
12199 #if GLYPH_DEBUG
12200 if (inhibit_try_window_reusing)
12201 return 0;
12202 #endif
12203
12204 if (/* This function doesn't handle terminal frames. */
12205 !FRAME_WINDOW_P (f)
12206 /* Don't try to reuse the display if windows have been split
12207 or such. */
12208 || windows_or_buffers_changed
12209 || cursor_type_changed)
12210 return 0;
12211
12212 /* Can't do this if region may have changed. */
12213 if ((!NILP (Vtransient_mark_mode)
12214 && !NILP (current_buffer->mark_active))
12215 || !NILP (w->region_showing)
12216 || !NILP (Vshow_trailing_whitespace))
12217 return 0;
12218
12219 /* If top-line visibility has changed, give up. */
12220 if (WINDOW_WANTS_HEADER_LINE_P (w)
12221 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12222 return 0;
12223
12224 /* Give up if old or new display is scrolled vertically. We could
12225 make this function handle this, but right now it doesn't. */
12226 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12227 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12228 return 0;
12229
12230 /* The variable new_start now holds the new window start. The old
12231 start `start' can be determined from the current matrix. */
12232 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12233 start = start_row->start.pos;
12234 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12235
12236 /* Clear the desired matrix for the display below. */
12237 clear_glyph_matrix (w->desired_matrix);
12238
12239 if (CHARPOS (new_start) <= CHARPOS (start))
12240 {
12241 int first_row_y;
12242
12243 /* Don't use this method if the display starts with an ellipsis
12244 displayed for invisible text. It's not easy to handle that case
12245 below, and it's certainly not worth the effort since this is
12246 not a frequent case. */
12247 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12248 return 0;
12249
12250 IF_DEBUG (debug_method_add (w, "twu1"));
12251
12252 /* Display up to a row that can be reused. The variable
12253 last_text_row is set to the last row displayed that displays
12254 text. Note that it.vpos == 0 if or if not there is a
12255 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12256 start_display (&it, w, new_start);
12257 first_row_y = it.current_y;
12258 w->cursor.vpos = -1;
12259 last_text_row = last_reused_text_row = NULL;
12260
12261 while (it.current_y < it.last_visible_y
12262 && IT_CHARPOS (it) < CHARPOS (start)
12263 && !fonts_changed_p)
12264 if (display_line (&it))
12265 last_text_row = it.glyph_row - 1;
12266
12267 /* A value of current_y < last_visible_y means that we stopped
12268 at the previous window start, which in turn means that we
12269 have at least one reusable row. */
12270 if (it.current_y < it.last_visible_y)
12271 {
12272 /* IT.vpos always starts from 0; it counts text lines. */
12273 nrows_scrolled = it.vpos;
12274
12275 /* Find PT if not already found in the lines displayed. */
12276 if (w->cursor.vpos < 0)
12277 {
12278 int dy = it.current_y - first_row_y;
12279
12280 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12281 row = row_containing_pos (w, PT, row, NULL, dy);
12282 if (row)
12283 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12284 dy, nrows_scrolled);
12285 else
12286 {
12287 clear_glyph_matrix (w->desired_matrix);
12288 return 0;
12289 }
12290 }
12291
12292 /* Scroll the display. Do it before the current matrix is
12293 changed. The problem here is that update has not yet
12294 run, i.e. part of the current matrix is not up to date.
12295 scroll_run_hook will clear the cursor, and use the
12296 current matrix to get the height of the row the cursor is
12297 in. */
12298 run.current_y = first_row_y;
12299 run.desired_y = it.current_y;
12300 run.height = it.last_visible_y - it.current_y;
12301
12302 if (run.height > 0 && run.current_y != run.desired_y)
12303 {
12304 update_begin (f);
12305 rif->update_window_begin_hook (w);
12306 rif->clear_window_mouse_face (w);
12307 rif->scroll_run_hook (w, &run);
12308 rif->update_window_end_hook (w, 0, 0);
12309 update_end (f);
12310 }
12311
12312 /* Shift current matrix down by nrows_scrolled lines. */
12313 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12314 rotate_matrix (w->current_matrix,
12315 start_vpos,
12316 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12317 nrows_scrolled);
12318
12319 /* Disable lines that must be updated. */
12320 for (i = 0; i < it.vpos; ++i)
12321 (start_row + i)->enabled_p = 0;
12322
12323 /* Re-compute Y positions. */
12324 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12325 max_y = it.last_visible_y;
12326 for (row = start_row + nrows_scrolled;
12327 row < bottom_row;
12328 ++row)
12329 {
12330 row->y = it.current_y;
12331 row->visible_height = row->height;
12332
12333 if (row->y < min_y)
12334 row->visible_height -= min_y - row->y;
12335 if (row->y + row->height > max_y)
12336 row->visible_height -= row->y + row->height - max_y;
12337
12338 it.current_y += row->height;
12339
12340 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12341 last_reused_text_row = row;
12342 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12343 break;
12344 }
12345
12346 /* Disable lines in the current matrix which are now
12347 below the window. */
12348 for (++row; row < bottom_row; ++row)
12349 row->enabled_p = 0;
12350 }
12351
12352 /* Update window_end_pos etc.; last_reused_text_row is the last
12353 reused row from the current matrix containing text, if any.
12354 The value of last_text_row is the last displayed line
12355 containing text. */
12356 if (last_reused_text_row)
12357 {
12358 w->window_end_bytepos
12359 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12360 w->window_end_pos
12361 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12362 w->window_end_vpos
12363 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12364 w->current_matrix));
12365 }
12366 else if (last_text_row)
12367 {
12368 w->window_end_bytepos
12369 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12370 w->window_end_pos
12371 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12372 w->window_end_vpos
12373 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12374 }
12375 else
12376 {
12377 /* This window must be completely empty. */
12378 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12379 w->window_end_pos = make_number (Z - ZV);
12380 w->window_end_vpos = make_number (0);
12381 }
12382 w->window_end_valid = Qnil;
12383
12384 /* Update hint: don't try scrolling again in update_window. */
12385 w->desired_matrix->no_scrolling_p = 1;
12386
12387 #if GLYPH_DEBUG
12388 debug_method_add (w, "try_window_reusing_current_matrix 1");
12389 #endif
12390 return 1;
12391 }
12392 else if (CHARPOS (new_start) > CHARPOS (start))
12393 {
12394 struct glyph_row *pt_row, *row;
12395 struct glyph_row *first_reusable_row;
12396 struct glyph_row *first_row_to_display;
12397 int dy;
12398 int yb = window_text_bottom_y (w);
12399
12400 /* Find the row starting at new_start, if there is one. Don't
12401 reuse a partially visible line at the end. */
12402 first_reusable_row = start_row;
12403 while (first_reusable_row->enabled_p
12404 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12405 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12406 < CHARPOS (new_start)))
12407 ++first_reusable_row;
12408
12409 /* Give up if there is no row to reuse. */
12410 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12411 || !first_reusable_row->enabled_p
12412 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12413 != CHARPOS (new_start)))
12414 return 0;
12415
12416 /* We can reuse fully visible rows beginning with
12417 first_reusable_row to the end of the window. Set
12418 first_row_to_display to the first row that cannot be reused.
12419 Set pt_row to the row containing point, if there is any. */
12420 pt_row = NULL;
12421 for (first_row_to_display = first_reusable_row;
12422 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12423 ++first_row_to_display)
12424 {
12425 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12426 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12427 pt_row = first_row_to_display;
12428 }
12429
12430 /* Start displaying at the start of first_row_to_display. */
12431 xassert (first_row_to_display->y < yb);
12432 init_to_row_start (&it, w, first_row_to_display);
12433
12434 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12435 - start_vpos);
12436 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12437 - nrows_scrolled);
12438 it.current_y = (first_row_to_display->y - first_reusable_row->y
12439 + WINDOW_HEADER_LINE_HEIGHT (w));
12440
12441 /* Display lines beginning with first_row_to_display in the
12442 desired matrix. Set last_text_row to the last row displayed
12443 that displays text. */
12444 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12445 if (pt_row == NULL)
12446 w->cursor.vpos = -1;
12447 last_text_row = NULL;
12448 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12449 if (display_line (&it))
12450 last_text_row = it.glyph_row - 1;
12451
12452 /* Give up If point isn't in a row displayed or reused. */
12453 if (w->cursor.vpos < 0)
12454 {
12455 clear_glyph_matrix (w->desired_matrix);
12456 return 0;
12457 }
12458
12459 /* If point is in a reused row, adjust y and vpos of the cursor
12460 position. */
12461 if (pt_row)
12462 {
12463 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12464 w->current_matrix);
12465 w->cursor.y -= first_reusable_row->y;
12466 }
12467
12468 /* Scroll the display. */
12469 run.current_y = first_reusable_row->y;
12470 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12471 run.height = it.last_visible_y - run.current_y;
12472 dy = run.current_y - run.desired_y;
12473
12474 if (run.height)
12475 {
12476 struct frame *f = XFRAME (WINDOW_FRAME (w));
12477 update_begin (f);
12478 rif->update_window_begin_hook (w);
12479 rif->clear_window_mouse_face (w);
12480 rif->scroll_run_hook (w, &run);
12481 rif->update_window_end_hook (w, 0, 0);
12482 update_end (f);
12483 }
12484
12485 /* Adjust Y positions of reused rows. */
12486 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12487 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12488 max_y = it.last_visible_y;
12489 for (row = first_reusable_row; row < first_row_to_display; ++row)
12490 {
12491 row->y -= dy;
12492 row->visible_height = row->height;
12493 if (row->y < min_y)
12494 row->visible_height -= min_y - row->y;
12495 if (row->y + row->height > max_y)
12496 row->visible_height -= row->y + row->height - max_y;
12497 }
12498
12499 /* Scroll the current matrix. */
12500 xassert (nrows_scrolled > 0);
12501 rotate_matrix (w->current_matrix,
12502 start_vpos,
12503 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12504 -nrows_scrolled);
12505
12506 /* Disable rows not reused. */
12507 for (row -= nrows_scrolled; row < bottom_row; ++row)
12508 row->enabled_p = 0;
12509
12510 /* Adjust window end. A null value of last_text_row means that
12511 the window end is in reused rows which in turn means that
12512 only its vpos can have changed. */
12513 if (last_text_row)
12514 {
12515 w->window_end_bytepos
12516 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12517 w->window_end_pos
12518 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12519 w->window_end_vpos
12520 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12521 }
12522 else
12523 {
12524 w->window_end_vpos
12525 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12526 }
12527
12528 w->window_end_valid = Qnil;
12529 w->desired_matrix->no_scrolling_p = 1;
12530
12531 #if GLYPH_DEBUG
12532 debug_method_add (w, "try_window_reusing_current_matrix 2");
12533 #endif
12534 return 1;
12535 }
12536
12537 return 0;
12538 }
12539
12540
12541 \f
12542 /************************************************************************
12543 Window redisplay reusing current matrix when buffer has changed
12544 ************************************************************************/
12545
12546 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12547 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12548 int *, int *));
12549 static struct glyph_row *
12550 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12551 struct glyph_row *));
12552
12553
12554 /* Return the last row in MATRIX displaying text. If row START is
12555 non-null, start searching with that row. IT gives the dimensions
12556 of the display. Value is null if matrix is empty; otherwise it is
12557 a pointer to the row found. */
12558
12559 static struct glyph_row *
12560 find_last_row_displaying_text (matrix, it, start)
12561 struct glyph_matrix *matrix;
12562 struct it *it;
12563 struct glyph_row *start;
12564 {
12565 struct glyph_row *row, *row_found;
12566
12567 /* Set row_found to the last row in IT->w's current matrix
12568 displaying text. The loop looks funny but think of partially
12569 visible lines. */
12570 row_found = NULL;
12571 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12572 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12573 {
12574 xassert (row->enabled_p);
12575 row_found = row;
12576 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12577 break;
12578 ++row;
12579 }
12580
12581 return row_found;
12582 }
12583
12584
12585 /* Return the last row in the current matrix of W that is not affected
12586 by changes at the start of current_buffer that occurred since W's
12587 current matrix was built. Value is null if no such row exists.
12588
12589 BEG_UNCHANGED us the number of characters unchanged at the start of
12590 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12591 first changed character in current_buffer. Characters at positions <
12592 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12593 when the current matrix was built. */
12594
12595 static struct glyph_row *
12596 find_last_unchanged_at_beg_row (w)
12597 struct window *w;
12598 {
12599 int first_changed_pos = BEG + BEG_UNCHANGED;
12600 struct glyph_row *row;
12601 struct glyph_row *row_found = NULL;
12602 int yb = window_text_bottom_y (w);
12603
12604 /* Find the last row displaying unchanged text. */
12605 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12606 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12607 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12608 {
12609 if (/* If row ends before first_changed_pos, it is unchanged,
12610 except in some case. */
12611 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12612 /* When row ends in ZV and we write at ZV it is not
12613 unchanged. */
12614 && !row->ends_at_zv_p
12615 /* When first_changed_pos is the end of a continued line,
12616 row is not unchanged because it may be no longer
12617 continued. */
12618 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12619 && row->continued_p))
12620 row_found = row;
12621
12622 /* Stop if last visible row. */
12623 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12624 break;
12625
12626 ++row;
12627 }
12628
12629 return row_found;
12630 }
12631
12632
12633 /* Find the first glyph row in the current matrix of W that is not
12634 affected by changes at the end of current_buffer since the
12635 time W's current matrix was built.
12636
12637 Return in *DELTA the number of chars by which buffer positions in
12638 unchanged text at the end of current_buffer must be adjusted.
12639
12640 Return in *DELTA_BYTES the corresponding number of bytes.
12641
12642 Value is null if no such row exists, i.e. all rows are affected by
12643 changes. */
12644
12645 static struct glyph_row *
12646 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12647 struct window *w;
12648 int *delta, *delta_bytes;
12649 {
12650 struct glyph_row *row;
12651 struct glyph_row *row_found = NULL;
12652
12653 *delta = *delta_bytes = 0;
12654
12655 /* Display must not have been paused, otherwise the current matrix
12656 is not up to date. */
12657 if (NILP (w->window_end_valid))
12658 abort ();
12659
12660 /* A value of window_end_pos >= END_UNCHANGED means that the window
12661 end is in the range of changed text. If so, there is no
12662 unchanged row at the end of W's current matrix. */
12663 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12664 return NULL;
12665
12666 /* Set row to the last row in W's current matrix displaying text. */
12667 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12668
12669 /* If matrix is entirely empty, no unchanged row exists. */
12670 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12671 {
12672 /* The value of row is the last glyph row in the matrix having a
12673 meaningful buffer position in it. The end position of row
12674 corresponds to window_end_pos. This allows us to translate
12675 buffer positions in the current matrix to current buffer
12676 positions for characters not in changed text. */
12677 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12678 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12679 int last_unchanged_pos, last_unchanged_pos_old;
12680 struct glyph_row *first_text_row
12681 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12682
12683 *delta = Z - Z_old;
12684 *delta_bytes = Z_BYTE - Z_BYTE_old;
12685
12686 /* Set last_unchanged_pos to the buffer position of the last
12687 character in the buffer that has not been changed. Z is the
12688 index + 1 of the last character in current_buffer, i.e. by
12689 subtracting END_UNCHANGED we get the index of the last
12690 unchanged character, and we have to add BEG to get its buffer
12691 position. */
12692 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12693 last_unchanged_pos_old = last_unchanged_pos - *delta;
12694
12695 /* Search backward from ROW for a row displaying a line that
12696 starts at a minimum position >= last_unchanged_pos_old. */
12697 for (; row > first_text_row; --row)
12698 {
12699 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12700 abort ();
12701
12702 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12703 row_found = row;
12704 }
12705 }
12706
12707 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12708 abort ();
12709
12710 return row_found;
12711 }
12712
12713
12714 /* Make sure that glyph rows in the current matrix of window W
12715 reference the same glyph memory as corresponding rows in the
12716 frame's frame matrix. This function is called after scrolling W's
12717 current matrix on a terminal frame in try_window_id and
12718 try_window_reusing_current_matrix. */
12719
12720 static void
12721 sync_frame_with_window_matrix_rows (w)
12722 struct window *w;
12723 {
12724 struct frame *f = XFRAME (w->frame);
12725 struct glyph_row *window_row, *window_row_end, *frame_row;
12726
12727 /* Preconditions: W must be a leaf window and full-width. Its frame
12728 must have a frame matrix. */
12729 xassert (NILP (w->hchild) && NILP (w->vchild));
12730 xassert (WINDOW_FULL_WIDTH_P (w));
12731 xassert (!FRAME_WINDOW_P (f));
12732
12733 /* If W is a full-width window, glyph pointers in W's current matrix
12734 have, by definition, to be the same as glyph pointers in the
12735 corresponding frame matrix. Note that frame matrices have no
12736 marginal areas (see build_frame_matrix). */
12737 window_row = w->current_matrix->rows;
12738 window_row_end = window_row + w->current_matrix->nrows;
12739 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12740 while (window_row < window_row_end)
12741 {
12742 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12743 struct glyph *end = window_row->glyphs[LAST_AREA];
12744
12745 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12746 frame_row->glyphs[TEXT_AREA] = start;
12747 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12748 frame_row->glyphs[LAST_AREA] = end;
12749
12750 /* Disable frame rows whose corresponding window rows have
12751 been disabled in try_window_id. */
12752 if (!window_row->enabled_p)
12753 frame_row->enabled_p = 0;
12754
12755 ++window_row, ++frame_row;
12756 }
12757 }
12758
12759
12760 /* Find the glyph row in window W containing CHARPOS. Consider all
12761 rows between START and END (not inclusive). END null means search
12762 all rows to the end of the display area of W. Value is the row
12763 containing CHARPOS or null. */
12764
12765 struct glyph_row *
12766 row_containing_pos (w, charpos, start, end, dy)
12767 struct window *w;
12768 int charpos;
12769 struct glyph_row *start, *end;
12770 int dy;
12771 {
12772 struct glyph_row *row = start;
12773 int last_y;
12774
12775 /* If we happen to start on a header-line, skip that. */
12776 if (row->mode_line_p)
12777 ++row;
12778
12779 if ((end && row >= end) || !row->enabled_p)
12780 return NULL;
12781
12782 last_y = window_text_bottom_y (w) - dy;
12783
12784 while (1)
12785 {
12786 /* Give up if we have gone too far. */
12787 if (end && row >= end)
12788 return NULL;
12789 /* This formerly returned if they were equal.
12790 I think that both quantities are of a "last plus one" type;
12791 if so, when they are equal, the row is within the screen. -- rms. */
12792 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12793 return NULL;
12794
12795 /* If it is in this row, return this row. */
12796 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12797 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12798 /* The end position of a row equals the start
12799 position of the next row. If CHARPOS is there, we
12800 would rather display it in the next line, except
12801 when this line ends in ZV. */
12802 && !row->ends_at_zv_p
12803 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12804 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12805 return row;
12806 ++row;
12807 }
12808 }
12809
12810
12811 /* Try to redisplay window W by reusing its existing display. W's
12812 current matrix must be up to date when this function is called,
12813 i.e. window_end_valid must not be nil.
12814
12815 Value is
12816
12817 1 if display has been updated
12818 0 if otherwise unsuccessful
12819 -1 if redisplay with same window start is known not to succeed
12820
12821 The following steps are performed:
12822
12823 1. Find the last row in the current matrix of W that is not
12824 affected by changes at the start of current_buffer. If no such row
12825 is found, give up.
12826
12827 2. Find the first row in W's current matrix that is not affected by
12828 changes at the end of current_buffer. Maybe there is no such row.
12829
12830 3. Display lines beginning with the row + 1 found in step 1 to the
12831 row found in step 2 or, if step 2 didn't find a row, to the end of
12832 the window.
12833
12834 4. If cursor is not known to appear on the window, give up.
12835
12836 5. If display stopped at the row found in step 2, scroll the
12837 display and current matrix as needed.
12838
12839 6. Maybe display some lines at the end of W, if we must. This can
12840 happen under various circumstances, like a partially visible line
12841 becoming fully visible, or because newly displayed lines are displayed
12842 in smaller font sizes.
12843
12844 7. Update W's window end information. */
12845
12846 static int
12847 try_window_id (w)
12848 struct window *w;
12849 {
12850 struct frame *f = XFRAME (w->frame);
12851 struct glyph_matrix *current_matrix = w->current_matrix;
12852 struct glyph_matrix *desired_matrix = w->desired_matrix;
12853 struct glyph_row *last_unchanged_at_beg_row;
12854 struct glyph_row *first_unchanged_at_end_row;
12855 struct glyph_row *row;
12856 struct glyph_row *bottom_row;
12857 int bottom_vpos;
12858 struct it it;
12859 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12860 struct text_pos start_pos;
12861 struct run run;
12862 int first_unchanged_at_end_vpos = 0;
12863 struct glyph_row *last_text_row, *last_text_row_at_end;
12864 struct text_pos start;
12865 int first_changed_charpos, last_changed_charpos;
12866
12867 #if GLYPH_DEBUG
12868 if (inhibit_try_window_id)
12869 return 0;
12870 #endif
12871
12872 /* This is handy for debugging. */
12873 #if 0
12874 #define GIVE_UP(X) \
12875 do { \
12876 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12877 return 0; \
12878 } while (0)
12879 #else
12880 #define GIVE_UP(X) return 0
12881 #endif
12882
12883 SET_TEXT_POS_FROM_MARKER (start, w->start);
12884
12885 /* Don't use this for mini-windows because these can show
12886 messages and mini-buffers, and we don't handle that here. */
12887 if (MINI_WINDOW_P (w))
12888 GIVE_UP (1);
12889
12890 /* This flag is used to prevent redisplay optimizations. */
12891 if (windows_or_buffers_changed || cursor_type_changed)
12892 GIVE_UP (2);
12893
12894 /* Verify that narrowing has not changed.
12895 Also verify that we were not told to prevent redisplay optimizations.
12896 It would be nice to further
12897 reduce the number of cases where this prevents try_window_id. */
12898 if (current_buffer->clip_changed
12899 || current_buffer->prevent_redisplay_optimizations_p)
12900 GIVE_UP (3);
12901
12902 /* Window must either use window-based redisplay or be full width. */
12903 if (!FRAME_WINDOW_P (f)
12904 && (!line_ins_del_ok
12905 || !WINDOW_FULL_WIDTH_P (w)))
12906 GIVE_UP (4);
12907
12908 /* Give up if point is not known NOT to appear in W. */
12909 if (PT < CHARPOS (start))
12910 GIVE_UP (5);
12911
12912 /* Another way to prevent redisplay optimizations. */
12913 if (XFASTINT (w->last_modified) == 0)
12914 GIVE_UP (6);
12915
12916 /* Verify that window is not hscrolled. */
12917 if (XFASTINT (w->hscroll) != 0)
12918 GIVE_UP (7);
12919
12920 /* Verify that display wasn't paused. */
12921 if (NILP (w->window_end_valid))
12922 GIVE_UP (8);
12923
12924 /* Can't use this if highlighting a region because a cursor movement
12925 will do more than just set the cursor. */
12926 if (!NILP (Vtransient_mark_mode)
12927 && !NILP (current_buffer->mark_active))
12928 GIVE_UP (9);
12929
12930 /* Likewise if highlighting trailing whitespace. */
12931 if (!NILP (Vshow_trailing_whitespace))
12932 GIVE_UP (11);
12933
12934 /* Likewise if showing a region. */
12935 if (!NILP (w->region_showing))
12936 GIVE_UP (10);
12937
12938 /* Can use this if overlay arrow position and or string have changed. */
12939 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
12940 || !EQ (last_arrow_string, Voverlay_arrow_string))
12941 GIVE_UP (12);
12942
12943
12944 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12945 only if buffer has really changed. The reason is that the gap is
12946 initially at Z for freshly visited files. The code below would
12947 set end_unchanged to 0 in that case. */
12948 if (MODIFF > SAVE_MODIFF
12949 /* This seems to happen sometimes after saving a buffer. */
12950 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12951 {
12952 if (GPT - BEG < BEG_UNCHANGED)
12953 BEG_UNCHANGED = GPT - BEG;
12954 if (Z - GPT < END_UNCHANGED)
12955 END_UNCHANGED = Z - GPT;
12956 }
12957
12958 /* The position of the first and last character that has been changed. */
12959 first_changed_charpos = BEG + BEG_UNCHANGED;
12960 last_changed_charpos = Z - END_UNCHANGED;
12961
12962 /* If window starts after a line end, and the last change is in
12963 front of that newline, then changes don't affect the display.
12964 This case happens with stealth-fontification. Note that although
12965 the display is unchanged, glyph positions in the matrix have to
12966 be adjusted, of course. */
12967 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12968 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12969 && ((last_changed_charpos < CHARPOS (start)
12970 && CHARPOS (start) == BEGV)
12971 || (last_changed_charpos < CHARPOS (start) - 1
12972 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12973 {
12974 int Z_old, delta, Z_BYTE_old, delta_bytes;
12975 struct glyph_row *r0;
12976
12977 /* Compute how many chars/bytes have been added to or removed
12978 from the buffer. */
12979 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12980 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12981 delta = Z - Z_old;
12982 delta_bytes = Z_BYTE - Z_BYTE_old;
12983
12984 /* Give up if PT is not in the window. Note that it already has
12985 been checked at the start of try_window_id that PT is not in
12986 front of the window start. */
12987 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12988 GIVE_UP (13);
12989
12990 /* If window start is unchanged, we can reuse the whole matrix
12991 as is, after adjusting glyph positions. No need to compute
12992 the window end again, since its offset from Z hasn't changed. */
12993 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12994 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12995 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
12996 /* PT must not be in a partially visible line. */
12997 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
12998 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12999 {
13000 /* Adjust positions in the glyph matrix. */
13001 if (delta || delta_bytes)
13002 {
13003 struct glyph_row *r1
13004 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13005 increment_matrix_positions (w->current_matrix,
13006 MATRIX_ROW_VPOS (r0, current_matrix),
13007 MATRIX_ROW_VPOS (r1, current_matrix),
13008 delta, delta_bytes);
13009 }
13010
13011 /* Set the cursor. */
13012 row = row_containing_pos (w, PT, r0, NULL, 0);
13013 if (row)
13014 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13015 else
13016 abort ();
13017 return 1;
13018 }
13019 }
13020
13021 /* Handle the case that changes are all below what is displayed in
13022 the window, and that PT is in the window. This shortcut cannot
13023 be taken if ZV is visible in the window, and text has been added
13024 there that is visible in the window. */
13025 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13026 /* ZV is not visible in the window, or there are no
13027 changes at ZV, actually. */
13028 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13029 || first_changed_charpos == last_changed_charpos))
13030 {
13031 struct glyph_row *r0;
13032
13033 /* Give up if PT is not in the window. Note that it already has
13034 been checked at the start of try_window_id that PT is not in
13035 front of the window start. */
13036 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13037 GIVE_UP (14);
13038
13039 /* If window start is unchanged, we can reuse the whole matrix
13040 as is, without changing glyph positions since no text has
13041 been added/removed in front of the window end. */
13042 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13043 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13044 /* PT must not be in a partially visible line. */
13045 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13046 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13047 {
13048 /* We have to compute the window end anew since text
13049 can have been added/removed after it. */
13050 w->window_end_pos
13051 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13052 w->window_end_bytepos
13053 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13054
13055 /* Set the cursor. */
13056 row = row_containing_pos (w, PT, r0, NULL, 0);
13057 if (row)
13058 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13059 else
13060 abort ();
13061 return 2;
13062 }
13063 }
13064
13065 /* Give up if window start is in the changed area.
13066
13067 The condition used to read
13068
13069 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13070
13071 but why that was tested escapes me at the moment. */
13072 if (CHARPOS (start) >= first_changed_charpos
13073 && CHARPOS (start) <= last_changed_charpos)
13074 GIVE_UP (15);
13075
13076 /* Check that window start agrees with the start of the first glyph
13077 row in its current matrix. Check this after we know the window
13078 start is not in changed text, otherwise positions would not be
13079 comparable. */
13080 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13081 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13082 GIVE_UP (16);
13083
13084 /* Give up if the window ends in strings. Overlay strings
13085 at the end are difficult to handle, so don't try. */
13086 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13087 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13088 GIVE_UP (20);
13089
13090 /* Compute the position at which we have to start displaying new
13091 lines. Some of the lines at the top of the window might be
13092 reusable because they are not displaying changed text. Find the
13093 last row in W's current matrix not affected by changes at the
13094 start of current_buffer. Value is null if changes start in the
13095 first line of window. */
13096 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13097 if (last_unchanged_at_beg_row)
13098 {
13099 /* Avoid starting to display in the moddle of a character, a TAB
13100 for instance. This is easier than to set up the iterator
13101 exactly, and it's not a frequent case, so the additional
13102 effort wouldn't really pay off. */
13103 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13104 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13105 && last_unchanged_at_beg_row > w->current_matrix->rows)
13106 --last_unchanged_at_beg_row;
13107
13108 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13109 GIVE_UP (17);
13110
13111 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13112 GIVE_UP (18);
13113 start_pos = it.current.pos;
13114
13115 /* Start displaying new lines in the desired matrix at the same
13116 vpos we would use in the current matrix, i.e. below
13117 last_unchanged_at_beg_row. */
13118 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13119 current_matrix);
13120 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13121 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13122
13123 xassert (it.hpos == 0 && it.current_x == 0);
13124 }
13125 else
13126 {
13127 /* There are no reusable lines at the start of the window.
13128 Start displaying in the first line. */
13129 start_display (&it, w, start);
13130 start_pos = it.current.pos;
13131 }
13132
13133 /* Find the first row that is not affected by changes at the end of
13134 the buffer. Value will be null if there is no unchanged row, in
13135 which case we must redisplay to the end of the window. delta
13136 will be set to the value by which buffer positions beginning with
13137 first_unchanged_at_end_row have to be adjusted due to text
13138 changes. */
13139 first_unchanged_at_end_row
13140 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13141 IF_DEBUG (debug_delta = delta);
13142 IF_DEBUG (debug_delta_bytes = delta_bytes);
13143
13144 /* Set stop_pos to the buffer position up to which we will have to
13145 display new lines. If first_unchanged_at_end_row != NULL, this
13146 is the buffer position of the start of the line displayed in that
13147 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13148 that we don't stop at a buffer position. */
13149 stop_pos = 0;
13150 if (first_unchanged_at_end_row)
13151 {
13152 xassert (last_unchanged_at_beg_row == NULL
13153 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13154
13155 /* If this is a continuation line, move forward to the next one
13156 that isn't. Changes in lines above affect this line.
13157 Caution: this may move first_unchanged_at_end_row to a row
13158 not displaying text. */
13159 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13160 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13161 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13162 < it.last_visible_y))
13163 ++first_unchanged_at_end_row;
13164
13165 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13166 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13167 >= it.last_visible_y))
13168 first_unchanged_at_end_row = NULL;
13169 else
13170 {
13171 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13172 + delta);
13173 first_unchanged_at_end_vpos
13174 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13175 xassert (stop_pos >= Z - END_UNCHANGED);
13176 }
13177 }
13178 else if (last_unchanged_at_beg_row == NULL)
13179 GIVE_UP (19);
13180
13181
13182 #if GLYPH_DEBUG
13183
13184 /* Either there is no unchanged row at the end, or the one we have
13185 now displays text. This is a necessary condition for the window
13186 end pos calculation at the end of this function. */
13187 xassert (first_unchanged_at_end_row == NULL
13188 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13189
13190 debug_last_unchanged_at_beg_vpos
13191 = (last_unchanged_at_beg_row
13192 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13193 : -1);
13194 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13195
13196 #endif /* GLYPH_DEBUG != 0 */
13197
13198
13199 /* Display new lines. Set last_text_row to the last new line
13200 displayed which has text on it, i.e. might end up as being the
13201 line where the window_end_vpos is. */
13202 w->cursor.vpos = -1;
13203 last_text_row = NULL;
13204 overlay_arrow_seen = 0;
13205 while (it.current_y < it.last_visible_y
13206 && !fonts_changed_p
13207 && (first_unchanged_at_end_row == NULL
13208 || IT_CHARPOS (it) < stop_pos))
13209 {
13210 if (display_line (&it))
13211 last_text_row = it.glyph_row - 1;
13212 }
13213
13214 if (fonts_changed_p)
13215 return -1;
13216
13217
13218 /* Compute differences in buffer positions, y-positions etc. for
13219 lines reused at the bottom of the window. Compute what we can
13220 scroll. */
13221 if (first_unchanged_at_end_row
13222 /* No lines reused because we displayed everything up to the
13223 bottom of the window. */
13224 && it.current_y < it.last_visible_y)
13225 {
13226 dvpos = (it.vpos
13227 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13228 current_matrix));
13229 dy = it.current_y - first_unchanged_at_end_row->y;
13230 run.current_y = first_unchanged_at_end_row->y;
13231 run.desired_y = run.current_y + dy;
13232 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13233 }
13234 else
13235 {
13236 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13237 first_unchanged_at_end_row = NULL;
13238 }
13239 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13240
13241
13242 /* Find the cursor if not already found. We have to decide whether
13243 PT will appear on this window (it sometimes doesn't, but this is
13244 not a very frequent case.) This decision has to be made before
13245 the current matrix is altered. A value of cursor.vpos < 0 means
13246 that PT is either in one of the lines beginning at
13247 first_unchanged_at_end_row or below the window. Don't care for
13248 lines that might be displayed later at the window end; as
13249 mentioned, this is not a frequent case. */
13250 if (w->cursor.vpos < 0)
13251 {
13252 /* Cursor in unchanged rows at the top? */
13253 if (PT < CHARPOS (start_pos)
13254 && last_unchanged_at_beg_row)
13255 {
13256 row = row_containing_pos (w, PT,
13257 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13258 last_unchanged_at_beg_row + 1, 0);
13259 if (row)
13260 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13261 }
13262
13263 /* Start from first_unchanged_at_end_row looking for PT. */
13264 else if (first_unchanged_at_end_row)
13265 {
13266 row = row_containing_pos (w, PT - delta,
13267 first_unchanged_at_end_row, NULL, 0);
13268 if (row)
13269 set_cursor_from_row (w, row, w->current_matrix, delta,
13270 delta_bytes, dy, dvpos);
13271 }
13272
13273 /* Give up if cursor was not found. */
13274 if (w->cursor.vpos < 0)
13275 {
13276 clear_glyph_matrix (w->desired_matrix);
13277 return -1;
13278 }
13279 }
13280
13281 /* Don't let the cursor end in the scroll margins. */
13282 {
13283 int this_scroll_margin, cursor_height;
13284
13285 this_scroll_margin = max (0, scroll_margin);
13286 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13287 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13288 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13289
13290 if ((w->cursor.y < this_scroll_margin
13291 && CHARPOS (start) > BEGV)
13292 /* Don't take scroll margin into account at the bottom because
13293 old redisplay didn't do it either. */
13294 || w->cursor.y + cursor_height > it.last_visible_y)
13295 {
13296 w->cursor.vpos = -1;
13297 clear_glyph_matrix (w->desired_matrix);
13298 return -1;
13299 }
13300 }
13301
13302 /* Scroll the display. Do it before changing the current matrix so
13303 that xterm.c doesn't get confused about where the cursor glyph is
13304 found. */
13305 if (dy && run.height)
13306 {
13307 update_begin (f);
13308
13309 if (FRAME_WINDOW_P (f))
13310 {
13311 rif->update_window_begin_hook (w);
13312 rif->clear_window_mouse_face (w);
13313 rif->scroll_run_hook (w, &run);
13314 rif->update_window_end_hook (w, 0, 0);
13315 }
13316 else
13317 {
13318 /* Terminal frame. In this case, dvpos gives the number of
13319 lines to scroll by; dvpos < 0 means scroll up. */
13320 int first_unchanged_at_end_vpos
13321 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13322 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13323 int end = (WINDOW_TOP_EDGE_LINE (w)
13324 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13325 + window_internal_height (w));
13326
13327 /* Perform the operation on the screen. */
13328 if (dvpos > 0)
13329 {
13330 /* Scroll last_unchanged_at_beg_row to the end of the
13331 window down dvpos lines. */
13332 set_terminal_window (end);
13333
13334 /* On dumb terminals delete dvpos lines at the end
13335 before inserting dvpos empty lines. */
13336 if (!scroll_region_ok)
13337 ins_del_lines (end - dvpos, -dvpos);
13338
13339 /* Insert dvpos empty lines in front of
13340 last_unchanged_at_beg_row. */
13341 ins_del_lines (from, dvpos);
13342 }
13343 else if (dvpos < 0)
13344 {
13345 /* Scroll up last_unchanged_at_beg_vpos to the end of
13346 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13347 set_terminal_window (end);
13348
13349 /* Delete dvpos lines in front of
13350 last_unchanged_at_beg_vpos. ins_del_lines will set
13351 the cursor to the given vpos and emit |dvpos| delete
13352 line sequences. */
13353 ins_del_lines (from + dvpos, dvpos);
13354
13355 /* On a dumb terminal insert dvpos empty lines at the
13356 end. */
13357 if (!scroll_region_ok)
13358 ins_del_lines (end + dvpos, -dvpos);
13359 }
13360
13361 set_terminal_window (0);
13362 }
13363
13364 update_end (f);
13365 }
13366
13367 /* Shift reused rows of the current matrix to the right position.
13368 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13369 text. */
13370 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13371 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13372 if (dvpos < 0)
13373 {
13374 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13375 bottom_vpos, dvpos);
13376 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13377 bottom_vpos, 0);
13378 }
13379 else if (dvpos > 0)
13380 {
13381 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13382 bottom_vpos, dvpos);
13383 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13384 first_unchanged_at_end_vpos + dvpos, 0);
13385 }
13386
13387 /* For frame-based redisplay, make sure that current frame and window
13388 matrix are in sync with respect to glyph memory. */
13389 if (!FRAME_WINDOW_P (f))
13390 sync_frame_with_window_matrix_rows (w);
13391
13392 /* Adjust buffer positions in reused rows. */
13393 if (delta)
13394 increment_matrix_positions (current_matrix,
13395 first_unchanged_at_end_vpos + dvpos,
13396 bottom_vpos, delta, delta_bytes);
13397
13398 /* Adjust Y positions. */
13399 if (dy)
13400 shift_glyph_matrix (w, current_matrix,
13401 first_unchanged_at_end_vpos + dvpos,
13402 bottom_vpos, dy);
13403
13404 if (first_unchanged_at_end_row)
13405 first_unchanged_at_end_row += dvpos;
13406
13407 /* If scrolling up, there may be some lines to display at the end of
13408 the window. */
13409 last_text_row_at_end = NULL;
13410 if (dy < 0)
13411 {
13412 /* Scrolling up can leave for example a partially visible line
13413 at the end of the window to be redisplayed. */
13414 /* Set last_row to the glyph row in the current matrix where the
13415 window end line is found. It has been moved up or down in
13416 the matrix by dvpos. */
13417 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13418 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13419
13420 /* If last_row is the window end line, it should display text. */
13421 xassert (last_row->displays_text_p);
13422
13423 /* If window end line was partially visible before, begin
13424 displaying at that line. Otherwise begin displaying with the
13425 line following it. */
13426 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13427 {
13428 init_to_row_start (&it, w, last_row);
13429 it.vpos = last_vpos;
13430 it.current_y = last_row->y;
13431 }
13432 else
13433 {
13434 init_to_row_end (&it, w, last_row);
13435 it.vpos = 1 + last_vpos;
13436 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13437 ++last_row;
13438 }
13439
13440 /* We may start in a continuation line. If so, we have to
13441 get the right continuation_lines_width and current_x. */
13442 it.continuation_lines_width = last_row->continuation_lines_width;
13443 it.hpos = it.current_x = 0;
13444
13445 /* Display the rest of the lines at the window end. */
13446 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13447 while (it.current_y < it.last_visible_y
13448 && !fonts_changed_p)
13449 {
13450 /* Is it always sure that the display agrees with lines in
13451 the current matrix? I don't think so, so we mark rows
13452 displayed invalid in the current matrix by setting their
13453 enabled_p flag to zero. */
13454 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13455 if (display_line (&it))
13456 last_text_row_at_end = it.glyph_row - 1;
13457 }
13458 }
13459
13460 /* Update window_end_pos and window_end_vpos. */
13461 if (first_unchanged_at_end_row
13462 && first_unchanged_at_end_row->y < it.last_visible_y
13463 && !last_text_row_at_end)
13464 {
13465 /* Window end line if one of the preserved rows from the current
13466 matrix. Set row to the last row displaying text in current
13467 matrix starting at first_unchanged_at_end_row, after
13468 scrolling. */
13469 xassert (first_unchanged_at_end_row->displays_text_p);
13470 row = find_last_row_displaying_text (w->current_matrix, &it,
13471 first_unchanged_at_end_row);
13472 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13473
13474 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13475 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13476 w->window_end_vpos
13477 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13478 xassert (w->window_end_bytepos >= 0);
13479 IF_DEBUG (debug_method_add (w, "A"));
13480 }
13481 else if (last_text_row_at_end)
13482 {
13483 w->window_end_pos
13484 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13485 w->window_end_bytepos
13486 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13487 w->window_end_vpos
13488 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13489 xassert (w->window_end_bytepos >= 0);
13490 IF_DEBUG (debug_method_add (w, "B"));
13491 }
13492 else if (last_text_row)
13493 {
13494 /* We have displayed either to the end of the window or at the
13495 end of the window, i.e. the last row with text is to be found
13496 in the desired matrix. */
13497 w->window_end_pos
13498 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13499 w->window_end_bytepos
13500 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13501 w->window_end_vpos
13502 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13503 xassert (w->window_end_bytepos >= 0);
13504 }
13505 else if (first_unchanged_at_end_row == NULL
13506 && last_text_row == NULL
13507 && last_text_row_at_end == NULL)
13508 {
13509 /* Displayed to end of window, but no line containing text was
13510 displayed. Lines were deleted at the end of the window. */
13511 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13512 int vpos = XFASTINT (w->window_end_vpos);
13513 struct glyph_row *current_row = current_matrix->rows + vpos;
13514 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13515
13516 for (row = NULL;
13517 row == NULL && vpos >= first_vpos;
13518 --vpos, --current_row, --desired_row)
13519 {
13520 if (desired_row->enabled_p)
13521 {
13522 if (desired_row->displays_text_p)
13523 row = desired_row;
13524 }
13525 else if (current_row->displays_text_p)
13526 row = current_row;
13527 }
13528
13529 xassert (row != NULL);
13530 w->window_end_vpos = make_number (vpos + 1);
13531 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13532 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13533 xassert (w->window_end_bytepos >= 0);
13534 IF_DEBUG (debug_method_add (w, "C"));
13535 }
13536 else
13537 abort ();
13538
13539 #if 0 /* This leads to problems, for instance when the cursor is
13540 at ZV, and the cursor line displays no text. */
13541 /* Disable rows below what's displayed in the window. This makes
13542 debugging easier. */
13543 enable_glyph_matrix_rows (current_matrix,
13544 XFASTINT (w->window_end_vpos) + 1,
13545 bottom_vpos, 0);
13546 #endif
13547
13548 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13549 debug_end_vpos = XFASTINT (w->window_end_vpos));
13550
13551 /* Record that display has not been completed. */
13552 w->window_end_valid = Qnil;
13553 w->desired_matrix->no_scrolling_p = 1;
13554 return 3;
13555
13556 #undef GIVE_UP
13557 }
13558
13559
13560 \f
13561 /***********************************************************************
13562 More debugging support
13563 ***********************************************************************/
13564
13565 #if GLYPH_DEBUG
13566
13567 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13568 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13569 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13570
13571
13572 /* Dump the contents of glyph matrix MATRIX on stderr.
13573
13574 GLYPHS 0 means don't show glyph contents.
13575 GLYPHS 1 means show glyphs in short form
13576 GLYPHS > 1 means show glyphs in long form. */
13577
13578 void
13579 dump_glyph_matrix (matrix, glyphs)
13580 struct glyph_matrix *matrix;
13581 int glyphs;
13582 {
13583 int i;
13584 for (i = 0; i < matrix->nrows; ++i)
13585 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13586 }
13587
13588
13589 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13590 the glyph row and area where the glyph comes from. */
13591
13592 void
13593 dump_glyph (row, glyph, area)
13594 struct glyph_row *row;
13595 struct glyph *glyph;
13596 int area;
13597 {
13598 if (glyph->type == CHAR_GLYPH)
13599 {
13600 fprintf (stderr,
13601 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13602 glyph - row->glyphs[TEXT_AREA],
13603 'C',
13604 glyph->charpos,
13605 (BUFFERP (glyph->object)
13606 ? 'B'
13607 : (STRINGP (glyph->object)
13608 ? 'S'
13609 : '-')),
13610 glyph->pixel_width,
13611 glyph->u.ch,
13612 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13613 ? glyph->u.ch
13614 : '.'),
13615 glyph->face_id,
13616 glyph->left_box_line_p,
13617 glyph->right_box_line_p);
13618 }
13619 else if (glyph->type == STRETCH_GLYPH)
13620 {
13621 fprintf (stderr,
13622 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13623 glyph - row->glyphs[TEXT_AREA],
13624 'S',
13625 glyph->charpos,
13626 (BUFFERP (glyph->object)
13627 ? 'B'
13628 : (STRINGP (glyph->object)
13629 ? 'S'
13630 : '-')),
13631 glyph->pixel_width,
13632 0,
13633 '.',
13634 glyph->face_id,
13635 glyph->left_box_line_p,
13636 glyph->right_box_line_p);
13637 }
13638 else if (glyph->type == IMAGE_GLYPH)
13639 {
13640 fprintf (stderr,
13641 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13642 glyph - row->glyphs[TEXT_AREA],
13643 'I',
13644 glyph->charpos,
13645 (BUFFERP (glyph->object)
13646 ? 'B'
13647 : (STRINGP (glyph->object)
13648 ? 'S'
13649 : '-')),
13650 glyph->pixel_width,
13651 glyph->u.img_id,
13652 '.',
13653 glyph->face_id,
13654 glyph->left_box_line_p,
13655 glyph->right_box_line_p);
13656 }
13657 }
13658
13659
13660 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13661 GLYPHS 0 means don't show glyph contents.
13662 GLYPHS 1 means show glyphs in short form
13663 GLYPHS > 1 means show glyphs in long form. */
13664
13665 void
13666 dump_glyph_row (row, vpos, glyphs)
13667 struct glyph_row *row;
13668 int vpos, glyphs;
13669 {
13670 if (glyphs != 1)
13671 {
13672 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13673 fprintf (stderr, "=======================================================================\n");
13674
13675 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13676 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13677 vpos,
13678 MATRIX_ROW_START_CHARPOS (row),
13679 MATRIX_ROW_END_CHARPOS (row),
13680 row->used[TEXT_AREA],
13681 row->contains_overlapping_glyphs_p,
13682 row->enabled_p,
13683 row->truncated_on_left_p,
13684 row->truncated_on_right_p,
13685 row->overlay_arrow_p,
13686 row->continued_p,
13687 MATRIX_ROW_CONTINUATION_LINE_P (row),
13688 row->displays_text_p,
13689 row->ends_at_zv_p,
13690 row->fill_line_p,
13691 row->ends_in_middle_of_char_p,
13692 row->starts_in_middle_of_char_p,
13693 row->mouse_face_p,
13694 row->x,
13695 row->y,
13696 row->pixel_width,
13697 row->height,
13698 row->visible_height,
13699 row->ascent,
13700 row->phys_ascent);
13701 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13702 row->end.overlay_string_index,
13703 row->continuation_lines_width);
13704 fprintf (stderr, "%9d %5d\n",
13705 CHARPOS (row->start.string_pos),
13706 CHARPOS (row->end.string_pos));
13707 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13708 row->end.dpvec_index);
13709 }
13710
13711 if (glyphs > 1)
13712 {
13713 int area;
13714
13715 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13716 {
13717 struct glyph *glyph = row->glyphs[area];
13718 struct glyph *glyph_end = glyph + row->used[area];
13719
13720 /* Glyph for a line end in text. */
13721 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13722 ++glyph_end;
13723
13724 if (glyph < glyph_end)
13725 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13726
13727 for (; glyph < glyph_end; ++glyph)
13728 dump_glyph (row, glyph, area);
13729 }
13730 }
13731 else if (glyphs == 1)
13732 {
13733 int area;
13734
13735 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13736 {
13737 char *s = (char *) alloca (row->used[area] + 1);
13738 int i;
13739
13740 for (i = 0; i < row->used[area]; ++i)
13741 {
13742 struct glyph *glyph = row->glyphs[area] + i;
13743 if (glyph->type == CHAR_GLYPH
13744 && glyph->u.ch < 0x80
13745 && glyph->u.ch >= ' ')
13746 s[i] = glyph->u.ch;
13747 else
13748 s[i] = '.';
13749 }
13750
13751 s[i] = '\0';
13752 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13753 }
13754 }
13755 }
13756
13757
13758 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13759 Sdump_glyph_matrix, 0, 1, "p",
13760 doc: /* Dump the current matrix of the selected window to stderr.
13761 Shows contents of glyph row structures. With non-nil
13762 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13763 glyphs in short form, otherwise show glyphs in long form. */)
13764 (glyphs)
13765 Lisp_Object glyphs;
13766 {
13767 struct window *w = XWINDOW (selected_window);
13768 struct buffer *buffer = XBUFFER (w->buffer);
13769
13770 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13771 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13772 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13773 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13774 fprintf (stderr, "=============================================\n");
13775 dump_glyph_matrix (w->current_matrix,
13776 NILP (glyphs) ? 0 : XINT (glyphs));
13777 return Qnil;
13778 }
13779
13780
13781 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13782 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13783 ()
13784 {
13785 struct frame *f = XFRAME (selected_frame);
13786 dump_glyph_matrix (f->current_matrix, 1);
13787 return Qnil;
13788 }
13789
13790
13791 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13792 doc: /* Dump glyph row ROW to stderr.
13793 GLYPH 0 means don't dump glyphs.
13794 GLYPH 1 means dump glyphs in short form.
13795 GLYPH > 1 or omitted means dump glyphs in long form. */)
13796 (row, glyphs)
13797 Lisp_Object row, glyphs;
13798 {
13799 struct glyph_matrix *matrix;
13800 int vpos;
13801
13802 CHECK_NUMBER (row);
13803 matrix = XWINDOW (selected_window)->current_matrix;
13804 vpos = XINT (row);
13805 if (vpos >= 0 && vpos < matrix->nrows)
13806 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13807 vpos,
13808 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13809 return Qnil;
13810 }
13811
13812
13813 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13814 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13815 GLYPH 0 means don't dump glyphs.
13816 GLYPH 1 means dump glyphs in short form.
13817 GLYPH > 1 or omitted means dump glyphs in long form. */)
13818 (row, glyphs)
13819 Lisp_Object row, glyphs;
13820 {
13821 struct frame *sf = SELECTED_FRAME ();
13822 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13823 int vpos;
13824
13825 CHECK_NUMBER (row);
13826 vpos = XINT (row);
13827 if (vpos >= 0 && vpos < m->nrows)
13828 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13829 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13830 return Qnil;
13831 }
13832
13833
13834 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13835 doc: /* Toggle tracing of redisplay.
13836 With ARG, turn tracing on if and only if ARG is positive. */)
13837 (arg)
13838 Lisp_Object arg;
13839 {
13840 if (NILP (arg))
13841 trace_redisplay_p = !trace_redisplay_p;
13842 else
13843 {
13844 arg = Fprefix_numeric_value (arg);
13845 trace_redisplay_p = XINT (arg) > 0;
13846 }
13847
13848 return Qnil;
13849 }
13850
13851
13852 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13853 doc: /* Like `format', but print result to stderr.
13854 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13855 (nargs, args)
13856 int nargs;
13857 Lisp_Object *args;
13858 {
13859 Lisp_Object s = Fformat (nargs, args);
13860 fprintf (stderr, "%s", SDATA (s));
13861 return Qnil;
13862 }
13863
13864 #endif /* GLYPH_DEBUG */
13865
13866
13867 \f
13868 /***********************************************************************
13869 Building Desired Matrix Rows
13870 ***********************************************************************/
13871
13872 /* Return a temporary glyph row holding the glyphs of an overlay
13873 arrow. Only used for non-window-redisplay windows. */
13874
13875 static struct glyph_row *
13876 get_overlay_arrow_glyph_row (w)
13877 struct window *w;
13878 {
13879 struct frame *f = XFRAME (WINDOW_FRAME (w));
13880 struct buffer *buffer = XBUFFER (w->buffer);
13881 struct buffer *old = current_buffer;
13882 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13883 int arrow_len = SCHARS (Voverlay_arrow_string);
13884 const unsigned char *arrow_end = arrow_string + arrow_len;
13885 const unsigned char *p;
13886 struct it it;
13887 int multibyte_p;
13888 int n_glyphs_before;
13889
13890 set_buffer_temp (buffer);
13891 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13892 it.glyph_row->used[TEXT_AREA] = 0;
13893 SET_TEXT_POS (it.position, 0, 0);
13894
13895 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13896 p = arrow_string;
13897 while (p < arrow_end)
13898 {
13899 Lisp_Object face, ilisp;
13900
13901 /* Get the next character. */
13902 if (multibyte_p)
13903 it.c = string_char_and_length (p, arrow_len, &it.len);
13904 else
13905 it.c = *p, it.len = 1;
13906 p += it.len;
13907
13908 /* Get its face. */
13909 ilisp = make_number (p - arrow_string);
13910 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
13911 it.face_id = compute_char_face (f, it.c, face);
13912
13913 /* Compute its width, get its glyphs. */
13914 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13915 SET_TEXT_POS (it.position, -1, -1);
13916 PRODUCE_GLYPHS (&it);
13917
13918 /* If this character doesn't fit any more in the line, we have
13919 to remove some glyphs. */
13920 if (it.current_x > it.last_visible_x)
13921 {
13922 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13923 break;
13924 }
13925 }
13926
13927 set_buffer_temp (old);
13928 return it.glyph_row;
13929 }
13930
13931
13932 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13933 glyphs are only inserted for terminal frames since we can't really
13934 win with truncation glyphs when partially visible glyphs are
13935 involved. Which glyphs to insert is determined by
13936 produce_special_glyphs. */
13937
13938 static void
13939 insert_left_trunc_glyphs (it)
13940 struct it *it;
13941 {
13942 struct it truncate_it;
13943 struct glyph *from, *end, *to, *toend;
13944
13945 xassert (!FRAME_WINDOW_P (it->f));
13946
13947 /* Get the truncation glyphs. */
13948 truncate_it = *it;
13949 truncate_it.current_x = 0;
13950 truncate_it.face_id = DEFAULT_FACE_ID;
13951 truncate_it.glyph_row = &scratch_glyph_row;
13952 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13953 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13954 truncate_it.object = make_number (0);
13955 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13956
13957 /* Overwrite glyphs from IT with truncation glyphs. */
13958 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13959 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13960 to = it->glyph_row->glyphs[TEXT_AREA];
13961 toend = to + it->glyph_row->used[TEXT_AREA];
13962
13963 while (from < end)
13964 *to++ = *from++;
13965
13966 /* There may be padding glyphs left over. Overwrite them too. */
13967 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13968 {
13969 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13970 while (from < end)
13971 *to++ = *from++;
13972 }
13973
13974 if (to > toend)
13975 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13976 }
13977
13978
13979 /* Compute the pixel height and width of IT->glyph_row.
13980
13981 Most of the time, ascent and height of a display line will be equal
13982 to the max_ascent and max_height values of the display iterator
13983 structure. This is not the case if
13984
13985 1. We hit ZV without displaying anything. In this case, max_ascent
13986 and max_height will be zero.
13987
13988 2. We have some glyphs that don't contribute to the line height.
13989 (The glyph row flag contributes_to_line_height_p is for future
13990 pixmap extensions).
13991
13992 The first case is easily covered by using default values because in
13993 these cases, the line height does not really matter, except that it
13994 must not be zero. */
13995
13996 static void
13997 compute_line_metrics (it)
13998 struct it *it;
13999 {
14000 struct glyph_row *row = it->glyph_row;
14001 int area, i;
14002
14003 if (FRAME_WINDOW_P (it->f))
14004 {
14005 int i, min_y, max_y;
14006
14007 /* The line may consist of one space only, that was added to
14008 place the cursor on it. If so, the row's height hasn't been
14009 computed yet. */
14010 if (row->height == 0)
14011 {
14012 if (it->max_ascent + it->max_descent == 0)
14013 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14014 row->ascent = it->max_ascent;
14015 row->height = it->max_ascent + it->max_descent;
14016 row->phys_ascent = it->max_phys_ascent;
14017 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14018 }
14019
14020 /* Compute the width of this line. */
14021 row->pixel_width = row->x;
14022 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14023 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14024
14025 xassert (row->pixel_width >= 0);
14026 xassert (row->ascent >= 0 && row->height > 0);
14027
14028 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14029 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14030
14031 /* If first line's physical ascent is larger than its logical
14032 ascent, use the physical ascent, and make the row taller.
14033 This makes accented characters fully visible. */
14034 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14035 && row->phys_ascent > row->ascent)
14036 {
14037 row->height += row->phys_ascent - row->ascent;
14038 row->ascent = row->phys_ascent;
14039 }
14040
14041 /* Compute how much of the line is visible. */
14042 row->visible_height = row->height;
14043
14044 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14045 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14046
14047 if (row->y < min_y)
14048 row->visible_height -= min_y - row->y;
14049 if (row->y + row->height > max_y)
14050 row->visible_height -= row->y + row->height - max_y;
14051 }
14052 else
14053 {
14054 row->pixel_width = row->used[TEXT_AREA];
14055 if (row->continued_p)
14056 row->pixel_width -= it->continuation_pixel_width;
14057 else if (row->truncated_on_right_p)
14058 row->pixel_width -= it->truncation_pixel_width;
14059 row->ascent = row->phys_ascent = 0;
14060 row->height = row->phys_height = row->visible_height = 1;
14061 }
14062
14063 /* Compute a hash code for this row. */
14064 row->hash = 0;
14065 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14066 for (i = 0; i < row->used[area]; ++i)
14067 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14068 + row->glyphs[area][i].u.val
14069 + row->glyphs[area][i].face_id
14070 + row->glyphs[area][i].padding_p
14071 + (row->glyphs[area][i].type << 2));
14072
14073 it->max_ascent = it->max_descent = 0;
14074 it->max_phys_ascent = it->max_phys_descent = 0;
14075 }
14076
14077
14078 /* Append one space to the glyph row of iterator IT if doing a
14079 window-based redisplay. DEFAULT_FACE_P non-zero means let the
14080 space have the default face, otherwise let it have the same face as
14081 IT->face_id. Value is non-zero if a space was added.
14082
14083 This function is called to make sure that there is always one glyph
14084 at the end of a glyph row that the cursor can be set on under
14085 window-systems. (If there weren't such a glyph we would not know
14086 how wide and tall a box cursor should be displayed).
14087
14088 At the same time this space let's a nicely handle clearing to the
14089 end of the line if the row ends in italic text. */
14090
14091 static int
14092 append_space (it, default_face_p)
14093 struct it *it;
14094 int default_face_p;
14095 {
14096 if (FRAME_WINDOW_P (it->f))
14097 {
14098 int n = it->glyph_row->used[TEXT_AREA];
14099
14100 if (it->glyph_row->glyphs[TEXT_AREA] + n
14101 < it->glyph_row->glyphs[1 + TEXT_AREA])
14102 {
14103 /* Save some values that must not be changed.
14104 Must save IT->c and IT->len because otherwise
14105 ITERATOR_AT_END_P wouldn't work anymore after
14106 append_space has been called. */
14107 enum display_element_type saved_what = it->what;
14108 int saved_c = it->c, saved_len = it->len;
14109 int saved_x = it->current_x;
14110 int saved_face_id = it->face_id;
14111 struct text_pos saved_pos;
14112 Lisp_Object saved_object;
14113 struct face *face;
14114
14115 saved_object = it->object;
14116 saved_pos = it->position;
14117
14118 it->what = IT_CHARACTER;
14119 bzero (&it->position, sizeof it->position);
14120 it->object = make_number (0);
14121 it->c = ' ';
14122 it->len = 1;
14123
14124 if (default_face_p)
14125 it->face_id = DEFAULT_FACE_ID;
14126 else if (it->face_before_selective_p)
14127 it->face_id = it->saved_face_id;
14128 face = FACE_FROM_ID (it->f, it->face_id);
14129 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
14130
14131 PRODUCE_GLYPHS (it);
14132
14133 it->current_x = saved_x;
14134 it->object = saved_object;
14135 it->position = saved_pos;
14136 it->what = saved_what;
14137 it->face_id = saved_face_id;
14138 it->len = saved_len;
14139 it->c = saved_c;
14140 return 1;
14141 }
14142 }
14143
14144 return 0;
14145 }
14146
14147
14148 /* Extend the face of the last glyph in the text area of IT->glyph_row
14149 to the end of the display line. Called from display_line.
14150 If the glyph row is empty, add a space glyph to it so that we
14151 know the face to draw. Set the glyph row flag fill_line_p. */
14152
14153 static void
14154 extend_face_to_end_of_line (it)
14155 struct it *it;
14156 {
14157 struct face *face;
14158 struct frame *f = it->f;
14159
14160 /* If line is already filled, do nothing. */
14161 if (it->current_x >= it->last_visible_x)
14162 return;
14163
14164 /* Face extension extends the background and box of IT->face_id
14165 to the end of the line. If the background equals the background
14166 of the frame, we don't have to do anything. */
14167 if (it->face_before_selective_p)
14168 face = FACE_FROM_ID (it->f, it->saved_face_id);
14169 else
14170 face = FACE_FROM_ID (f, it->face_id);
14171
14172 if (FRAME_WINDOW_P (f)
14173 && face->box == FACE_NO_BOX
14174 && face->background == FRAME_BACKGROUND_PIXEL (f)
14175 && !face->stipple)
14176 return;
14177
14178 /* Set the glyph row flag indicating that the face of the last glyph
14179 in the text area has to be drawn to the end of the text area. */
14180 it->glyph_row->fill_line_p = 1;
14181
14182 /* If current character of IT is not ASCII, make sure we have the
14183 ASCII face. This will be automatically undone the next time
14184 get_next_display_element returns a multibyte character. Note
14185 that the character will always be single byte in unibyte text. */
14186 if (!ASCII_CHAR_P (it->c))
14187 {
14188 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
14189 }
14190
14191 if (FRAME_WINDOW_P (f))
14192 {
14193 /* If the row is empty, add a space with the current face of IT,
14194 so that we know which face to draw. */
14195 if (it->glyph_row->used[TEXT_AREA] == 0)
14196 {
14197 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14198 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14199 it->glyph_row->used[TEXT_AREA] = 1;
14200 }
14201 }
14202 else
14203 {
14204 /* Save some values that must not be changed. */
14205 int saved_x = it->current_x;
14206 struct text_pos saved_pos;
14207 Lisp_Object saved_object;
14208 enum display_element_type saved_what = it->what;
14209 int saved_face_id = it->face_id;
14210
14211 saved_object = it->object;
14212 saved_pos = it->position;
14213
14214 it->what = IT_CHARACTER;
14215 bzero (&it->position, sizeof it->position);
14216 it->object = make_number (0);
14217 it->c = ' ';
14218 it->len = 1;
14219 it->face_id = face->id;
14220
14221 PRODUCE_GLYPHS (it);
14222
14223 while (it->current_x <= it->last_visible_x)
14224 PRODUCE_GLYPHS (it);
14225
14226 /* Don't count these blanks really. It would let us insert a left
14227 truncation glyph below and make us set the cursor on them, maybe. */
14228 it->current_x = saved_x;
14229 it->object = saved_object;
14230 it->position = saved_pos;
14231 it->what = saved_what;
14232 it->face_id = saved_face_id;
14233 }
14234 }
14235
14236
14237 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14238 trailing whitespace. */
14239
14240 static int
14241 trailing_whitespace_p (charpos)
14242 int charpos;
14243 {
14244 int bytepos = CHAR_TO_BYTE (charpos);
14245 int c = 0;
14246
14247 while (bytepos < ZV_BYTE
14248 && (c = FETCH_CHAR (bytepos),
14249 c == ' ' || c == '\t'))
14250 ++bytepos;
14251
14252 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14253 {
14254 if (bytepos != PT_BYTE)
14255 return 1;
14256 }
14257 return 0;
14258 }
14259
14260
14261 /* Highlight trailing whitespace, if any, in ROW. */
14262
14263 void
14264 highlight_trailing_whitespace (f, row)
14265 struct frame *f;
14266 struct glyph_row *row;
14267 {
14268 int used = row->used[TEXT_AREA];
14269
14270 if (used)
14271 {
14272 struct glyph *start = row->glyphs[TEXT_AREA];
14273 struct glyph *glyph = start + used - 1;
14274
14275 /* Skip over glyphs inserted to display the cursor at the
14276 end of a line, for extending the face of the last glyph
14277 to the end of the line on terminals, and for truncation
14278 and continuation glyphs. */
14279 while (glyph >= start
14280 && glyph->type == CHAR_GLYPH
14281 && INTEGERP (glyph->object))
14282 --glyph;
14283
14284 /* If last glyph is a space or stretch, and it's trailing
14285 whitespace, set the face of all trailing whitespace glyphs in
14286 IT->glyph_row to `trailing-whitespace'. */
14287 if (glyph >= start
14288 && BUFFERP (glyph->object)
14289 && (glyph->type == STRETCH_GLYPH
14290 || (glyph->type == CHAR_GLYPH
14291 && glyph->u.ch == ' '))
14292 && trailing_whitespace_p (glyph->charpos))
14293 {
14294 int face_id = lookup_named_face (f, Qtrailing_whitespace);
14295
14296 while (glyph >= start
14297 && BUFFERP (glyph->object)
14298 && (glyph->type == STRETCH_GLYPH
14299 || (glyph->type == CHAR_GLYPH
14300 && glyph->u.ch == ' ')))
14301 (glyph--)->face_id = face_id;
14302 }
14303 }
14304 }
14305
14306
14307 /* Value is non-zero if glyph row ROW in window W should be
14308 used to hold the cursor. */
14309
14310 static int
14311 cursor_row_p (w, row)
14312 struct window *w;
14313 struct glyph_row *row;
14314 {
14315 int cursor_row_p = 1;
14316
14317 if (PT == MATRIX_ROW_END_CHARPOS (row))
14318 {
14319 /* If the row ends with a newline from a string, we don't want
14320 the cursor there (if the row is continued it doesn't end in a
14321 newline). */
14322 if (CHARPOS (row->end.string_pos) >= 0
14323 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14324 cursor_row_p = row->continued_p;
14325
14326 /* If the row ends at ZV, display the cursor at the end of that
14327 row instead of at the start of the row below. */
14328 else if (row->ends_at_zv_p)
14329 cursor_row_p = 1;
14330 else
14331 cursor_row_p = 0;
14332 }
14333
14334 return cursor_row_p;
14335 }
14336
14337
14338 /* Construct the glyph row IT->glyph_row in the desired matrix of
14339 IT->w from text at the current position of IT. See dispextern.h
14340 for an overview of struct it. Value is non-zero if
14341 IT->glyph_row displays text, as opposed to a line displaying ZV
14342 only. */
14343
14344 static int
14345 display_line (it)
14346 struct it *it;
14347 {
14348 struct glyph_row *row = it->glyph_row;
14349
14350 /* We always start displaying at hpos zero even if hscrolled. */
14351 xassert (it->hpos == 0 && it->current_x == 0);
14352
14353 /* We must not display in a row that's not a text row. */
14354 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14355 < it->w->desired_matrix->nrows);
14356
14357 /* Is IT->w showing the region? */
14358 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14359
14360 /* Clear the result glyph row and enable it. */
14361 prepare_desired_row (row);
14362
14363 row->y = it->current_y;
14364 row->start = it->current;
14365 row->continuation_lines_width = it->continuation_lines_width;
14366 row->displays_text_p = 1;
14367 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14368 it->starts_in_middle_of_char_p = 0;
14369
14370 /* Arrange the overlays nicely for our purposes. Usually, we call
14371 display_line on only one line at a time, in which case this
14372 can't really hurt too much, or we call it on lines which appear
14373 one after another in the buffer, in which case all calls to
14374 recenter_overlay_lists but the first will be pretty cheap. */
14375 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14376
14377 /* Move over display elements that are not visible because we are
14378 hscrolled. This may stop at an x-position < IT->first_visible_x
14379 if the first glyph is partially visible or if we hit a line end. */
14380 if (it->current_x < it->first_visible_x)
14381 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14382 MOVE_TO_POS | MOVE_TO_X);
14383
14384 /* Get the initial row height. This is either the height of the
14385 text hscrolled, if there is any, or zero. */
14386 row->ascent = it->max_ascent;
14387 row->height = it->max_ascent + it->max_descent;
14388 row->phys_ascent = it->max_phys_ascent;
14389 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14390
14391 /* Loop generating characters. The loop is left with IT on the next
14392 character to display. */
14393 while (1)
14394 {
14395 int n_glyphs_before, hpos_before, x_before;
14396 int x, i, nglyphs;
14397 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14398
14399 /* Retrieve the next thing to display. Value is zero if end of
14400 buffer reached. */
14401 if (!get_next_display_element (it))
14402 {
14403 /* Maybe add a space at the end of this line that is used to
14404 display the cursor there under X. Set the charpos of the
14405 first glyph of blank lines not corresponding to any text
14406 to -1. */
14407 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14408 || row->used[TEXT_AREA] == 0)
14409 {
14410 row->glyphs[TEXT_AREA]->charpos = -1;
14411 row->displays_text_p = 0;
14412
14413 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14414 && (!MINI_WINDOW_P (it->w)
14415 || (minibuf_level && EQ (it->window, minibuf_window))))
14416 row->indicate_empty_line_p = 1;
14417 }
14418
14419 it->continuation_lines_width = 0;
14420 row->ends_at_zv_p = 1;
14421 break;
14422 }
14423
14424 /* Now, get the metrics of what we want to display. This also
14425 generates glyphs in `row' (which is IT->glyph_row). */
14426 n_glyphs_before = row->used[TEXT_AREA];
14427 x = it->current_x;
14428
14429 /* Remember the line height so far in case the next element doesn't
14430 fit on the line. */
14431 if (!it->truncate_lines_p)
14432 {
14433 ascent = it->max_ascent;
14434 descent = it->max_descent;
14435 phys_ascent = it->max_phys_ascent;
14436 phys_descent = it->max_phys_descent;
14437 }
14438
14439 PRODUCE_GLYPHS (it);
14440
14441 /* If this display element was in marginal areas, continue with
14442 the next one. */
14443 if (it->area != TEXT_AREA)
14444 {
14445 row->ascent = max (row->ascent, it->max_ascent);
14446 row->height = max (row->height, it->max_ascent + it->max_descent);
14447 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14448 row->phys_height = max (row->phys_height,
14449 it->max_phys_ascent + it->max_phys_descent);
14450 set_iterator_to_next (it, 1);
14451 continue;
14452 }
14453
14454 /* Does the display element fit on the line? If we truncate
14455 lines, we should draw past the right edge of the window. If
14456 we don't truncate, we want to stop so that we can display the
14457 continuation glyph before the right margin. If lines are
14458 continued, there are two possible strategies for characters
14459 resulting in more than 1 glyph (e.g. tabs): Display as many
14460 glyphs as possible in this line and leave the rest for the
14461 continuation line, or display the whole element in the next
14462 line. Original redisplay did the former, so we do it also. */
14463 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14464 hpos_before = it->hpos;
14465 x_before = x;
14466
14467 if (/* Not a newline. */
14468 nglyphs > 0
14469 /* Glyphs produced fit entirely in the line. */
14470 && it->current_x < it->last_visible_x)
14471 {
14472 it->hpos += nglyphs;
14473 row->ascent = max (row->ascent, it->max_ascent);
14474 row->height = max (row->height, it->max_ascent + it->max_descent);
14475 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14476 row->phys_height = max (row->phys_height,
14477 it->max_phys_ascent + it->max_phys_descent);
14478 if (it->current_x - it->pixel_width < it->first_visible_x)
14479 row->x = x - it->first_visible_x;
14480 }
14481 else
14482 {
14483 int new_x;
14484 struct glyph *glyph;
14485
14486 for (i = 0; i < nglyphs; ++i, x = new_x)
14487 {
14488 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14489 new_x = x + glyph->pixel_width;
14490
14491 if (/* Lines are continued. */
14492 !it->truncate_lines_p
14493 && (/* Glyph doesn't fit on the line. */
14494 new_x > it->last_visible_x
14495 /* Or it fits exactly on a window system frame. */
14496 || (new_x == it->last_visible_x
14497 && FRAME_WINDOW_P (it->f))))
14498 {
14499 /* End of a continued line. */
14500
14501 if (it->hpos == 0
14502 || (new_x == it->last_visible_x
14503 && FRAME_WINDOW_P (it->f)))
14504 {
14505 /* Current glyph is the only one on the line or
14506 fits exactly on the line. We must continue
14507 the line because we can't draw the cursor
14508 after the glyph. */
14509 row->continued_p = 1;
14510 it->current_x = new_x;
14511 it->continuation_lines_width += new_x;
14512 ++it->hpos;
14513 if (i == nglyphs - 1)
14514 set_iterator_to_next (it, 1);
14515 }
14516 else if (CHAR_GLYPH_PADDING_P (*glyph)
14517 && !FRAME_WINDOW_P (it->f))
14518 {
14519 /* A padding glyph that doesn't fit on this line.
14520 This means the whole character doesn't fit
14521 on the line. */
14522 row->used[TEXT_AREA] = n_glyphs_before;
14523
14524 /* Fill the rest of the row with continuation
14525 glyphs like in 20.x. */
14526 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14527 < row->glyphs[1 + TEXT_AREA])
14528 produce_special_glyphs (it, IT_CONTINUATION);
14529
14530 row->continued_p = 1;
14531 it->current_x = x_before;
14532 it->continuation_lines_width += x_before;
14533
14534 /* Restore the height to what it was before the
14535 element not fitting on the line. */
14536 it->max_ascent = ascent;
14537 it->max_descent = descent;
14538 it->max_phys_ascent = phys_ascent;
14539 it->max_phys_descent = phys_descent;
14540 }
14541 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14542 {
14543 /* A TAB that extends past the right edge of the
14544 window. This produces a single glyph on
14545 window system frames. We leave the glyph in
14546 this row and let it fill the row, but don't
14547 consume the TAB. */
14548 it->continuation_lines_width += it->last_visible_x;
14549 row->ends_in_middle_of_char_p = 1;
14550 row->continued_p = 1;
14551 glyph->pixel_width = it->last_visible_x - x;
14552 it->starts_in_middle_of_char_p = 1;
14553 }
14554 else
14555 {
14556 /* Something other than a TAB that draws past
14557 the right edge of the window. Restore
14558 positions to values before the element. */
14559 row->used[TEXT_AREA] = n_glyphs_before + i;
14560
14561 /* Display continuation glyphs. */
14562 if (!FRAME_WINDOW_P (it->f))
14563 produce_special_glyphs (it, IT_CONTINUATION);
14564 row->continued_p = 1;
14565
14566 it->continuation_lines_width += x;
14567
14568 if (nglyphs > 1 && i > 0)
14569 {
14570 row->ends_in_middle_of_char_p = 1;
14571 it->starts_in_middle_of_char_p = 1;
14572 }
14573
14574 /* Restore the height to what it was before the
14575 element not fitting on the line. */
14576 it->max_ascent = ascent;
14577 it->max_descent = descent;
14578 it->max_phys_ascent = phys_ascent;
14579 it->max_phys_descent = phys_descent;
14580 }
14581
14582 break;
14583 }
14584 else if (new_x > it->first_visible_x)
14585 {
14586 /* Increment number of glyphs actually displayed. */
14587 ++it->hpos;
14588
14589 if (x < it->first_visible_x)
14590 /* Glyph is partially visible, i.e. row starts at
14591 negative X position. */
14592 row->x = x - it->first_visible_x;
14593 }
14594 else
14595 {
14596 /* Glyph is completely off the left margin of the
14597 window. This should not happen because of the
14598 move_it_in_display_line at the start of this
14599 function, unless the text display area of the
14600 window is empty. */
14601 xassert (it->first_visible_x <= it->last_visible_x);
14602 }
14603 }
14604
14605 row->ascent = max (row->ascent, it->max_ascent);
14606 row->height = max (row->height, it->max_ascent + it->max_descent);
14607 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14608 row->phys_height = max (row->phys_height,
14609 it->max_phys_ascent + it->max_phys_descent);
14610
14611 /* End of this display line if row is continued. */
14612 if (row->continued_p)
14613 break;
14614 }
14615
14616 /* Is this a line end? If yes, we're also done, after making
14617 sure that a non-default face is extended up to the right
14618 margin of the window. */
14619 if (ITERATOR_AT_END_OF_LINE_P (it))
14620 {
14621 int used_before = row->used[TEXT_AREA];
14622
14623 row->ends_in_newline_from_string_p = STRINGP (it->object);
14624
14625 /* Add a space at the end of the line that is used to
14626 display the cursor there. */
14627 append_space (it, 0);
14628
14629 /* Extend the face to the end of the line. */
14630 extend_face_to_end_of_line (it);
14631
14632 /* Make sure we have the position. */
14633 if (used_before == 0)
14634 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14635
14636 /* Consume the line end. This skips over invisible lines. */
14637 set_iterator_to_next (it, 1);
14638 it->continuation_lines_width = 0;
14639 break;
14640 }
14641
14642 /* Proceed with next display element. Note that this skips
14643 over lines invisible because of selective display. */
14644 set_iterator_to_next (it, 1);
14645
14646 /* If we truncate lines, we are done when the last displayed
14647 glyphs reach past the right margin of the window. */
14648 if (it->truncate_lines_p
14649 && (FRAME_WINDOW_P (it->f)
14650 ? (it->current_x >= it->last_visible_x)
14651 : (it->current_x > it->last_visible_x)))
14652 {
14653 /* Maybe add truncation glyphs. */
14654 if (!FRAME_WINDOW_P (it->f))
14655 {
14656 int i, n;
14657
14658 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14659 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14660 break;
14661
14662 for (n = row->used[TEXT_AREA]; i < n; ++i)
14663 {
14664 row->used[TEXT_AREA] = i;
14665 produce_special_glyphs (it, IT_TRUNCATION);
14666 }
14667 }
14668
14669 row->truncated_on_right_p = 1;
14670 it->continuation_lines_width = 0;
14671 reseat_at_next_visible_line_start (it, 0);
14672 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14673 it->hpos = hpos_before;
14674 it->current_x = x_before;
14675 break;
14676 }
14677 }
14678
14679 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14680 at the left window margin. */
14681 if (it->first_visible_x
14682 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14683 {
14684 if (!FRAME_WINDOW_P (it->f))
14685 insert_left_trunc_glyphs (it);
14686 row->truncated_on_left_p = 1;
14687 }
14688
14689 /* If the start of this line is the overlay arrow-position, then
14690 mark this glyph row as the one containing the overlay arrow.
14691 This is clearly a mess with variable size fonts. It would be
14692 better to let it be displayed like cursors under X. */
14693 if (MARKERP (Voverlay_arrow_position)
14694 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
14695 && (MATRIX_ROW_START_CHARPOS (row)
14696 == marker_position (Voverlay_arrow_position))
14697 && STRINGP (Voverlay_arrow_string)
14698 && ! overlay_arrow_seen)
14699 {
14700 /* Overlay arrow in window redisplay is a fringe bitmap. */
14701 if (!FRAME_WINDOW_P (it->f))
14702 {
14703 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
14704 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14705 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14706 struct glyph *p = row->glyphs[TEXT_AREA];
14707 struct glyph *p2, *end;
14708
14709 /* Copy the arrow glyphs. */
14710 while (glyph < arrow_end)
14711 *p++ = *glyph++;
14712
14713 /* Throw away padding glyphs. */
14714 p2 = p;
14715 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14716 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14717 ++p2;
14718 if (p2 > p)
14719 {
14720 while (p2 < end)
14721 *p++ = *p2++;
14722 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14723 }
14724 }
14725
14726 overlay_arrow_seen = 1;
14727 row->overlay_arrow_p = 1;
14728 }
14729
14730 /* Compute pixel dimensions of this line. */
14731 compute_line_metrics (it);
14732
14733 /* Remember the position at which this line ends. */
14734 row->end = it->current;
14735
14736 /* Maybe set the cursor. */
14737 if (it->w->cursor.vpos < 0
14738 && PT >= MATRIX_ROW_START_CHARPOS (row)
14739 && PT <= MATRIX_ROW_END_CHARPOS (row)
14740 && cursor_row_p (it->w, row))
14741 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14742
14743 /* Highlight trailing whitespace. */
14744 if (!NILP (Vshow_trailing_whitespace))
14745 highlight_trailing_whitespace (it->f, it->glyph_row);
14746
14747 /* Prepare for the next line. This line starts horizontally at (X
14748 HPOS) = (0 0). Vertical positions are incremented. As a
14749 convenience for the caller, IT->glyph_row is set to the next
14750 row to be used. */
14751 it->current_x = it->hpos = 0;
14752 it->current_y += row->height;
14753 ++it->vpos;
14754 ++it->glyph_row;
14755 return row->displays_text_p;
14756 }
14757
14758
14759 \f
14760 /***********************************************************************
14761 Menu Bar
14762 ***********************************************************************/
14763
14764 /* Redisplay the menu bar in the frame for window W.
14765
14766 The menu bar of X frames that don't have X toolkit support is
14767 displayed in a special window W->frame->menu_bar_window.
14768
14769 The menu bar of terminal frames is treated specially as far as
14770 glyph matrices are concerned. Menu bar lines are not part of
14771 windows, so the update is done directly on the frame matrix rows
14772 for the menu bar. */
14773
14774 static void
14775 display_menu_bar (w)
14776 struct window *w;
14777 {
14778 struct frame *f = XFRAME (WINDOW_FRAME (w));
14779 struct it it;
14780 Lisp_Object items;
14781 int i;
14782
14783 /* Don't do all this for graphical frames. */
14784 #ifdef HAVE_NTGUI
14785 if (!NILP (Vwindow_system))
14786 return;
14787 #endif
14788 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14789 if (FRAME_X_P (f))
14790 return;
14791 #endif
14792 #ifdef MAC_OS
14793 if (FRAME_MAC_P (f))
14794 return;
14795 #endif
14796
14797 #ifdef USE_X_TOOLKIT
14798 xassert (!FRAME_WINDOW_P (f));
14799 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14800 it.first_visible_x = 0;
14801 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14802 #else /* not USE_X_TOOLKIT */
14803 if (FRAME_WINDOW_P (f))
14804 {
14805 /* Menu bar lines are displayed in the desired matrix of the
14806 dummy window menu_bar_window. */
14807 struct window *menu_w;
14808 xassert (WINDOWP (f->menu_bar_window));
14809 menu_w = XWINDOW (f->menu_bar_window);
14810 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14811 MENU_FACE_ID);
14812 it.first_visible_x = 0;
14813 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14814 }
14815 else
14816 {
14817 /* This is a TTY frame, i.e. character hpos/vpos are used as
14818 pixel x/y. */
14819 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14820 MENU_FACE_ID);
14821 it.first_visible_x = 0;
14822 it.last_visible_x = FRAME_COLS (f);
14823 }
14824 #endif /* not USE_X_TOOLKIT */
14825
14826 if (! mode_line_inverse_video)
14827 /* Force the menu-bar to be displayed in the default face. */
14828 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14829
14830 /* Clear all rows of the menu bar. */
14831 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14832 {
14833 struct glyph_row *row = it.glyph_row + i;
14834 clear_glyph_row (row);
14835 row->enabled_p = 1;
14836 row->full_width_p = 1;
14837 }
14838
14839 /* Display all items of the menu bar. */
14840 items = FRAME_MENU_BAR_ITEMS (it.f);
14841 for (i = 0; i < XVECTOR (items)->size; i += 4)
14842 {
14843 Lisp_Object string;
14844
14845 /* Stop at nil string. */
14846 string = AREF (items, i + 1);
14847 if (NILP (string))
14848 break;
14849
14850 /* Remember where item was displayed. */
14851 AREF (items, i + 3) = make_number (it.hpos);
14852
14853 /* Display the item, pad with one space. */
14854 if (it.current_x < it.last_visible_x)
14855 display_string (NULL, string, Qnil, 0, 0, &it,
14856 SCHARS (string) + 1, 0, 0, -1);
14857 }
14858
14859 /* Fill out the line with spaces. */
14860 if (it.current_x < it.last_visible_x)
14861 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14862
14863 /* Compute the total height of the lines. */
14864 compute_line_metrics (&it);
14865 }
14866
14867
14868 \f
14869 /***********************************************************************
14870 Mode Line
14871 ***********************************************************************/
14872
14873 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14874 FORCE is non-zero, redisplay mode lines unconditionally.
14875 Otherwise, redisplay only mode lines that are garbaged. Value is
14876 the number of windows whose mode lines were redisplayed. */
14877
14878 static int
14879 redisplay_mode_lines (window, force)
14880 Lisp_Object window;
14881 int force;
14882 {
14883 int nwindows = 0;
14884
14885 while (!NILP (window))
14886 {
14887 struct window *w = XWINDOW (window);
14888
14889 if (WINDOWP (w->hchild))
14890 nwindows += redisplay_mode_lines (w->hchild, force);
14891 else if (WINDOWP (w->vchild))
14892 nwindows += redisplay_mode_lines (w->vchild, force);
14893 else if (force
14894 || FRAME_GARBAGED_P (XFRAME (w->frame))
14895 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14896 {
14897 struct text_pos lpoint;
14898 struct buffer *old = current_buffer;
14899
14900 /* Set the window's buffer for the mode line display. */
14901 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14902 set_buffer_internal_1 (XBUFFER (w->buffer));
14903
14904 /* Point refers normally to the selected window. For any
14905 other window, set up appropriate value. */
14906 if (!EQ (window, selected_window))
14907 {
14908 struct text_pos pt;
14909
14910 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14911 if (CHARPOS (pt) < BEGV)
14912 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14913 else if (CHARPOS (pt) > (ZV - 1))
14914 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14915 else
14916 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14917 }
14918
14919 /* Display mode lines. */
14920 clear_glyph_matrix (w->desired_matrix);
14921 if (display_mode_lines (w))
14922 {
14923 ++nwindows;
14924 w->must_be_updated_p = 1;
14925 }
14926
14927 /* Restore old settings. */
14928 set_buffer_internal_1 (old);
14929 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14930 }
14931
14932 window = w->next;
14933 }
14934
14935 return nwindows;
14936 }
14937
14938
14939 /* Display the mode and/or top line of window W. Value is the number
14940 of mode lines displayed. */
14941
14942 static int
14943 display_mode_lines (w)
14944 struct window *w;
14945 {
14946 Lisp_Object old_selected_window, old_selected_frame;
14947 int n = 0;
14948
14949 old_selected_frame = selected_frame;
14950 selected_frame = w->frame;
14951 old_selected_window = selected_window;
14952 XSETWINDOW (selected_window, w);
14953
14954 /* These will be set while the mode line specs are processed. */
14955 line_number_displayed = 0;
14956 w->column_number_displayed = Qnil;
14957
14958 if (WINDOW_WANTS_MODELINE_P (w))
14959 {
14960 struct window *sel_w = XWINDOW (old_selected_window);
14961
14962 /* Select mode line face based on the real selected window. */
14963 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
14964 current_buffer->mode_line_format);
14965 ++n;
14966 }
14967
14968 if (WINDOW_WANTS_HEADER_LINE_P (w))
14969 {
14970 display_mode_line (w, HEADER_LINE_FACE_ID,
14971 current_buffer->header_line_format);
14972 ++n;
14973 }
14974
14975 selected_frame = old_selected_frame;
14976 selected_window = old_selected_window;
14977 return n;
14978 }
14979
14980
14981 /* Display mode or top line of window W. FACE_ID specifies which line
14982 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14983 FORMAT is the mode line format to display. Value is the pixel
14984 height of the mode line displayed. */
14985
14986 static int
14987 display_mode_line (w, face_id, format)
14988 struct window *w;
14989 enum face_id face_id;
14990 Lisp_Object format;
14991 {
14992 struct it it;
14993 struct face *face;
14994
14995 init_iterator (&it, w, -1, -1, NULL, face_id);
14996 prepare_desired_row (it.glyph_row);
14997
14998 if (! mode_line_inverse_video)
14999 /* Force the mode-line to be displayed in the default face. */
15000 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15001
15002 /* Temporarily make frame's keyboard the current kboard so that
15003 kboard-local variables in the mode_line_format will get the right
15004 values. */
15005 push_frame_kboard (it.f);
15006 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15007 pop_frame_kboard ();
15008
15009 /* Fill up with spaces. */
15010 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15011
15012 compute_line_metrics (&it);
15013 it.glyph_row->full_width_p = 1;
15014 it.glyph_row->mode_line_p = 1;
15015 it.glyph_row->continued_p = 0;
15016 it.glyph_row->truncated_on_left_p = 0;
15017 it.glyph_row->truncated_on_right_p = 0;
15018
15019 /* Make a 3D mode-line have a shadow at its right end. */
15020 face = FACE_FROM_ID (it.f, face_id);
15021 extend_face_to_end_of_line (&it);
15022 if (face->box != FACE_NO_BOX)
15023 {
15024 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15025 + it.glyph_row->used[TEXT_AREA] - 1);
15026 last->right_box_line_p = 1;
15027 }
15028
15029 return it.glyph_row->height;
15030 }
15031
15032 /* Alist that caches the results of :propertize.
15033 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15034 Lisp_Object mode_line_proptrans_alist;
15035
15036 /* List of strings making up the mode-line. */
15037 Lisp_Object mode_line_string_list;
15038
15039 /* Base face property when building propertized mode line string. */
15040 static Lisp_Object mode_line_string_face;
15041 static Lisp_Object mode_line_string_face_prop;
15042
15043
15044 /* Contribute ELT to the mode line for window IT->w. How it
15045 translates into text depends on its data type.
15046
15047 IT describes the display environment in which we display, as usual.
15048
15049 DEPTH is the depth in recursion. It is used to prevent
15050 infinite recursion here.
15051
15052 FIELD_WIDTH is the number of characters the display of ELT should
15053 occupy in the mode line, and PRECISION is the maximum number of
15054 characters to display from ELT's representation. See
15055 display_string for details.
15056
15057 Returns the hpos of the end of the text generated by ELT.
15058
15059 PROPS is a property list to add to any string we encounter.
15060
15061 If RISKY is nonzero, remove (disregard) any properties in any string
15062 we encounter, and ignore :eval and :propertize.
15063
15064 If the global variable `frame_title_ptr' is non-NULL, then the output
15065 is passed to `store_frame_title' instead of `display_string'. */
15066
15067 static int
15068 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15069 struct it *it;
15070 int depth;
15071 int field_width, precision;
15072 Lisp_Object elt, props;
15073 int risky;
15074 {
15075 int n = 0, field, prec;
15076 int literal = 0;
15077
15078 tail_recurse:
15079 if (depth > 100)
15080 elt = build_string ("*too-deep*");
15081
15082 depth++;
15083
15084 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15085 {
15086 case Lisp_String:
15087 {
15088 /* A string: output it and check for %-constructs within it. */
15089 unsigned char c;
15090 const unsigned char *this, *lisp_string;
15091
15092 if (!NILP (props) || risky)
15093 {
15094 Lisp_Object oprops, aelt;
15095 oprops = Ftext_properties_at (make_number (0), elt);
15096
15097 if (NILP (Fequal (props, oprops)) || risky)
15098 {
15099 /* If the starting string has properties,
15100 merge the specified ones onto the existing ones. */
15101 if (! NILP (oprops) && !risky)
15102 {
15103 Lisp_Object tem;
15104
15105 oprops = Fcopy_sequence (oprops);
15106 tem = props;
15107 while (CONSP (tem))
15108 {
15109 oprops = Fplist_put (oprops, XCAR (tem),
15110 XCAR (XCDR (tem)));
15111 tem = XCDR (XCDR (tem));
15112 }
15113 props = oprops;
15114 }
15115
15116 aelt = Fassoc (elt, mode_line_proptrans_alist);
15117 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15118 {
15119 mode_line_proptrans_alist
15120 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15121 elt = XCAR (aelt);
15122 }
15123 else
15124 {
15125 Lisp_Object tem;
15126
15127 elt = Fcopy_sequence (elt);
15128 Fset_text_properties (make_number (0), Flength (elt),
15129 props, elt);
15130 /* Add this item to mode_line_proptrans_alist. */
15131 mode_line_proptrans_alist
15132 = Fcons (Fcons (elt, props),
15133 mode_line_proptrans_alist);
15134 /* Truncate mode_line_proptrans_alist
15135 to at most 50 elements. */
15136 tem = Fnthcdr (make_number (50),
15137 mode_line_proptrans_alist);
15138 if (! NILP (tem))
15139 XSETCDR (tem, Qnil);
15140 }
15141 }
15142 }
15143
15144 this = SDATA (elt);
15145 lisp_string = this;
15146
15147 if (literal)
15148 {
15149 prec = precision - n;
15150 if (frame_title_ptr)
15151 n += store_frame_title (SDATA (elt), -1, prec);
15152 else if (!NILP (mode_line_string_list))
15153 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15154 else
15155 n += display_string (NULL, elt, Qnil, 0, 0, it,
15156 0, prec, 0, STRING_MULTIBYTE (elt));
15157
15158 break;
15159 }
15160
15161 while ((precision <= 0 || n < precision)
15162 && *this
15163 && (frame_title_ptr
15164 || !NILP (mode_line_string_list)
15165 || it->current_x < it->last_visible_x))
15166 {
15167 const unsigned char *last = this;
15168
15169 /* Advance to end of string or next format specifier. */
15170 while ((c = *this++) != '\0' && c != '%')
15171 ;
15172
15173 if (this - 1 != last)
15174 {
15175 /* Output to end of string or up to '%'. Field width
15176 is length of string. Don't output more than
15177 PRECISION allows us. */
15178 --this;
15179
15180 prec = chars_in_text (last, this - last);
15181 if (precision > 0 && prec > precision - n)
15182 prec = precision - n;
15183
15184 if (frame_title_ptr)
15185 n += store_frame_title (last, 0, prec);
15186 else if (!NILP (mode_line_string_list))
15187 {
15188 int bytepos = last - lisp_string;
15189 int charpos = string_byte_to_char (elt, bytepos);
15190 n += store_mode_line_string (NULL,
15191 Fsubstring (elt, make_number (charpos),
15192 make_number (charpos + prec)),
15193 0, 0, 0, Qnil);
15194 }
15195 else
15196 {
15197 int bytepos = last - lisp_string;
15198 int charpos = string_byte_to_char (elt, bytepos);
15199 n += display_string (NULL, elt, Qnil, 0, charpos,
15200 it, 0, prec, 0,
15201 STRING_MULTIBYTE (elt));
15202 }
15203 }
15204 else /* c == '%' */
15205 {
15206 const unsigned char *percent_position = this;
15207
15208 /* Get the specified minimum width. Zero means
15209 don't pad. */
15210 field = 0;
15211 while ((c = *this++) >= '0' && c <= '9')
15212 field = field * 10 + c - '0';
15213
15214 /* Don't pad beyond the total padding allowed. */
15215 if (field_width - n > 0 && field > field_width - n)
15216 field = field_width - n;
15217
15218 /* Note that either PRECISION <= 0 or N < PRECISION. */
15219 prec = precision - n;
15220
15221 if (c == 'M')
15222 n += display_mode_element (it, depth, field, prec,
15223 Vglobal_mode_string, props,
15224 risky);
15225 else if (c != 0)
15226 {
15227 int multibyte;
15228 int bytepos, charpos;
15229 unsigned char *spec;
15230
15231 bytepos = percent_position - lisp_string;
15232 charpos = (STRING_MULTIBYTE (elt)
15233 ? string_byte_to_char (elt, bytepos)
15234 : bytepos);
15235
15236 spec
15237 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15238
15239 if (frame_title_ptr)
15240 n += store_frame_title (spec, field, prec);
15241 else if (!NILP (mode_line_string_list))
15242 {
15243 int len = strlen (spec);
15244 Lisp_Object tem = make_string (spec, len);
15245 props = Ftext_properties_at (make_number (charpos), elt);
15246 /* Should only keep face property in props */
15247 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15248 }
15249 else
15250 {
15251 int nglyphs_before, nwritten;
15252
15253 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15254 nwritten = display_string (spec, Qnil, elt,
15255 charpos, 0, it,
15256 field, prec, 0,
15257 multibyte);
15258
15259 /* Assign to the glyphs written above the
15260 string where the `%x' came from, position
15261 of the `%'. */
15262 if (nwritten > 0)
15263 {
15264 struct glyph *glyph
15265 = (it->glyph_row->glyphs[TEXT_AREA]
15266 + nglyphs_before);
15267 int i;
15268
15269 for (i = 0; i < nwritten; ++i)
15270 {
15271 glyph[i].object = elt;
15272 glyph[i].charpos = charpos;
15273 }
15274
15275 n += nwritten;
15276 }
15277 }
15278 }
15279 else /* c == 0 */
15280 break;
15281 }
15282 }
15283 }
15284 break;
15285
15286 case Lisp_Symbol:
15287 /* A symbol: process the value of the symbol recursively
15288 as if it appeared here directly. Avoid error if symbol void.
15289 Special case: if value of symbol is a string, output the string
15290 literally. */
15291 {
15292 register Lisp_Object tem;
15293
15294 /* If the variable is not marked as risky to set
15295 then its contents are risky to use. */
15296 if (NILP (Fget (elt, Qrisky_local_variable)))
15297 risky = 1;
15298
15299 tem = Fboundp (elt);
15300 if (!NILP (tem))
15301 {
15302 tem = Fsymbol_value (elt);
15303 /* If value is a string, output that string literally:
15304 don't check for % within it. */
15305 if (STRINGP (tem))
15306 literal = 1;
15307
15308 if (!EQ (tem, elt))
15309 {
15310 /* Give up right away for nil or t. */
15311 elt = tem;
15312 goto tail_recurse;
15313 }
15314 }
15315 }
15316 break;
15317
15318 case Lisp_Cons:
15319 {
15320 register Lisp_Object car, tem;
15321
15322 /* A cons cell: five distinct cases.
15323 If first element is :eval or :propertize, do something special.
15324 If first element is a string or a cons, process all the elements
15325 and effectively concatenate them.
15326 If first element is a negative number, truncate displaying cdr to
15327 at most that many characters. If positive, pad (with spaces)
15328 to at least that many characters.
15329 If first element is a symbol, process the cadr or caddr recursively
15330 according to whether the symbol's value is non-nil or nil. */
15331 car = XCAR (elt);
15332 if (EQ (car, QCeval))
15333 {
15334 /* An element of the form (:eval FORM) means evaluate FORM
15335 and use the result as mode line elements. */
15336
15337 if (risky)
15338 break;
15339
15340 if (CONSP (XCDR (elt)))
15341 {
15342 Lisp_Object spec;
15343 spec = safe_eval (XCAR (XCDR (elt)));
15344 n += display_mode_element (it, depth, field_width - n,
15345 precision - n, spec, props,
15346 risky);
15347 }
15348 }
15349 else if (EQ (car, QCpropertize))
15350 {
15351 /* An element of the form (:propertize ELT PROPS...)
15352 means display ELT but applying properties PROPS. */
15353
15354 if (risky)
15355 break;
15356
15357 if (CONSP (XCDR (elt)))
15358 n += display_mode_element (it, depth, field_width - n,
15359 precision - n, XCAR (XCDR (elt)),
15360 XCDR (XCDR (elt)), risky);
15361 }
15362 else if (SYMBOLP (car))
15363 {
15364 tem = Fboundp (car);
15365 elt = XCDR (elt);
15366 if (!CONSP (elt))
15367 goto invalid;
15368 /* elt is now the cdr, and we know it is a cons cell.
15369 Use its car if CAR has a non-nil value. */
15370 if (!NILP (tem))
15371 {
15372 tem = Fsymbol_value (car);
15373 if (!NILP (tem))
15374 {
15375 elt = XCAR (elt);
15376 goto tail_recurse;
15377 }
15378 }
15379 /* Symbol's value is nil (or symbol is unbound)
15380 Get the cddr of the original list
15381 and if possible find the caddr and use that. */
15382 elt = XCDR (elt);
15383 if (NILP (elt))
15384 break;
15385 else if (!CONSP (elt))
15386 goto invalid;
15387 elt = XCAR (elt);
15388 goto tail_recurse;
15389 }
15390 else if (INTEGERP (car))
15391 {
15392 register int lim = XINT (car);
15393 elt = XCDR (elt);
15394 if (lim < 0)
15395 {
15396 /* Negative int means reduce maximum width. */
15397 if (precision <= 0)
15398 precision = -lim;
15399 else
15400 precision = min (precision, -lim);
15401 }
15402 else if (lim > 0)
15403 {
15404 /* Padding specified. Don't let it be more than
15405 current maximum. */
15406 if (precision > 0)
15407 lim = min (precision, lim);
15408
15409 /* If that's more padding than already wanted, queue it.
15410 But don't reduce padding already specified even if
15411 that is beyond the current truncation point. */
15412 field_width = max (lim, field_width);
15413 }
15414 goto tail_recurse;
15415 }
15416 else if (STRINGP (car) || CONSP (car))
15417 {
15418 register int limit = 50;
15419 /* Limit is to protect against circular lists. */
15420 while (CONSP (elt)
15421 && --limit > 0
15422 && (precision <= 0 || n < precision))
15423 {
15424 n += display_mode_element (it, depth, field_width - n,
15425 precision - n, XCAR (elt),
15426 props, risky);
15427 elt = XCDR (elt);
15428 }
15429 }
15430 }
15431 break;
15432
15433 default:
15434 invalid:
15435 elt = build_string ("*invalid*");
15436 goto tail_recurse;
15437 }
15438
15439 /* Pad to FIELD_WIDTH. */
15440 if (field_width > 0 && n < field_width)
15441 {
15442 if (frame_title_ptr)
15443 n += store_frame_title ("", field_width - n, 0);
15444 else if (!NILP (mode_line_string_list))
15445 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15446 else
15447 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15448 0, 0, 0);
15449 }
15450
15451 return n;
15452 }
15453
15454 /* Store a mode-line string element in mode_line_string_list.
15455
15456 If STRING is non-null, display that C string. Otherwise, the Lisp
15457 string LISP_STRING is displayed.
15458
15459 FIELD_WIDTH is the minimum number of output glyphs to produce.
15460 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15461 with spaces. FIELD_WIDTH <= 0 means don't pad.
15462
15463 PRECISION is the maximum number of characters to output from
15464 STRING. PRECISION <= 0 means don't truncate the string.
15465
15466 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15467 properties to the string.
15468
15469 PROPS are the properties to add to the string.
15470 The mode_line_string_face face property is always added to the string.
15471 */
15472
15473 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15474 char *string;
15475 Lisp_Object lisp_string;
15476 int copy_string;
15477 int field_width;
15478 int precision;
15479 Lisp_Object props;
15480 {
15481 int len;
15482 int n = 0;
15483
15484 if (string != NULL)
15485 {
15486 len = strlen (string);
15487 if (precision > 0 && len > precision)
15488 len = precision;
15489 lisp_string = make_string (string, len);
15490 if (NILP (props))
15491 props = mode_line_string_face_prop;
15492 else if (!NILP (mode_line_string_face))
15493 {
15494 Lisp_Object face = Fplist_get (props, Qface);
15495 props = Fcopy_sequence (props);
15496 if (NILP (face))
15497 face = mode_line_string_face;
15498 else
15499 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15500 props = Fplist_put (props, Qface, face);
15501 }
15502 Fadd_text_properties (make_number (0), make_number (len),
15503 props, lisp_string);
15504 }
15505 else
15506 {
15507 len = XFASTINT (Flength (lisp_string));
15508 if (precision > 0 && len > precision)
15509 {
15510 len = precision;
15511 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15512 precision = -1;
15513 }
15514 if (!NILP (mode_line_string_face))
15515 {
15516 Lisp_Object face;
15517 if (NILP (props))
15518 props = Ftext_properties_at (make_number (0), lisp_string);
15519 face = Fplist_get (props, Qface);
15520 if (NILP (face))
15521 face = mode_line_string_face;
15522 else
15523 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15524 props = Fcons (Qface, Fcons (face, Qnil));
15525 if (copy_string)
15526 lisp_string = Fcopy_sequence (lisp_string);
15527 }
15528 if (!NILP (props))
15529 Fadd_text_properties (make_number (0), make_number (len),
15530 props, lisp_string);
15531 }
15532
15533 if (len > 0)
15534 {
15535 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15536 n += len;
15537 }
15538
15539 if (field_width > len)
15540 {
15541 field_width -= len;
15542 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15543 if (!NILP (props))
15544 Fadd_text_properties (make_number (0), make_number (field_width),
15545 props, lisp_string);
15546 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15547 n += field_width;
15548 }
15549
15550 return n;
15551 }
15552
15553
15554 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15555 0, 3, 0,
15556 doc: /* Return the mode-line of selected window as a string.
15557 First optional arg FORMAT specifies a different format string (see
15558 `mode-line-format' for details) to use. If FORMAT is t, return
15559 the buffer's header-line. Second optional arg WINDOW specifies a
15560 different window to use as the context for the formatting.
15561 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15562 (format, window, no_props)
15563 Lisp_Object format, window, no_props;
15564 {
15565 struct it it;
15566 int len;
15567 struct window *w;
15568 struct buffer *old_buffer = NULL;
15569 enum face_id face_id = DEFAULT_FACE_ID;
15570
15571 if (NILP (window))
15572 window = selected_window;
15573 CHECK_WINDOW (window);
15574 w = XWINDOW (window);
15575 CHECK_BUFFER (w->buffer);
15576
15577 if (XBUFFER (w->buffer) != current_buffer)
15578 {
15579 old_buffer = current_buffer;
15580 set_buffer_internal_1 (XBUFFER (w->buffer));
15581 }
15582
15583 if (NILP (format) || EQ (format, Qt))
15584 {
15585 face_id = NILP (format)
15586 ? CURRENT_MODE_LINE_FACE_ID (w) :
15587 HEADER_LINE_FACE_ID;
15588 format = NILP (format)
15589 ? current_buffer->mode_line_format
15590 : current_buffer->header_line_format;
15591 }
15592
15593 init_iterator (&it, w, -1, -1, NULL, face_id);
15594
15595 if (NILP (no_props))
15596 {
15597 mode_line_string_face =
15598 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15599 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15600 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15601
15602 mode_line_string_face_prop =
15603 NILP (mode_line_string_face) ? Qnil :
15604 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15605
15606 /* We need a dummy last element in mode_line_string_list to
15607 indicate we are building the propertized mode-line string.
15608 Using mode_line_string_face_prop here GC protects it. */
15609 mode_line_string_list =
15610 Fcons (mode_line_string_face_prop, Qnil);
15611 frame_title_ptr = NULL;
15612 }
15613 else
15614 {
15615 mode_line_string_face_prop = Qnil;
15616 mode_line_string_list = Qnil;
15617 frame_title_ptr = frame_title_buf;
15618 }
15619
15620 push_frame_kboard (it.f);
15621 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15622 pop_frame_kboard ();
15623
15624 if (old_buffer)
15625 set_buffer_internal_1 (old_buffer);
15626
15627 if (NILP (no_props))
15628 {
15629 Lisp_Object str;
15630 mode_line_string_list = Fnreverse (mode_line_string_list);
15631 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15632 make_string ("", 0));
15633 mode_line_string_face_prop = Qnil;
15634 mode_line_string_list = Qnil;
15635 return str;
15636 }
15637
15638 len = frame_title_ptr - frame_title_buf;
15639 if (len > 0 && frame_title_ptr[-1] == '-')
15640 {
15641 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15642 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15643 ;
15644 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15645 if (len > frame_title_ptr - frame_title_buf)
15646 len = frame_title_ptr - frame_title_buf;
15647 }
15648
15649 frame_title_ptr = NULL;
15650 return make_string (frame_title_buf, len);
15651 }
15652
15653 /* Write a null-terminated, right justified decimal representation of
15654 the positive integer D to BUF using a minimal field width WIDTH. */
15655
15656 static void
15657 pint2str (buf, width, d)
15658 register char *buf;
15659 register int width;
15660 register int d;
15661 {
15662 register char *p = buf;
15663
15664 if (d <= 0)
15665 *p++ = '0';
15666 else
15667 {
15668 while (d > 0)
15669 {
15670 *p++ = d % 10 + '0';
15671 d /= 10;
15672 }
15673 }
15674
15675 for (width -= (int) (p - buf); width > 0; --width)
15676 *p++ = ' ';
15677 *p-- = '\0';
15678 while (p > buf)
15679 {
15680 d = *buf;
15681 *buf++ = *p;
15682 *p-- = d;
15683 }
15684 }
15685
15686 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15687 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15688 type of CODING_SYSTEM. Return updated pointer into BUF. */
15689
15690 static unsigned char invalid_eol_type[] = "(*invalid*)";
15691
15692 static char *
15693 decode_mode_spec_coding (coding_system, buf, eol_flag)
15694 Lisp_Object coding_system;
15695 register char *buf;
15696 int eol_flag;
15697 {
15698 Lisp_Object val;
15699 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15700 const unsigned char *eol_str;
15701 int eol_str_len;
15702 /* The EOL conversion we are using. */
15703 Lisp_Object eoltype;
15704
15705 val = CODING_SYSTEM_SPEC (coding_system);
15706 eoltype = Qnil;
15707
15708 if (!VECTORP (val)) /* Not yet decided. */
15709 {
15710 if (multibyte)
15711 *buf++ = '-';
15712 if (eol_flag)
15713 eoltype = eol_mnemonic_undecided;
15714 /* Don't mention EOL conversion if it isn't decided. */
15715 }
15716 else
15717 {
15718 Lisp_Object attrs;
15719 Lisp_Object eolvalue;
15720
15721 attrs = AREF (val, 0);
15722 eolvalue = AREF (val, 2);
15723
15724 if (multibyte)
15725 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
15726
15727 if (eol_flag)
15728 {
15729 /* The EOL conversion that is normal on this system. */
15730
15731 if (NILP (eolvalue)) /* Not yet decided. */
15732 eoltype = eol_mnemonic_undecided;
15733 else if (VECTORP (eolvalue)) /* Not yet decided. */
15734 eoltype = eol_mnemonic_undecided;
15735 else /* eolvalue is Qunix, Qdos, or Qmac. */
15736 eoltype = (EQ (eolvalue, Qunix)
15737 ? eol_mnemonic_unix
15738 : (EQ (eolvalue, Qdos) == 1
15739 ? eol_mnemonic_dos : eol_mnemonic_mac));
15740 }
15741 }
15742
15743 if (eol_flag)
15744 {
15745 /* Mention the EOL conversion if it is not the usual one. */
15746 if (STRINGP (eoltype))
15747 {
15748 eol_str = SDATA (eoltype);
15749 eol_str_len = SBYTES (eoltype);
15750 }
15751 else if (CHARACTERP (eoltype))
15752 {
15753 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15754 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15755 eol_str = tmp;
15756 }
15757 else
15758 {
15759 eol_str = invalid_eol_type;
15760 eol_str_len = sizeof (invalid_eol_type) - 1;
15761 }
15762 bcopy (eol_str, buf, eol_str_len);
15763 buf += eol_str_len;
15764 }
15765
15766 return buf;
15767 }
15768
15769 /* Return a string for the output of a mode line %-spec for window W,
15770 generated by character C. PRECISION >= 0 means don't return a
15771 string longer than that value. FIELD_WIDTH > 0 means pad the
15772 string returned with spaces to that value. Return 1 in *MULTIBYTE
15773 if the result is multibyte text. */
15774
15775 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15776
15777 static char *
15778 decode_mode_spec (w, c, field_width, precision, multibyte)
15779 struct window *w;
15780 register int c;
15781 int field_width, precision;
15782 int *multibyte;
15783 {
15784 Lisp_Object obj;
15785 struct frame *f = XFRAME (WINDOW_FRAME (w));
15786 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15787 struct buffer *b = XBUFFER (w->buffer);
15788
15789 obj = Qnil;
15790 *multibyte = 0;
15791
15792 switch (c)
15793 {
15794 case '*':
15795 if (!NILP (b->read_only))
15796 return "%";
15797 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15798 return "*";
15799 return "-";
15800
15801 case '+':
15802 /* This differs from %* only for a modified read-only buffer. */
15803 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15804 return "*";
15805 if (!NILP (b->read_only))
15806 return "%";
15807 return "-";
15808
15809 case '&':
15810 /* This differs from %* in ignoring read-only-ness. */
15811 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15812 return "*";
15813 return "-";
15814
15815 case '%':
15816 return "%";
15817
15818 case '[':
15819 {
15820 int i;
15821 char *p;
15822
15823 if (command_loop_level > 5)
15824 return "[[[... ";
15825 p = decode_mode_spec_buf;
15826 for (i = 0; i < command_loop_level; i++)
15827 *p++ = '[';
15828 *p = 0;
15829 return decode_mode_spec_buf;
15830 }
15831
15832 case ']':
15833 {
15834 int i;
15835 char *p;
15836
15837 if (command_loop_level > 5)
15838 return " ...]]]";
15839 p = decode_mode_spec_buf;
15840 for (i = 0; i < command_loop_level; i++)
15841 *p++ = ']';
15842 *p = 0;
15843 return decode_mode_spec_buf;
15844 }
15845
15846 case '-':
15847 {
15848 register int i;
15849
15850 /* Let lots_of_dashes be a string of infinite length. */
15851 if (!NILP (mode_line_string_list))
15852 return "--";
15853 if (field_width <= 0
15854 || field_width > sizeof (lots_of_dashes))
15855 {
15856 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
15857 decode_mode_spec_buf[i] = '-';
15858 decode_mode_spec_buf[i] = '\0';
15859 return decode_mode_spec_buf;
15860 }
15861 else
15862 return lots_of_dashes;
15863 }
15864
15865 case 'b':
15866 obj = b->name;
15867 break;
15868
15869 case 'c':
15870 {
15871 int col = (int) current_column (); /* iftc */
15872 w->column_number_displayed = make_number (col);
15873 pint2str (decode_mode_spec_buf, field_width, col);
15874 return decode_mode_spec_buf;
15875 }
15876
15877 case 'F':
15878 /* %F displays the frame name. */
15879 if (!NILP (f->title))
15880 return (char *) SDATA (f->title);
15881 if (f->explicit_name || ! FRAME_WINDOW_P (f))
15882 return (char *) SDATA (f->name);
15883 return "Emacs";
15884
15885 case 'f':
15886 obj = b->filename;
15887 break;
15888
15889 case 'l':
15890 {
15891 int startpos = XMARKER (w->start)->charpos;
15892 int startpos_byte = marker_byte_position (w->start);
15893 int line, linepos, linepos_byte, topline;
15894 int nlines, junk;
15895 int height = WINDOW_TOTAL_LINES (w);
15896
15897 /* If we decided that this buffer isn't suitable for line numbers,
15898 don't forget that too fast. */
15899 if (EQ (w->base_line_pos, w->buffer))
15900 goto no_value;
15901 /* But do forget it, if the window shows a different buffer now. */
15902 else if (BUFFERP (w->base_line_pos))
15903 w->base_line_pos = Qnil;
15904
15905 /* If the buffer is very big, don't waste time. */
15906 if (INTEGERP (Vline_number_display_limit)
15907 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
15908 {
15909 w->base_line_pos = Qnil;
15910 w->base_line_number = Qnil;
15911 goto no_value;
15912 }
15913
15914 if (!NILP (w->base_line_number)
15915 && !NILP (w->base_line_pos)
15916 && XFASTINT (w->base_line_pos) <= startpos)
15917 {
15918 line = XFASTINT (w->base_line_number);
15919 linepos = XFASTINT (w->base_line_pos);
15920 linepos_byte = buf_charpos_to_bytepos (b, linepos);
15921 }
15922 else
15923 {
15924 line = 1;
15925 linepos = BUF_BEGV (b);
15926 linepos_byte = BUF_BEGV_BYTE (b);
15927 }
15928
15929 /* Count lines from base line to window start position. */
15930 nlines = display_count_lines (linepos, linepos_byte,
15931 startpos_byte,
15932 startpos, &junk);
15933
15934 topline = nlines + line;
15935
15936 /* Determine a new base line, if the old one is too close
15937 or too far away, or if we did not have one.
15938 "Too close" means it's plausible a scroll-down would
15939 go back past it. */
15940 if (startpos == BUF_BEGV (b))
15941 {
15942 w->base_line_number = make_number (topline);
15943 w->base_line_pos = make_number (BUF_BEGV (b));
15944 }
15945 else if (nlines < height + 25 || nlines > height * 3 + 50
15946 || linepos == BUF_BEGV (b))
15947 {
15948 int limit = BUF_BEGV (b);
15949 int limit_byte = BUF_BEGV_BYTE (b);
15950 int position;
15951 int distance = (height * 2 + 30) * line_number_display_limit_width;
15952
15953 if (startpos - distance > limit)
15954 {
15955 limit = startpos - distance;
15956 limit_byte = CHAR_TO_BYTE (limit);
15957 }
15958
15959 nlines = display_count_lines (startpos, startpos_byte,
15960 limit_byte,
15961 - (height * 2 + 30),
15962 &position);
15963 /* If we couldn't find the lines we wanted within
15964 line_number_display_limit_width chars per line,
15965 give up on line numbers for this window. */
15966 if (position == limit_byte && limit == startpos - distance)
15967 {
15968 w->base_line_pos = w->buffer;
15969 w->base_line_number = Qnil;
15970 goto no_value;
15971 }
15972
15973 w->base_line_number = make_number (topline - nlines);
15974 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
15975 }
15976
15977 /* Now count lines from the start pos to point. */
15978 nlines = display_count_lines (startpos, startpos_byte,
15979 PT_BYTE, PT, &junk);
15980
15981 /* Record that we did display the line number. */
15982 line_number_displayed = 1;
15983
15984 /* Make the string to show. */
15985 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
15986 return decode_mode_spec_buf;
15987 no_value:
15988 {
15989 char* p = decode_mode_spec_buf;
15990 int pad = field_width - 2;
15991 while (pad-- > 0)
15992 *p++ = ' ';
15993 *p++ = '?';
15994 *p++ = '?';
15995 *p = '\0';
15996 return decode_mode_spec_buf;
15997 }
15998 }
15999 break;
16000
16001 case 'm':
16002 obj = b->mode_name;
16003 break;
16004
16005 case 'n':
16006 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16007 return " Narrow";
16008 break;
16009
16010 case 'p':
16011 {
16012 int pos = marker_position (w->start);
16013 int total = BUF_ZV (b) - BUF_BEGV (b);
16014
16015 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16016 {
16017 if (pos <= BUF_BEGV (b))
16018 return "All";
16019 else
16020 return "Bottom";
16021 }
16022 else if (pos <= BUF_BEGV (b))
16023 return "Top";
16024 else
16025 {
16026 if (total > 1000000)
16027 /* Do it differently for a large value, to avoid overflow. */
16028 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16029 else
16030 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16031 /* We can't normally display a 3-digit number,
16032 so get us a 2-digit number that is close. */
16033 if (total == 100)
16034 total = 99;
16035 sprintf (decode_mode_spec_buf, "%2d%%", total);
16036 return decode_mode_spec_buf;
16037 }
16038 }
16039
16040 /* Display percentage of size above the bottom of the screen. */
16041 case 'P':
16042 {
16043 int toppos = marker_position (w->start);
16044 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16045 int total = BUF_ZV (b) - BUF_BEGV (b);
16046
16047 if (botpos >= BUF_ZV (b))
16048 {
16049 if (toppos <= BUF_BEGV (b))
16050 return "All";
16051 else
16052 return "Bottom";
16053 }
16054 else
16055 {
16056 if (total > 1000000)
16057 /* Do it differently for a large value, to avoid overflow. */
16058 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16059 else
16060 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16061 /* We can't normally display a 3-digit number,
16062 so get us a 2-digit number that is close. */
16063 if (total == 100)
16064 total = 99;
16065 if (toppos <= BUF_BEGV (b))
16066 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16067 else
16068 sprintf (decode_mode_spec_buf, "%2d%%", total);
16069 return decode_mode_spec_buf;
16070 }
16071 }
16072
16073 case 's':
16074 /* status of process */
16075 obj = Fget_buffer_process (w->buffer);
16076 if (NILP (obj))
16077 return "no process";
16078 #ifdef subprocesses
16079 obj = Fsymbol_name (Fprocess_status (obj));
16080 #endif
16081 break;
16082
16083 case 't': /* indicate TEXT or BINARY */
16084 #ifdef MODE_LINE_BINARY_TEXT
16085 return MODE_LINE_BINARY_TEXT (b);
16086 #else
16087 return "T";
16088 #endif
16089
16090 case 'z':
16091 /* coding-system (not including end-of-line format) */
16092 case 'Z':
16093 /* coding-system (including end-of-line type) */
16094 {
16095 int eol_flag = (c == 'Z');
16096 char *p = decode_mode_spec_buf;
16097
16098 if (! FRAME_WINDOW_P (f))
16099 {
16100 /* No need to mention EOL here--the terminal never needs
16101 to do EOL conversion. */
16102 p = decode_mode_spec_coding (CODING_ID_NAME (keyboard_coding.id),
16103 p, 0);
16104 p = decode_mode_spec_coding (CODING_ID_NAME (terminal_coding.id),
16105 p, 0);
16106 }
16107 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16108 p, eol_flag);
16109
16110 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16111 #ifdef subprocesses
16112 obj = Fget_buffer_process (Fcurrent_buffer ());
16113 if (PROCESSP (obj))
16114 {
16115 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16116 p, eol_flag);
16117 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16118 p, eol_flag);
16119 }
16120 #endif /* subprocesses */
16121 #endif /* 0 */
16122 *p = 0;
16123 return decode_mode_spec_buf;
16124 }
16125 }
16126
16127 if (STRINGP (obj))
16128 {
16129 *multibyte = STRING_MULTIBYTE (obj);
16130 return (char *) SDATA (obj);
16131 }
16132 else
16133 return "";
16134 }
16135
16136
16137 /* Count up to COUNT lines starting from START / START_BYTE.
16138 But don't go beyond LIMIT_BYTE.
16139 Return the number of lines thus found (always nonnegative).
16140
16141 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16142
16143 static int
16144 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16145 int start, start_byte, limit_byte, count;
16146 int *byte_pos_ptr;
16147 {
16148 register unsigned char *cursor;
16149 unsigned char *base;
16150
16151 register int ceiling;
16152 register unsigned char *ceiling_addr;
16153 int orig_count = count;
16154
16155 /* If we are not in selective display mode,
16156 check only for newlines. */
16157 int selective_display = (!NILP (current_buffer->selective_display)
16158 && !INTEGERP (current_buffer->selective_display));
16159
16160 if (count > 0)
16161 {
16162 while (start_byte < limit_byte)
16163 {
16164 ceiling = BUFFER_CEILING_OF (start_byte);
16165 ceiling = min (limit_byte - 1, ceiling);
16166 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16167 base = (cursor = BYTE_POS_ADDR (start_byte));
16168 while (1)
16169 {
16170 if (selective_display)
16171 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16172 ;
16173 else
16174 while (*cursor != '\n' && ++cursor != ceiling_addr)
16175 ;
16176
16177 if (cursor != ceiling_addr)
16178 {
16179 if (--count == 0)
16180 {
16181 start_byte += cursor - base + 1;
16182 *byte_pos_ptr = start_byte;
16183 return orig_count;
16184 }
16185 else
16186 if (++cursor == ceiling_addr)
16187 break;
16188 }
16189 else
16190 break;
16191 }
16192 start_byte += cursor - base;
16193 }
16194 }
16195 else
16196 {
16197 while (start_byte > limit_byte)
16198 {
16199 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16200 ceiling = max (limit_byte, ceiling);
16201 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16202 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16203 while (1)
16204 {
16205 if (selective_display)
16206 while (--cursor != ceiling_addr
16207 && *cursor != '\n' && *cursor != 015)
16208 ;
16209 else
16210 while (--cursor != ceiling_addr && *cursor != '\n')
16211 ;
16212
16213 if (cursor != ceiling_addr)
16214 {
16215 if (++count == 0)
16216 {
16217 start_byte += cursor - base + 1;
16218 *byte_pos_ptr = start_byte;
16219 /* When scanning backwards, we should
16220 not count the newline posterior to which we stop. */
16221 return - orig_count - 1;
16222 }
16223 }
16224 else
16225 break;
16226 }
16227 /* Here we add 1 to compensate for the last decrement
16228 of CURSOR, which took it past the valid range. */
16229 start_byte += cursor - base + 1;
16230 }
16231 }
16232
16233 *byte_pos_ptr = limit_byte;
16234
16235 if (count < 0)
16236 return - orig_count + count;
16237 return orig_count - count;
16238
16239 }
16240
16241
16242 \f
16243 /***********************************************************************
16244 Displaying strings
16245 ***********************************************************************/
16246
16247 /* Display a NUL-terminated string, starting with index START.
16248
16249 If STRING is non-null, display that C string. Otherwise, the Lisp
16250 string LISP_STRING is displayed.
16251
16252 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16253 FACE_STRING. Display STRING or LISP_STRING with the face at
16254 FACE_STRING_POS in FACE_STRING:
16255
16256 Display the string in the environment given by IT, but use the
16257 standard display table, temporarily.
16258
16259 FIELD_WIDTH is the minimum number of output glyphs to produce.
16260 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16261 with spaces. If STRING has more characters, more than FIELD_WIDTH
16262 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16263
16264 PRECISION is the maximum number of characters to output from
16265 STRING. PRECISION < 0 means don't truncate the string.
16266
16267 This is roughly equivalent to printf format specifiers:
16268
16269 FIELD_WIDTH PRECISION PRINTF
16270 ----------------------------------------
16271 -1 -1 %s
16272 -1 10 %.10s
16273 10 -1 %10s
16274 20 10 %20.10s
16275
16276 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16277 display them, and < 0 means obey the current buffer's value of
16278 enable_multibyte_characters.
16279
16280 Value is the number of glyphs produced. */
16281
16282 static int
16283 display_string (string, lisp_string, face_string, face_string_pos,
16284 start, it, field_width, precision, max_x, multibyte)
16285 unsigned char *string;
16286 Lisp_Object lisp_string;
16287 Lisp_Object face_string;
16288 int face_string_pos;
16289 int start;
16290 struct it *it;
16291 int field_width, precision, max_x;
16292 int multibyte;
16293 {
16294 int hpos_at_start = it->hpos;
16295 int saved_face_id = it->face_id;
16296 struct glyph_row *row = it->glyph_row;
16297
16298 /* Initialize the iterator IT for iteration over STRING beginning
16299 with index START. */
16300 reseat_to_string (it, string, lisp_string, start,
16301 precision, field_width, multibyte);
16302
16303 /* If displaying STRING, set up the face of the iterator
16304 from LISP_STRING, if that's given. */
16305 if (STRINGP (face_string))
16306 {
16307 int endptr;
16308 struct face *face;
16309
16310 it->face_id
16311 = face_at_string_position (it->w, face_string, face_string_pos,
16312 0, it->region_beg_charpos,
16313 it->region_end_charpos,
16314 &endptr, it->base_face_id, 0);
16315 face = FACE_FROM_ID (it->f, it->face_id);
16316 it->face_box_p = face->box != FACE_NO_BOX;
16317 }
16318
16319 /* Set max_x to the maximum allowed X position. Don't let it go
16320 beyond the right edge of the window. */
16321 if (max_x <= 0)
16322 max_x = it->last_visible_x;
16323 else
16324 max_x = min (max_x, it->last_visible_x);
16325
16326 /* Skip over display elements that are not visible. because IT->w is
16327 hscrolled. */
16328 if (it->current_x < it->first_visible_x)
16329 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16330 MOVE_TO_POS | MOVE_TO_X);
16331
16332 row->ascent = it->max_ascent;
16333 row->height = it->max_ascent + it->max_descent;
16334 row->phys_ascent = it->max_phys_ascent;
16335 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16336
16337 /* This condition is for the case that we are called with current_x
16338 past last_visible_x. */
16339 while (it->current_x < max_x)
16340 {
16341 int x_before, x, n_glyphs_before, i, nglyphs;
16342
16343 /* Get the next display element. */
16344 if (!get_next_display_element (it))
16345 break;
16346
16347 /* Produce glyphs. */
16348 x_before = it->current_x;
16349 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16350 PRODUCE_GLYPHS (it);
16351
16352 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16353 i = 0;
16354 x = x_before;
16355 while (i < nglyphs)
16356 {
16357 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16358
16359 if (!it->truncate_lines_p
16360 && x + glyph->pixel_width > max_x)
16361 {
16362 /* End of continued line or max_x reached. */
16363 if (CHAR_GLYPH_PADDING_P (*glyph))
16364 {
16365 /* A wide character is unbreakable. */
16366 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16367 it->current_x = x_before;
16368 }
16369 else
16370 {
16371 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16372 it->current_x = x;
16373 }
16374 break;
16375 }
16376 else if (x + glyph->pixel_width >= it->first_visible_x)
16377 {
16378 /* Glyph is at least partially visible. */
16379 ++it->hpos;
16380 if (x < it->first_visible_x)
16381 it->glyph_row->x = x - it->first_visible_x;
16382 }
16383 else
16384 {
16385 /* Glyph is off the left margin of the display area.
16386 Should not happen. */
16387 abort ();
16388 }
16389
16390 row->ascent = max (row->ascent, it->max_ascent);
16391 row->height = max (row->height, it->max_ascent + it->max_descent);
16392 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16393 row->phys_height = max (row->phys_height,
16394 it->max_phys_ascent + it->max_phys_descent);
16395 x += glyph->pixel_width;
16396 ++i;
16397 }
16398
16399 /* Stop if max_x reached. */
16400 if (i < nglyphs)
16401 break;
16402
16403 /* Stop at line ends. */
16404 if (ITERATOR_AT_END_OF_LINE_P (it))
16405 {
16406 it->continuation_lines_width = 0;
16407 break;
16408 }
16409
16410 set_iterator_to_next (it, 1);
16411
16412 /* Stop if truncating at the right edge. */
16413 if (it->truncate_lines_p
16414 && it->current_x >= it->last_visible_x)
16415 {
16416 /* Add truncation mark, but don't do it if the line is
16417 truncated at a padding space. */
16418 if (IT_CHARPOS (*it) < it->string_nchars)
16419 {
16420 if (!FRAME_WINDOW_P (it->f))
16421 {
16422 int i, n;
16423
16424 if (it->current_x > it->last_visible_x)
16425 {
16426 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16427 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16428 break;
16429 for (n = row->used[TEXT_AREA]; i < n; ++i)
16430 {
16431 row->used[TEXT_AREA] = i;
16432 produce_special_glyphs (it, IT_TRUNCATION);
16433 }
16434 }
16435 produce_special_glyphs (it, IT_TRUNCATION);
16436 }
16437 it->glyph_row->truncated_on_right_p = 1;
16438 }
16439 break;
16440 }
16441 }
16442
16443 /* Maybe insert a truncation at the left. */
16444 if (it->first_visible_x
16445 && IT_CHARPOS (*it) > 0)
16446 {
16447 if (!FRAME_WINDOW_P (it->f))
16448 insert_left_trunc_glyphs (it);
16449 it->glyph_row->truncated_on_left_p = 1;
16450 }
16451
16452 it->face_id = saved_face_id;
16453
16454 /* Value is number of columns displayed. */
16455 return it->hpos - hpos_at_start;
16456 }
16457
16458
16459 \f
16460 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16461 appears as an element of LIST or as the car of an element of LIST.
16462 If PROPVAL is a list, compare each element against LIST in that
16463 way, and return 1/2 if any element of PROPVAL is found in LIST.
16464 Otherwise return 0. This function cannot quit.
16465 The return value is 2 if the text is invisible but with an ellipsis
16466 and 1 if it's invisible and without an ellipsis. */
16467
16468 int
16469 invisible_p (propval, list)
16470 register Lisp_Object propval;
16471 Lisp_Object list;
16472 {
16473 register Lisp_Object tail, proptail;
16474
16475 for (tail = list; CONSP (tail); tail = XCDR (tail))
16476 {
16477 register Lisp_Object tem;
16478 tem = XCAR (tail);
16479 if (EQ (propval, tem))
16480 return 1;
16481 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16482 return NILP (XCDR (tem)) ? 1 : 2;
16483 }
16484
16485 if (CONSP (propval))
16486 {
16487 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16488 {
16489 Lisp_Object propelt;
16490 propelt = XCAR (proptail);
16491 for (tail = list; CONSP (tail); tail = XCDR (tail))
16492 {
16493 register Lisp_Object tem;
16494 tem = XCAR (tail);
16495 if (EQ (propelt, tem))
16496 return 1;
16497 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16498 return NILP (XCDR (tem)) ? 1 : 2;
16499 }
16500 }
16501 }
16502
16503 return 0;
16504 }
16505
16506 \f
16507 /***********************************************************************
16508 Glyph Display
16509 ***********************************************************************/
16510
16511 #ifdef HAVE_WINDOW_SYSTEM
16512
16513 #if GLYPH_DEBUG
16514
16515 void
16516 dump_glyph_string (s)
16517 struct glyph_string *s;
16518 {
16519 fprintf (stderr, "glyph string\n");
16520 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16521 s->x, s->y, s->width, s->height);
16522 fprintf (stderr, " ybase = %d\n", s->ybase);
16523 fprintf (stderr, " hl = %d\n", s->hl);
16524 fprintf (stderr, " left overhang = %d, right = %d\n",
16525 s->left_overhang, s->right_overhang);
16526 fprintf (stderr, " nchars = %d\n", s->nchars);
16527 fprintf (stderr, " extends to end of line = %d\n",
16528 s->extends_to_end_of_line_p);
16529 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16530 fprintf (stderr, " bg width = %d\n", s->background_width);
16531 }
16532
16533 #endif /* GLYPH_DEBUG */
16534
16535 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16536 of XChar2b structures for S; it can't be allocated in
16537 init_glyph_string because it must be allocated via `alloca'. W
16538 is the window on which S is drawn. ROW and AREA are the glyph row
16539 and area within the row from which S is constructed. START is the
16540 index of the first glyph structure covered by S. HL is a
16541 face-override for drawing S. */
16542
16543 #ifdef HAVE_NTGUI
16544 #define OPTIONAL_HDC(hdc) hdc,
16545 #define DECLARE_HDC(hdc) HDC hdc;
16546 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16547 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16548 #endif
16549
16550 #ifndef OPTIONAL_HDC
16551 #define OPTIONAL_HDC(hdc)
16552 #define DECLARE_HDC(hdc)
16553 #define ALLOCATE_HDC(hdc, f)
16554 #define RELEASE_HDC(hdc, f)
16555 #endif
16556
16557 static void
16558 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16559 struct glyph_string *s;
16560 DECLARE_HDC (hdc)
16561 XChar2b *char2b;
16562 struct window *w;
16563 struct glyph_row *row;
16564 enum glyph_row_area area;
16565 int start;
16566 enum draw_glyphs_face hl;
16567 {
16568 bzero (s, sizeof *s);
16569 s->w = w;
16570 s->f = XFRAME (w->frame);
16571 #ifdef HAVE_NTGUI
16572 s->hdc = hdc;
16573 #endif
16574 s->display = FRAME_X_DISPLAY (s->f);
16575 s->window = FRAME_X_WINDOW (s->f);
16576 s->char2b = char2b;
16577 s->hl = hl;
16578 s->row = row;
16579 s->area = area;
16580 s->first_glyph = row->glyphs[area] + start;
16581 s->height = row->height;
16582 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16583
16584 /* Display the internal border below the tool-bar window. */
16585 if (s->w == XWINDOW (s->f->tool_bar_window))
16586 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16587
16588 s->ybase = s->y + row->ascent;
16589 }
16590
16591
16592 /* Append the list of glyph strings with head H and tail T to the list
16593 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16594
16595 static INLINE void
16596 append_glyph_string_lists (head, tail, h, t)
16597 struct glyph_string **head, **tail;
16598 struct glyph_string *h, *t;
16599 {
16600 if (h)
16601 {
16602 if (*head)
16603 (*tail)->next = h;
16604 else
16605 *head = h;
16606 h->prev = *tail;
16607 *tail = t;
16608 }
16609 }
16610
16611
16612 /* Prepend the list of glyph strings with head H and tail T to the
16613 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16614 result. */
16615
16616 static INLINE void
16617 prepend_glyph_string_lists (head, tail, h, t)
16618 struct glyph_string **head, **tail;
16619 struct glyph_string *h, *t;
16620 {
16621 if (h)
16622 {
16623 if (*head)
16624 (*head)->prev = t;
16625 else
16626 *tail = t;
16627 t->next = *head;
16628 *head = h;
16629 }
16630 }
16631
16632
16633 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16634 Set *HEAD and *TAIL to the resulting list. */
16635
16636 static INLINE void
16637 append_glyph_string (head, tail, s)
16638 struct glyph_string **head, **tail;
16639 struct glyph_string *s;
16640 {
16641 s->next = s->prev = NULL;
16642 append_glyph_string_lists (head, tail, s, s);
16643 }
16644
16645
16646 /* Get face and two-byte form of character glyph GLYPH on frame F.
16647 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16648 a pointer to a realized face that is ready for display. */
16649
16650 static INLINE struct face *
16651 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16652 struct frame *f;
16653 struct glyph *glyph;
16654 XChar2b *char2b;
16655 int *two_byte_p;
16656 {
16657 struct face *face;
16658
16659 xassert (glyph->type == CHAR_GLYPH);
16660 face = FACE_FROM_ID (f, glyph->face_id);
16661
16662 if (two_byte_p)
16663 *two_byte_p = 0;
16664
16665 if (!glyph->multibyte_p)
16666 {
16667 /* Unibyte case. We don't have to encode, but we have to make
16668 sure to use a face suitable for unibyte. */
16669 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16670 }
16671 else if (glyph->u.ch < 128
16672 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16673 {
16674 /* Case of ASCII in a face known to fit ASCII. */
16675 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16676 }
16677 else
16678 {
16679 struct font_info *font_info
16680 = FONT_INFO_FROM_ID (f, face->font_info_id);
16681 if (font_info)
16682 {
16683 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
16684 unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
16685
16686 if (CHARSET_DIMENSION (charset) == 1)
16687 STORE_XCHAR2B (char2b, 0, code);
16688 else
16689 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
16690
16691 /* Maybe encode the character in *CHAR2B. */
16692 if (CHARSET_ID (charset) != charset_ascii)
16693 {
16694 glyph->font_type
16695 = rif->encode_char (glyph->u.ch, char2b, font_info, charset,
16696 two_byte_p);
16697 }
16698 }
16699 }
16700
16701 /* Make sure X resources of the face are allocated. */
16702 xassert (face != NULL);
16703 PREPARE_FACE_FOR_DISPLAY (f, face);
16704 return face;
16705 }
16706
16707
16708 /* Fill glyph string S with composition components specified by S->cmp.
16709
16710 FACES is an array of faces for all components of this composition.
16711 S->gidx is the index of the first component for S.
16712 OVERLAPS_P non-zero means S should draw the foreground only, and
16713 use its physical height for clipping.
16714
16715 Value is the index of a component not in S. */
16716
16717 static int
16718 fill_composite_glyph_string (s, faces, overlaps_p)
16719 struct glyph_string *s;
16720 struct face **faces;
16721 int overlaps_p;
16722 {
16723 int i;
16724
16725 xassert (s);
16726
16727 s->for_overlaps_p = overlaps_p;
16728
16729 s->face = faces[s->gidx];
16730 s->font = s->face->font;
16731 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16732
16733 /* For all glyphs of this composition, starting at the offset
16734 S->gidx, until we reach the end of the definition or encounter a
16735 glyph that requires the different face, add it to S. */
16736 ++s->nchars;
16737 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16738 ++s->nchars;
16739
16740 /* All glyph strings for the same composition has the same width,
16741 i.e. the width set for the first component of the composition. */
16742
16743 s->width = s->first_glyph->pixel_width;
16744
16745 /* If the specified font could not be loaded, use the frame's
16746 default font, but record the fact that we couldn't load it in
16747 the glyph string so that we can draw rectangles for the
16748 characters of the glyph string. */
16749 if (s->font == NULL)
16750 {
16751 s->font_not_found_p = 1;
16752 s->font = FRAME_FONT (s->f);
16753 }
16754
16755 /* Adjust base line for subscript/superscript text. */
16756 s->ybase += s->first_glyph->voffset;
16757
16758 xassert (s->face && s->face->gc);
16759
16760 /* This glyph string must always be drawn with 16-bit functions. */
16761 s->two_byte_p = 1;
16762
16763 return s->gidx + s->nchars;
16764 }
16765
16766
16767 /* Fill glyph string S from a sequence of character glyphs.
16768
16769 FACE_ID is the face id of the string. START is the index of the
16770 first glyph to consider, END is the index of the last + 1.
16771 OVERLAPS_P non-zero means S should draw the foreground only, and
16772 use its physical height for clipping.
16773
16774 Value is the index of the first glyph not in S. */
16775
16776 static int
16777 fill_glyph_string (s, face_id, start, end, overlaps_p)
16778 struct glyph_string *s;
16779 int face_id;
16780 int start, end, overlaps_p;
16781 {
16782 struct glyph *glyph, *last;
16783 int voffset;
16784 int glyph_not_available_p;
16785
16786 xassert (s->f == XFRAME (s->w->frame));
16787 xassert (s->nchars == 0);
16788 xassert (start >= 0 && end > start);
16789
16790 s->for_overlaps_p = overlaps_p,
16791 glyph = s->row->glyphs[s->area] + start;
16792 last = s->row->glyphs[s->area] + end;
16793 voffset = glyph->voffset;
16794
16795 glyph_not_available_p = glyph->glyph_not_available_p;
16796
16797 while (glyph < last
16798 && glyph->type == CHAR_GLYPH
16799 && glyph->voffset == voffset
16800 /* Same face id implies same font, nowadays. */
16801 && glyph->face_id == face_id
16802 && glyph->glyph_not_available_p == glyph_not_available_p)
16803 {
16804 int two_byte_p;
16805
16806 s->face = get_glyph_face_and_encoding (s->f, glyph,
16807 s->char2b + s->nchars,
16808 &two_byte_p);
16809 s->two_byte_p = two_byte_p;
16810 ++s->nchars;
16811 xassert (s->nchars <= end - start);
16812 s->width += glyph->pixel_width;
16813 ++glyph;
16814 }
16815
16816 s->font = s->face->font;
16817 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16818
16819 /* If the specified font could not be loaded, use the frame's font,
16820 but record the fact that we couldn't load it in
16821 S->font_not_found_p so that we can draw rectangles for the
16822 characters of the glyph string. */
16823 if (s->font == NULL || glyph_not_available_p)
16824 {
16825 s->font_not_found_p = 1;
16826 s->font = FRAME_FONT (s->f);
16827 }
16828
16829 /* Adjust base line for subscript/superscript text. */
16830 s->ybase += voffset;
16831
16832 xassert (s->face && s->face->gc);
16833 return glyph - s->row->glyphs[s->area];
16834 }
16835
16836
16837 /* Fill glyph string S from image glyph S->first_glyph. */
16838
16839 static void
16840 fill_image_glyph_string (s)
16841 struct glyph_string *s;
16842 {
16843 xassert (s->first_glyph->type == IMAGE_GLYPH);
16844 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16845 xassert (s->img);
16846 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16847 s->font = s->face->font;
16848 s->width = s->first_glyph->pixel_width;
16849
16850 /* Adjust base line for subscript/superscript text. */
16851 s->ybase += s->first_glyph->voffset;
16852 }
16853
16854
16855 /* Fill glyph string S from a sequence of stretch glyphs.
16856
16857 ROW is the glyph row in which the glyphs are found, AREA is the
16858 area within the row. START is the index of the first glyph to
16859 consider, END is the index of the last + 1.
16860
16861 Value is the index of the first glyph not in S. */
16862
16863 static int
16864 fill_stretch_glyph_string (s, row, area, start, end)
16865 struct glyph_string *s;
16866 struct glyph_row *row;
16867 enum glyph_row_area area;
16868 int start, end;
16869 {
16870 struct glyph *glyph, *last;
16871 int voffset, face_id;
16872
16873 xassert (s->first_glyph->type == STRETCH_GLYPH);
16874
16875 glyph = s->row->glyphs[s->area] + start;
16876 last = s->row->glyphs[s->area] + end;
16877 face_id = glyph->face_id;
16878 s->face = FACE_FROM_ID (s->f, face_id);
16879 s->font = s->face->font;
16880 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16881 s->width = glyph->pixel_width;
16882 voffset = glyph->voffset;
16883
16884 for (++glyph;
16885 (glyph < last
16886 && glyph->type == STRETCH_GLYPH
16887 && glyph->voffset == voffset
16888 && glyph->face_id == face_id);
16889 ++glyph)
16890 s->width += glyph->pixel_width;
16891
16892 /* Adjust base line for subscript/superscript text. */
16893 s->ybase += voffset;
16894
16895 /* The case that face->gc == 0 is handled when drawing the glyph
16896 string by calling PREPARE_FACE_FOR_DISPLAY. */
16897 xassert (s->face);
16898 return glyph - s->row->glyphs[s->area];
16899 }
16900
16901
16902 /* EXPORT for RIF:
16903 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16904 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
16905 assumed to be zero. */
16906
16907 void
16908 x_get_glyph_overhangs (glyph, f, left, right)
16909 struct glyph *glyph;
16910 struct frame *f;
16911 int *left, *right;
16912 {
16913 *left = *right = 0;
16914
16915 if (glyph->type == CHAR_GLYPH)
16916 {
16917 XFontStruct *font;
16918 struct face *face;
16919 struct font_info *font_info;
16920 XChar2b char2b;
16921 XCharStruct *pcm;
16922
16923 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
16924 font = face->font;
16925 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
16926 if (font /* ++KFS: Should this be font_info ? */
16927 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
16928 {
16929 if (pcm->rbearing > pcm->width)
16930 *right = pcm->rbearing - pcm->width;
16931 if (pcm->lbearing < 0)
16932 *left = -pcm->lbearing;
16933 }
16934 }
16935 else if (glyph->type == COMPOSITE_GLYPH)
16936 {
16937 struct composition *cmp = composition_table[glyph->u.cmp_id];
16938
16939 *right = cmp->rbearing - cmp->pixel_width;
16940 *left = - cmp->lbearing;
16941 }
16942 }
16943
16944
16945 /* Return the index of the first glyph preceding glyph string S that
16946 is overwritten by S because of S's left overhang. Value is -1
16947 if no glyphs are overwritten. */
16948
16949 static int
16950 left_overwritten (s)
16951 struct glyph_string *s;
16952 {
16953 int k;
16954
16955 if (s->left_overhang)
16956 {
16957 int x = 0, i;
16958 struct glyph *glyphs = s->row->glyphs[s->area];
16959 int first = s->first_glyph - glyphs;
16960
16961 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
16962 x -= glyphs[i].pixel_width;
16963
16964 k = i + 1;
16965 }
16966 else
16967 k = -1;
16968
16969 return k;
16970 }
16971
16972
16973 /* Return the index of the first glyph preceding glyph string S that
16974 is overwriting S because of its right overhang. Value is -1 if no
16975 glyph in front of S overwrites S. */
16976
16977 static int
16978 left_overwriting (s)
16979 struct glyph_string *s;
16980 {
16981 int i, k, x;
16982 struct glyph *glyphs = s->row->glyphs[s->area];
16983 int first = s->first_glyph - glyphs;
16984
16985 k = -1;
16986 x = 0;
16987 for (i = first - 1; i >= 0; --i)
16988 {
16989 int left, right;
16990 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16991 if (x + right > 0)
16992 k = i;
16993 x -= glyphs[i].pixel_width;
16994 }
16995
16996 return k;
16997 }
16998
16999
17000 /* Return the index of the last glyph following glyph string S that is
17001 not overwritten by S because of S's right overhang. Value is -1 if
17002 no such glyph is found. */
17003
17004 static int
17005 right_overwritten (s)
17006 struct glyph_string *s;
17007 {
17008 int k = -1;
17009
17010 if (s->right_overhang)
17011 {
17012 int x = 0, i;
17013 struct glyph *glyphs = s->row->glyphs[s->area];
17014 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17015 int end = s->row->used[s->area];
17016
17017 for (i = first; i < end && s->right_overhang > x; ++i)
17018 x += glyphs[i].pixel_width;
17019
17020 k = i;
17021 }
17022
17023 return k;
17024 }
17025
17026
17027 /* Return the index of the last glyph following glyph string S that
17028 overwrites S because of its left overhang. Value is negative
17029 if no such glyph is found. */
17030
17031 static int
17032 right_overwriting (s)
17033 struct glyph_string *s;
17034 {
17035 int i, k, x;
17036 int end = s->row->used[s->area];
17037 struct glyph *glyphs = s->row->glyphs[s->area];
17038 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17039
17040 k = -1;
17041 x = 0;
17042 for (i = first; i < end; ++i)
17043 {
17044 int left, right;
17045 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17046 if (x - left < 0)
17047 k = i;
17048 x += glyphs[i].pixel_width;
17049 }
17050
17051 return k;
17052 }
17053
17054
17055 /* Get face and two-byte form of character C in face FACE_ID on frame
17056 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17057 means we want to display multibyte text. DISPLAY_P non-zero means
17058 make sure that X resources for the face returned are allocated.
17059 Value is a pointer to a realized face that is ready for display if
17060 DISPLAY_P is non-zero. */
17061
17062 static INLINE struct face *
17063 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17064 struct frame *f;
17065 int c, face_id;
17066 XChar2b *char2b;
17067 int multibyte_p, display_p;
17068 {
17069 struct face *face = FACE_FROM_ID (f, face_id);
17070
17071 if (!multibyte_p)
17072 {
17073 /* Unibyte case. We don't have to encode, but we have to make
17074 sure to use a face suitable for unibyte. */
17075 STORE_XCHAR2B (char2b, 0, c);
17076 face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
17077 face = FACE_FROM_ID (f, face_id);
17078 }
17079 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17080 {
17081 /* Case of ASCII in a face known to fit ASCII. */
17082 STORE_XCHAR2B (char2b, 0, c);
17083 }
17084 else if (face->font != NULL)
17085 {
17086 struct font_info *font_info
17087 = FONT_INFO_FROM_ID (f, face->font_info_id);
17088 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
17089 unsigned code = ENCODE_CHAR (charset, c);
17090
17091 if (CHARSET_DIMENSION (charset) == 1)
17092 STORE_XCHAR2B (char2b, 0, code);
17093 else
17094 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
17095 /* Maybe encode the character in *CHAR2B. */
17096 rif->encode_char (c, char2b, font_info, charset, NULL);
17097 }
17098
17099 /* Make sure X resources of the face are allocated. */
17100 #ifdef HAVE_X_WINDOWS
17101 if (display_p)
17102 #endif
17103 {
17104 xassert (face != NULL);
17105 PREPARE_FACE_FOR_DISPLAY (f, face);
17106 }
17107
17108 return face;
17109 }
17110
17111
17112 /* Set background width of glyph string S. START is the index of the
17113 first glyph following S. LAST_X is the right-most x-position + 1
17114 in the drawing area. */
17115
17116 static INLINE void
17117 set_glyph_string_background_width (s, start, last_x)
17118 struct glyph_string *s;
17119 int start;
17120 int last_x;
17121 {
17122 /* If the face of this glyph string has to be drawn to the end of
17123 the drawing area, set S->extends_to_end_of_line_p. */
17124 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17125
17126 if (start == s->row->used[s->area]
17127 && s->area == TEXT_AREA
17128 && ((s->hl == DRAW_NORMAL_TEXT
17129 && (s->row->fill_line_p
17130 || s->face->background != default_face->background
17131 || s->face->stipple != default_face->stipple
17132 || s->row->mouse_face_p))
17133 || s->hl == DRAW_MOUSE_FACE
17134 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17135 && s->row->fill_line_p)))
17136 s->extends_to_end_of_line_p = 1;
17137
17138 /* If S extends its face to the end of the line, set its
17139 background_width to the distance to the right edge of the drawing
17140 area. */
17141 if (s->extends_to_end_of_line_p)
17142 s->background_width = last_x - s->x + 1;
17143 else
17144 s->background_width = s->width;
17145 }
17146
17147
17148 /* Compute overhangs and x-positions for glyph string S and its
17149 predecessors, or successors. X is the starting x-position for S.
17150 BACKWARD_P non-zero means process predecessors. */
17151
17152 static void
17153 compute_overhangs_and_x (s, x, backward_p)
17154 struct glyph_string *s;
17155 int x;
17156 int backward_p;
17157 {
17158 if (backward_p)
17159 {
17160 while (s)
17161 {
17162 if (rif->compute_glyph_string_overhangs)
17163 rif->compute_glyph_string_overhangs (s);
17164 x -= s->width;
17165 s->x = x;
17166 s = s->prev;
17167 }
17168 }
17169 else
17170 {
17171 while (s)
17172 {
17173 if (rif->compute_glyph_string_overhangs)
17174 rif->compute_glyph_string_overhangs (s);
17175 s->x = x;
17176 x += s->width;
17177 s = s->next;
17178 }
17179 }
17180 }
17181
17182
17183
17184 /* The following macros are only called from draw_glyphs below.
17185 They reference the following parameters of that function directly:
17186 `w', `row', `area', and `overlap_p'
17187 as well as the following local variables:
17188 `s', `f', and `hdc' (in W32) */
17189
17190 #ifdef HAVE_NTGUI
17191 /* On W32, silently add local `hdc' variable to argument list of
17192 init_glyph_string. */
17193 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17194 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17195 #else
17196 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17197 init_glyph_string (s, char2b, w, row, area, start, hl)
17198 #endif
17199
17200 /* Add a glyph string for a stretch glyph to the list of strings
17201 between HEAD and TAIL. START is the index of the stretch glyph in
17202 row area AREA of glyph row ROW. END is the index of the last glyph
17203 in that glyph row area. X is the current output position assigned
17204 to the new glyph string constructed. HL overrides that face of the
17205 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17206 is the right-most x-position of the drawing area. */
17207
17208 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17209 and below -- keep them on one line. */
17210 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17211 do \
17212 { \
17213 s = (struct glyph_string *) alloca (sizeof *s); \
17214 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17215 START = fill_stretch_glyph_string (s, row, area, START, END); \
17216 append_glyph_string (&HEAD, &TAIL, s); \
17217 s->x = (X); \
17218 } \
17219 while (0)
17220
17221
17222 /* Add a glyph string for an image glyph to the list of strings
17223 between HEAD and TAIL. START is the index of the image glyph in
17224 row area AREA of glyph row ROW. END is the index of the last glyph
17225 in that glyph row area. X is the current output position assigned
17226 to the new glyph string constructed. HL overrides that face of the
17227 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17228 is the right-most x-position of the drawing area. */
17229
17230 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17231 do \
17232 { \
17233 s = (struct glyph_string *) alloca (sizeof *s); \
17234 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17235 fill_image_glyph_string (s); \
17236 append_glyph_string (&HEAD, &TAIL, s); \
17237 ++START; \
17238 s->x = (X); \
17239 } \
17240 while (0)
17241
17242
17243 /* Add a glyph string for a sequence of character glyphs to the list
17244 of strings between HEAD and TAIL. START is the index of the first
17245 glyph in row area AREA of glyph row ROW that is part of the new
17246 glyph string. END is the index of the last glyph in that glyph row
17247 area. X is the current output position assigned to the new glyph
17248 string constructed. HL overrides that face of the glyph; e.g. it
17249 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17250 right-most x-position of the drawing area. */
17251
17252 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17253 do \
17254 { \
17255 int face_id; \
17256 XChar2b *char2b; \
17257 \
17258 face_id = (row)->glyphs[area][START].face_id; \
17259 \
17260 s = (struct glyph_string *) alloca (sizeof *s); \
17261 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17262 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17263 append_glyph_string (&HEAD, &TAIL, s); \
17264 s->x = (X); \
17265 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17266 } \
17267 while (0)
17268
17269
17270 /* Add a glyph string for a composite sequence to the list of strings
17271 between HEAD and TAIL. START is the index of the first glyph in
17272 row area AREA of glyph row ROW that is part of the new glyph
17273 string. END is the index of the last glyph in that glyph row area.
17274 X is the current output position assigned to the new glyph string
17275 constructed. HL overrides that face of the glyph; e.g. it is
17276 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17277 x-position of the drawing area. */
17278
17279 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17280 do { \
17281 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17282 int face_id = (row)->glyphs[area][START].face_id; \
17283 struct face *base_face = FACE_FROM_ID (f, face_id); \
17284 struct composition *cmp = composition_table[cmp_id]; \
17285 int glyph_len = cmp->glyph_len; \
17286 XChar2b *char2b; \
17287 struct face **faces; \
17288 struct glyph_string *first_s = NULL; \
17289 int n; \
17290 \
17291 base_face = base_face->ascii_face; \
17292 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17293 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17294 /* At first, fill in `char2b' and `faces'. */ \
17295 for (n = 0; n < glyph_len; n++) \
17296 { \
17297 int c = COMPOSITION_GLYPH (cmp, n); \
17298 int this_face_id = FACE_FOR_CHAR (f, base_face, c, -1, Qnil); \
17299 faces[n] = FACE_FROM_ID (f, this_face_id); \
17300 get_char_face_and_encoding (f, c, this_face_id, \
17301 char2b + n, 1, 1); \
17302 } \
17303 \
17304 /* Make glyph_strings for each glyph sequence that is drawable by \
17305 the same face, and append them to HEAD/TAIL. */ \
17306 for (n = 0; n < cmp->glyph_len;) \
17307 { \
17308 s = (struct glyph_string *) alloca (sizeof *s); \
17309 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17310 append_glyph_string (&(HEAD), &(TAIL), s); \
17311 s->cmp = cmp; \
17312 s->gidx = n; \
17313 s->x = (X); \
17314 \
17315 if (n == 0) \
17316 first_s = s; \
17317 \
17318 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17319 } \
17320 \
17321 ++START; \
17322 s = first_s; \
17323 } while (0)
17324
17325
17326 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17327 of AREA of glyph row ROW on window W between indices START and END.
17328 HL overrides the face for drawing glyph strings, e.g. it is
17329 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17330 x-positions of the drawing area.
17331
17332 This is an ugly monster macro construct because we must use alloca
17333 to allocate glyph strings (because draw_glyphs can be called
17334 asynchronously). */
17335
17336 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17337 do \
17338 { \
17339 HEAD = TAIL = NULL; \
17340 while (START < END) \
17341 { \
17342 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17343 switch (first_glyph->type) \
17344 { \
17345 case CHAR_GLYPH: \
17346 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17347 HL, X, LAST_X); \
17348 break; \
17349 \
17350 case COMPOSITE_GLYPH: \
17351 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17352 HL, X, LAST_X); \
17353 break; \
17354 \
17355 case STRETCH_GLYPH: \
17356 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17357 HL, X, LAST_X); \
17358 break; \
17359 \
17360 case IMAGE_GLYPH: \
17361 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17362 HL, X, LAST_X); \
17363 break; \
17364 \
17365 default: \
17366 abort (); \
17367 } \
17368 \
17369 set_glyph_string_background_width (s, START, LAST_X); \
17370 (X) += s->width; \
17371 } \
17372 } \
17373 while (0)
17374
17375
17376 /* Draw glyphs between START and END in AREA of ROW on window W,
17377 starting at x-position X. X is relative to AREA in W. HL is a
17378 face-override with the following meaning:
17379
17380 DRAW_NORMAL_TEXT draw normally
17381 DRAW_CURSOR draw in cursor face
17382 DRAW_MOUSE_FACE draw in mouse face.
17383 DRAW_INVERSE_VIDEO draw in mode line face
17384 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17385 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17386
17387 If OVERLAPS_P is non-zero, draw only the foreground of characters
17388 and clip to the physical height of ROW.
17389
17390 Value is the x-position reached, relative to AREA of W. */
17391
17392 static int
17393 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17394 struct window *w;
17395 int x;
17396 struct glyph_row *row;
17397 enum glyph_row_area area;
17398 EMACS_INT start, end;
17399 enum draw_glyphs_face hl;
17400 int overlaps_p;
17401 {
17402 struct glyph_string *head, *tail;
17403 struct glyph_string *s;
17404 int last_x, area_width;
17405 int x_reached;
17406 int i, j;
17407 struct frame *f = XFRAME (WINDOW_FRAME (w));
17408 DECLARE_HDC (hdc);
17409
17410 ALLOCATE_HDC (hdc, f);
17411
17412 /* Let's rather be paranoid than getting a SEGV. */
17413 end = min (end, row->used[area]);
17414 start = max (0, start);
17415 start = min (end, start);
17416
17417 /* Translate X to frame coordinates. Set last_x to the right
17418 end of the drawing area. */
17419 if (row->full_width_p)
17420 {
17421 /* X is relative to the left edge of W, without scroll bars
17422 or fringes. */
17423 x += WINDOW_LEFT_EDGE_X (w);
17424 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17425 }
17426 else
17427 {
17428 int area_left = window_box_left (w, area);
17429 x += area_left;
17430 area_width = window_box_width (w, area);
17431 last_x = area_left + area_width;
17432 }
17433
17434 /* Build a doubly-linked list of glyph_string structures between
17435 head and tail from what we have to draw. Note that the macro
17436 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17437 the reason we use a separate variable `i'. */
17438 i = start;
17439 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17440 if (tail)
17441 x_reached = tail->x + tail->background_width;
17442 else
17443 x_reached = x;
17444
17445 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17446 the row, redraw some glyphs in front or following the glyph
17447 strings built above. */
17448 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17449 {
17450 int dummy_x = 0;
17451 struct glyph_string *h, *t;
17452
17453 /* Compute overhangs for all glyph strings. */
17454 if (rif->compute_glyph_string_overhangs)
17455 for (s = head; s; s = s->next)
17456 rif->compute_glyph_string_overhangs (s);
17457
17458 /* Prepend glyph strings for glyphs in front of the first glyph
17459 string that are overwritten because of the first glyph
17460 string's left overhang. The background of all strings
17461 prepended must be drawn because the first glyph string
17462 draws over it. */
17463 i = left_overwritten (head);
17464 if (i >= 0)
17465 {
17466 j = i;
17467 BUILD_GLYPH_STRINGS (j, start, h, t,
17468 DRAW_NORMAL_TEXT, dummy_x, last_x);
17469 start = i;
17470 compute_overhangs_and_x (t, head->x, 1);
17471 prepend_glyph_string_lists (&head, &tail, h, t);
17472 }
17473
17474 /* Prepend glyph strings for glyphs in front of the first glyph
17475 string that overwrite that glyph string because of their
17476 right overhang. For these strings, only the foreground must
17477 be drawn, because it draws over the glyph string at `head'.
17478 The background must not be drawn because this would overwrite
17479 right overhangs of preceding glyphs for which no glyph
17480 strings exist. */
17481 i = left_overwriting (head);
17482 if (i >= 0)
17483 {
17484 BUILD_GLYPH_STRINGS (i, start, h, t,
17485 DRAW_NORMAL_TEXT, dummy_x, last_x);
17486 for (s = h; s; s = s->next)
17487 s->background_filled_p = 1;
17488 compute_overhangs_and_x (t, head->x, 1);
17489 prepend_glyph_string_lists (&head, &tail, h, t);
17490 }
17491
17492 /* Append glyphs strings for glyphs following the last glyph
17493 string tail that are overwritten by tail. The background of
17494 these strings has to be drawn because tail's foreground draws
17495 over it. */
17496 i = right_overwritten (tail);
17497 if (i >= 0)
17498 {
17499 BUILD_GLYPH_STRINGS (end, i, h, t,
17500 DRAW_NORMAL_TEXT, x, last_x);
17501 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17502 append_glyph_string_lists (&head, &tail, h, t);
17503 }
17504
17505 /* Append glyph strings for glyphs following the last glyph
17506 string tail that overwrite tail. The foreground of such
17507 glyphs has to be drawn because it writes into the background
17508 of tail. The background must not be drawn because it could
17509 paint over the foreground of following glyphs. */
17510 i = right_overwriting (tail);
17511 if (i >= 0)
17512 {
17513 BUILD_GLYPH_STRINGS (end, i, h, t,
17514 DRAW_NORMAL_TEXT, x, last_x);
17515 for (s = h; s; s = s->next)
17516 s->background_filled_p = 1;
17517 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17518 append_glyph_string_lists (&head, &tail, h, t);
17519 }
17520 }
17521
17522 /* Draw all strings. */
17523 for (s = head; s; s = s->next)
17524 rif->draw_glyph_string (s);
17525
17526 if (area == TEXT_AREA
17527 && !row->full_width_p
17528 /* When drawing overlapping rows, only the glyph strings'
17529 foreground is drawn, which doesn't erase a cursor
17530 completely. */
17531 && !overlaps_p)
17532 {
17533 int x0 = head ? head->x : x;
17534 int x1 = tail ? tail->x + tail->background_width : x;
17535
17536 int text_left = window_box_left (w, TEXT_AREA);
17537 x0 -= text_left;
17538 x1 -= text_left;
17539
17540 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
17541 row->y, MATRIX_ROW_BOTTOM_Y (row));
17542 }
17543
17544 /* Value is the x-position up to which drawn, relative to AREA of W.
17545 This doesn't include parts drawn because of overhangs. */
17546 if (row->full_width_p)
17547 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17548 else
17549 x_reached -= window_box_left (w, area);
17550
17551 RELEASE_HDC (hdc, f);
17552
17553 return x_reached;
17554 }
17555
17556
17557 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17558 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17559
17560 static INLINE void
17561 append_glyph (it)
17562 struct it *it;
17563 {
17564 struct glyph *glyph;
17565 enum glyph_row_area area = it->area;
17566
17567 xassert (it->glyph_row);
17568 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17569
17570 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17571 if (glyph < it->glyph_row->glyphs[area + 1])
17572 {
17573 glyph->charpos = CHARPOS (it->position);
17574 glyph->object = it->object;
17575 glyph->pixel_width = it->pixel_width;
17576 glyph->voffset = it->voffset;
17577 glyph->type = CHAR_GLYPH;
17578 glyph->multibyte_p = it->multibyte_p;
17579 glyph->left_box_line_p = it->start_of_box_run_p;
17580 glyph->right_box_line_p = it->end_of_box_run_p;
17581 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17582 || it->phys_descent > it->descent);
17583 glyph->padding_p = 0;
17584 glyph->glyph_not_available_p = it->glyph_not_available_p;
17585 glyph->face_id = it->face_id;
17586 glyph->u.ch = it->char_to_display;
17587 glyph->font_type = FONT_TYPE_UNKNOWN;
17588 ++it->glyph_row->used[area];
17589 }
17590 }
17591
17592 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17593 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17594
17595 static INLINE void
17596 append_composite_glyph (it)
17597 struct it *it;
17598 {
17599 struct glyph *glyph;
17600 enum glyph_row_area area = it->area;
17601
17602 xassert (it->glyph_row);
17603
17604 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17605 if (glyph < it->glyph_row->glyphs[area + 1])
17606 {
17607 glyph->charpos = CHARPOS (it->position);
17608 glyph->object = it->object;
17609 glyph->pixel_width = it->pixel_width;
17610 glyph->voffset = it->voffset;
17611 glyph->type = COMPOSITE_GLYPH;
17612 glyph->multibyte_p = it->multibyte_p;
17613 glyph->left_box_line_p = it->start_of_box_run_p;
17614 glyph->right_box_line_p = it->end_of_box_run_p;
17615 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17616 || it->phys_descent > it->descent);
17617 glyph->padding_p = 0;
17618 glyph->glyph_not_available_p = 0;
17619 glyph->face_id = it->face_id;
17620 glyph->u.cmp_id = it->cmp_id;
17621 glyph->font_type = FONT_TYPE_UNKNOWN;
17622 ++it->glyph_row->used[area];
17623 }
17624 }
17625
17626
17627 /* Change IT->ascent and IT->height according to the setting of
17628 IT->voffset. */
17629
17630 static INLINE void
17631 take_vertical_position_into_account (it)
17632 struct it *it;
17633 {
17634 if (it->voffset)
17635 {
17636 if (it->voffset < 0)
17637 /* Increase the ascent so that we can display the text higher
17638 in the line. */
17639 it->ascent += abs (it->voffset);
17640 else
17641 /* Increase the descent so that we can display the text lower
17642 in the line. */
17643 it->descent += it->voffset;
17644 }
17645 }
17646
17647
17648 /* Produce glyphs/get display metrics for the image IT is loaded with.
17649 See the description of struct display_iterator in dispextern.h for
17650 an overview of struct display_iterator. */
17651
17652 static void
17653 produce_image_glyph (it)
17654 struct it *it;
17655 {
17656 struct image *img;
17657 struct face *face;
17658
17659 xassert (it->what == IT_IMAGE);
17660
17661 face = FACE_FROM_ID (it->f, it->face_id);
17662 img = IMAGE_FROM_ID (it->f, it->image_id);
17663 xassert (img);
17664
17665 /* Make sure X resources of the face and image are loaded. */
17666 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17667 prepare_image_for_display (it->f, img);
17668
17669 it->ascent = it->phys_ascent = image_ascent (img, face);
17670 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17671 it->pixel_width = img->width + 2 * img->hmargin;
17672
17673 it->nglyphs = 1;
17674
17675 if (face->box != FACE_NO_BOX)
17676 {
17677 if (face->box_line_width > 0)
17678 {
17679 it->ascent += face->box_line_width;
17680 it->descent += face->box_line_width;
17681 }
17682
17683 if (it->start_of_box_run_p)
17684 it->pixel_width += abs (face->box_line_width);
17685 if (it->end_of_box_run_p)
17686 it->pixel_width += abs (face->box_line_width);
17687 }
17688
17689 take_vertical_position_into_account (it);
17690
17691 if (it->glyph_row)
17692 {
17693 struct glyph *glyph;
17694 enum glyph_row_area area = it->area;
17695
17696 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17697 if (glyph < it->glyph_row->glyphs[area + 1])
17698 {
17699 glyph->charpos = CHARPOS (it->position);
17700 glyph->object = it->object;
17701 glyph->pixel_width = it->pixel_width;
17702 glyph->voffset = it->voffset;
17703 glyph->type = IMAGE_GLYPH;
17704 glyph->multibyte_p = it->multibyte_p;
17705 glyph->left_box_line_p = it->start_of_box_run_p;
17706 glyph->right_box_line_p = it->end_of_box_run_p;
17707 glyph->overlaps_vertically_p = 0;
17708 glyph->padding_p = 0;
17709 glyph->glyph_not_available_p = 0;
17710 glyph->face_id = it->face_id;
17711 glyph->u.img_id = img->id;
17712 glyph->font_type = FONT_TYPE_UNKNOWN;
17713 ++it->glyph_row->used[area];
17714 }
17715 }
17716 }
17717
17718
17719 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17720 of the glyph, WIDTH and HEIGHT are the width and height of the
17721 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
17722 ascent of the glyph (0 <= ASCENT <= 1). */
17723
17724 static void
17725 append_stretch_glyph (it, object, width, height, ascent)
17726 struct it *it;
17727 Lisp_Object object;
17728 int width, height;
17729 double ascent;
17730 {
17731 struct glyph *glyph;
17732 enum glyph_row_area area = it->area;
17733
17734 xassert (ascent >= 0 && ascent <= 1);
17735
17736 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17737 if (glyph < it->glyph_row->glyphs[area + 1])
17738 {
17739 glyph->charpos = CHARPOS (it->position);
17740 glyph->object = object;
17741 glyph->pixel_width = width;
17742 glyph->voffset = it->voffset;
17743 glyph->type = STRETCH_GLYPH;
17744 glyph->multibyte_p = it->multibyte_p;
17745 glyph->left_box_line_p = it->start_of_box_run_p;
17746 glyph->right_box_line_p = it->end_of_box_run_p;
17747 glyph->overlaps_vertically_p = 0;
17748 glyph->padding_p = 0;
17749 glyph->glyph_not_available_p = 0;
17750 glyph->face_id = it->face_id;
17751 glyph->u.stretch.ascent = height * ascent;
17752 glyph->u.stretch.height = height;
17753 glyph->font_type = FONT_TYPE_UNKNOWN;
17754 ++it->glyph_row->used[area];
17755 }
17756 }
17757
17758
17759 /* Produce a stretch glyph for iterator IT. IT->object is the value
17760 of the glyph property displayed. The value must be a list
17761 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17762 being recognized:
17763
17764 1. `:width WIDTH' specifies that the space should be WIDTH *
17765 canonical char width wide. WIDTH may be an integer or floating
17766 point number.
17767
17768 2. `:relative-width FACTOR' specifies that the width of the stretch
17769 should be computed from the width of the first character having the
17770 `glyph' property, and should be FACTOR times that width.
17771
17772 3. `:align-to HPOS' specifies that the space should be wide enough
17773 to reach HPOS, a value in canonical character units.
17774
17775 Exactly one of the above pairs must be present.
17776
17777 4. `:height HEIGHT' specifies that the height of the stretch produced
17778 should be HEIGHT, measured in canonical character units.
17779
17780 5. `:relative-height FACTOR' specifies that the height of the
17781 stretch should be FACTOR times the height of the characters having
17782 the glyph property.
17783
17784 Either none or exactly one of 4 or 5 must be present.
17785
17786 6. `:ascent ASCENT' specifies that ASCENT percent of the height
17787 of the stretch should be used for the ascent of the stretch.
17788 ASCENT must be in the range 0 <= ASCENT <= 100. */
17789
17790 #define NUMVAL(X) \
17791 ((INTEGERP (X) || FLOATP (X)) \
17792 ? XFLOATINT (X) \
17793 : - 1)
17794
17795
17796 static void
17797 produce_stretch_glyph (it)
17798 struct it *it;
17799 {
17800 /* (space :width WIDTH :height HEIGHT. */
17801 Lisp_Object prop, plist;
17802 int width = 0, height = 0;
17803 double ascent = 0;
17804 struct face *face = FACE_FROM_ID (it->f, it->face_id);
17805 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
17806
17807 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17808
17809 /* List should start with `space'. */
17810 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
17811 plist = XCDR (it->object);
17812
17813 /* Compute the width of the stretch. */
17814 if (prop = Fplist_get (plist, QCwidth),
17815 NUMVAL (prop) > 0)
17816 /* Absolute width `:width WIDTH' specified and valid. */
17817 width = NUMVAL (prop) * FRAME_COLUMN_WIDTH (it->f);
17818 else if (prop = Fplist_get (plist, QCrelative_width),
17819 NUMVAL (prop) > 0)
17820 {
17821 /* Relative width `:relative-width FACTOR' specified and valid.
17822 Compute the width of the characters having the `glyph'
17823 property. */
17824 struct it it2;
17825 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
17826
17827 it2 = *it;
17828 if (it->multibyte_p)
17829 {
17830 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
17831 - IT_BYTEPOS (*it));
17832 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
17833 }
17834 else
17835 it2.c = *p, it2.len = 1;
17836
17837 it2.glyph_row = NULL;
17838 it2.what = IT_CHARACTER;
17839 x_produce_glyphs (&it2);
17840 width = NUMVAL (prop) * it2.pixel_width;
17841 }
17842 else if (prop = Fplist_get (plist, QCalign_to),
17843 NUMVAL (prop) > 0)
17844 width = NUMVAL (prop) * FRAME_COLUMN_WIDTH (it->f) - it->current_x;
17845 else
17846 /* Nothing specified -> width defaults to canonical char width. */
17847 width = FRAME_COLUMN_WIDTH (it->f);
17848
17849 /* Compute height. */
17850 if (prop = Fplist_get (plist, QCheight),
17851 NUMVAL (prop) > 0)
17852 height = NUMVAL (prop) * FRAME_LINE_HEIGHT (it->f);
17853 else if (prop = Fplist_get (plist, QCrelative_height),
17854 NUMVAL (prop) > 0)
17855 height = FONT_HEIGHT (font) * NUMVAL (prop);
17856 else
17857 height = FONT_HEIGHT (font);
17858
17859 /* Compute percentage of height used for ascent. If
17860 `:ascent ASCENT' is present and valid, use that. Otherwise,
17861 derive the ascent from the font in use. */
17862 if (prop = Fplist_get (plist, QCascent),
17863 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
17864 ascent = NUMVAL (prop) / 100.0;
17865 else
17866 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
17867
17868 if (width <= 0)
17869 width = 1;
17870 if (height <= 0)
17871 height = 1;
17872
17873 if (it->glyph_row)
17874 {
17875 Lisp_Object object = it->stack[it->sp - 1].string;
17876 if (!STRINGP (object))
17877 object = it->w->buffer;
17878 append_stretch_glyph (it, object, width, height, ascent);
17879 }
17880
17881 it->pixel_width = width;
17882 it->ascent = it->phys_ascent = height * ascent;
17883 it->descent = it->phys_descent = height - it->ascent;
17884 it->nglyphs = 1;
17885
17886 if (face->box != FACE_NO_BOX)
17887 {
17888 if (face->box_line_width > 0)
17889 {
17890 it->ascent += face->box_line_width;
17891 it->descent += face->box_line_width;
17892 }
17893
17894 if (it->start_of_box_run_p)
17895 it->pixel_width += abs (face->box_line_width);
17896 if (it->end_of_box_run_p)
17897 it->pixel_width += abs (face->box_line_width);
17898 }
17899
17900 take_vertical_position_into_account (it);
17901 }
17902
17903 /* RIF:
17904 Produce glyphs/get display metrics for the display element IT is
17905 loaded with. See the description of struct display_iterator in
17906 dispextern.h for an overview of struct display_iterator. */
17907
17908 void
17909 x_produce_glyphs (it)
17910 struct it *it;
17911 {
17912 it->glyph_not_available_p = 0;
17913
17914 if (it->what == IT_CHARACTER)
17915 {
17916 XChar2b char2b;
17917 XFontStruct *font;
17918 struct face *face = FACE_FROM_ID (it->f, it->face_id);
17919 XCharStruct *pcm;
17920 int font_not_found_p;
17921 struct font_info *font_info;
17922 int boff; /* baseline offset */
17923 /* We may change it->multibyte_p upon unibyte<->multibyte
17924 conversion. So, save the current value now and restore it
17925 later.
17926
17927 Note: It seems that we don't have to record multibyte_p in
17928 struct glyph because the character code itself tells if or
17929 not the character is multibyte. Thus, in the future, we must
17930 consider eliminating the field `multibyte_p' in the struct
17931 glyph. */
17932 int saved_multibyte_p = it->multibyte_p;
17933
17934 /* Maybe translate single-byte characters to multibyte, or the
17935 other way. */
17936 it->char_to_display = it->c;
17937 if (!ASCII_BYTE_P (it->c)
17938 && ! it->multibyte_p)
17939 {
17940 if (SINGLE_BYTE_CHAR_P (it->c)
17941 && unibyte_display_via_language_environment)
17942 it->char_to_display = unibyte_char_to_multibyte (it->c);
17943 if (! SINGLE_BYTE_CHAR_P (it->c))
17944 {
17945 it->multibyte_p = 1;
17946 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
17947 -1, Qnil);
17948 face = FACE_FROM_ID (it->f, it->face_id);
17949 }
17950 }
17951
17952 /* Get font to use. Encode IT->char_to_display. */
17953 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
17954 &char2b, it->multibyte_p, 0);
17955 font = face->font;
17956
17957 /* When no suitable font found, use the default font. */
17958 font_not_found_p = font == NULL;
17959 if (font_not_found_p)
17960 {
17961 font = FRAME_FONT (it->f);
17962 boff = FRAME_BASELINE_OFFSET (it->f);
17963 font_info = NULL;
17964 }
17965 else
17966 {
17967 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
17968 boff = font_info->baseline_offset;
17969 if (font_info->vertical_centering)
17970 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
17971 }
17972
17973 if (it->char_to_display >= ' '
17974 && (!it->multibyte_p || it->char_to_display < 128))
17975 {
17976 /* Either unibyte or ASCII. */
17977 int stretched_p;
17978
17979 it->nglyphs = 1;
17980
17981 pcm = rif->per_char_metric (font, &char2b,
17982 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
17983 it->ascent = FONT_BASE (font) + boff;
17984 it->descent = FONT_DESCENT (font) - boff;
17985
17986 if (pcm)
17987 {
17988 it->phys_ascent = pcm->ascent + boff;
17989 it->phys_descent = pcm->descent - boff;
17990 it->pixel_width = pcm->width;
17991 }
17992 else
17993 {
17994 it->glyph_not_available_p = 1;
17995 it->phys_ascent = FONT_BASE (font) + boff;
17996 it->phys_descent = FONT_DESCENT (font) - boff;
17997 it->pixel_width = FONT_WIDTH (font);
17998 }
17999
18000 /* If this is a space inside a region of text with
18001 `space-width' property, change its width. */
18002 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18003 if (stretched_p)
18004 it->pixel_width *= XFLOATINT (it->space_width);
18005
18006 /* If face has a box, add the box thickness to the character
18007 height. If character has a box line to the left and/or
18008 right, add the box line width to the character's width. */
18009 if (face->box != FACE_NO_BOX)
18010 {
18011 int thick = face->box_line_width;
18012
18013 if (thick > 0)
18014 {
18015 it->ascent += thick;
18016 it->descent += thick;
18017 }
18018 else
18019 thick = -thick;
18020
18021 if (it->start_of_box_run_p)
18022 it->pixel_width += thick;
18023 if (it->end_of_box_run_p)
18024 it->pixel_width += thick;
18025 }
18026
18027 /* If face has an overline, add the height of the overline
18028 (1 pixel) and a 1 pixel margin to the character height. */
18029 if (face->overline_p)
18030 it->ascent += 2;
18031
18032 take_vertical_position_into_account (it);
18033
18034 /* If we have to actually produce glyphs, do it. */
18035 if (it->glyph_row)
18036 {
18037 if (stretched_p)
18038 {
18039 /* Translate a space with a `space-width' property
18040 into a stretch glyph. */
18041 double ascent = (double) FONT_BASE (font)
18042 / FONT_HEIGHT (font);
18043 append_stretch_glyph (it, it->object, it->pixel_width,
18044 it->ascent + it->descent, ascent);
18045 }
18046 else
18047 append_glyph (it);
18048
18049 /* If characters with lbearing or rbearing are displayed
18050 in this line, record that fact in a flag of the
18051 glyph row. This is used to optimize X output code. */
18052 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18053 it->glyph_row->contains_overlapping_glyphs_p = 1;
18054 }
18055 }
18056 else if (it->char_to_display == '\n')
18057 {
18058 /* A newline has no width but we need the height of the line. */
18059 it->pixel_width = 0;
18060 it->nglyphs = 0;
18061 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18062 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18063
18064 if (face->box != FACE_NO_BOX
18065 && face->box_line_width > 0)
18066 {
18067 it->ascent += face->box_line_width;
18068 it->descent += face->box_line_width;
18069 }
18070 }
18071 else if (it->char_to_display == '\t')
18072 {
18073 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18074 int x = it->current_x + it->continuation_lines_width;
18075 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18076
18077 /* If the distance from the current position to the next tab
18078 stop is less than a canonical character width, use the
18079 tab stop after that. */
18080 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18081 next_tab_x += tab_width;
18082
18083 it->pixel_width = next_tab_x - x;
18084 it->nglyphs = 1;
18085 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18086 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18087
18088 if (it->glyph_row)
18089 {
18090 double ascent = (double) it->ascent / (it->ascent + it->descent);
18091 append_stretch_glyph (it, it->object, it->pixel_width,
18092 it->ascent + it->descent, ascent);
18093 }
18094 }
18095 else
18096 {
18097 /* A multi-byte character. Assume that the display width of the
18098 character is the width of the character multiplied by the
18099 width of the font. */
18100
18101 /* If we found a font, this font should give us the right
18102 metrics. If we didn't find a font, use the frame's
18103 default font and calculate the width of the character by
18104 multiplying the width of font by the width of the
18105 character. */
18106
18107 pcm = rif->per_char_metric (font, &char2b,
18108 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18109
18110 if (font_not_found_p || !pcm)
18111 {
18112 it->glyph_not_available_p = 1;
18113 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18114 * CHAR_WIDTH (it->char_to_display));
18115 it->phys_ascent = FONT_BASE (font) + boff;
18116 it->phys_descent = FONT_DESCENT (font) - boff;
18117 }
18118 else
18119 {
18120 it->pixel_width = pcm->width;
18121 it->phys_ascent = pcm->ascent + boff;
18122 it->phys_descent = pcm->descent - boff;
18123 if (it->glyph_row
18124 && (pcm->lbearing < 0
18125 || pcm->rbearing > pcm->width))
18126 it->glyph_row->contains_overlapping_glyphs_p = 1;
18127 }
18128 it->nglyphs = 1;
18129 it->ascent = FONT_BASE (font) + boff;
18130 it->descent = FONT_DESCENT (font) - boff;
18131 if (face->box != FACE_NO_BOX)
18132 {
18133 int thick = face->box_line_width;
18134
18135 if (thick > 0)
18136 {
18137 it->ascent += thick;
18138 it->descent += thick;
18139 }
18140 else
18141 thick = - thick;
18142
18143 if (it->start_of_box_run_p)
18144 it->pixel_width += thick;
18145 if (it->end_of_box_run_p)
18146 it->pixel_width += thick;
18147 }
18148
18149 /* If face has an overline, add the height of the overline
18150 (1 pixel) and a 1 pixel margin to the character height. */
18151 if (face->overline_p)
18152 it->ascent += 2;
18153
18154 take_vertical_position_into_account (it);
18155
18156 if (it->glyph_row)
18157 append_glyph (it);
18158 }
18159 it->multibyte_p = saved_multibyte_p;
18160 }
18161 else if (it->what == IT_COMPOSITION)
18162 {
18163 /* Note: A composition is represented as one glyph in the
18164 glyph matrix. There are no padding glyphs. */
18165 XChar2b char2b;
18166 XFontStruct *font;
18167 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18168 XCharStruct *pcm;
18169 int font_not_found_p;
18170 struct font_info *font_info;
18171 int boff; /* baseline offset */
18172 struct composition *cmp = composition_table[it->cmp_id];
18173 int pos;
18174
18175 /* Maybe translate single-byte characters to multibyte. */
18176 it->char_to_display = it->c;
18177 if (unibyte_display_via_language_environment
18178 && it->c >= 0200)
18179 {
18180 it->char_to_display = unibyte_char_to_multibyte (it->c);
18181 }
18182
18183 /* Get face and font to use. Encode IT->char_to_display. */
18184 pos = STRINGP (it->string) ? IT_STRING_CHARPOS (*it) : IT_CHARPOS (*it);
18185 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
18186 pos, it->string);
18187 face = FACE_FROM_ID (it->f, it->face_id);
18188 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18189 &char2b, it->multibyte_p, 0);
18190 font = face->font;
18191
18192 /* When no suitable font found, use the default font. */
18193 font_not_found_p = font == NULL;
18194 if (font_not_found_p)
18195 {
18196 font = FRAME_FONT (it->f);
18197 boff = FRAME_BASELINE_OFFSET (it->f);
18198 font_info = NULL;
18199 }
18200 else
18201 {
18202 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18203 boff = font_info->baseline_offset;
18204 if (font_info->vertical_centering)
18205 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18206 }
18207
18208 /* There are no padding glyphs, so there is only one glyph to
18209 produce for the composition. Important is that pixel_width,
18210 ascent and descent are the values of what is drawn by
18211 draw_glyphs (i.e. the values of the overall glyphs composed). */
18212 it->nglyphs = 1;
18213
18214 /* If we have not yet calculated pixel size data of glyphs of
18215 the composition for the current face font, calculate them
18216 now. Theoretically, we have to check all fonts for the
18217 glyphs, but that requires much time and memory space. So,
18218 here we check only the font of the first glyph. This leads
18219 to incorrect display, but it's very rare, and C-l (recenter)
18220 can correct the display anyway. */
18221 if (cmp->font != (void *) font)
18222 {
18223 /* Ascent and descent of the font of the first character of
18224 this composition (adjusted by baseline offset). Ascent
18225 and descent of overall glyphs should not be less than
18226 them respectively. */
18227 int font_ascent = FONT_BASE (font) + boff;
18228 int font_descent = FONT_DESCENT (font) - boff;
18229 int font_height = FONT_HEIGHT (font);
18230 /* Bounding box of the overall glyphs. */
18231 int leftmost, rightmost, lowest, highest;
18232 int lbearing, rbearing;
18233 int i, width, ascent, descent;
18234
18235 cmp->font = (void *) font;
18236
18237 /* Initialize the bounding box. */
18238 if (font_info
18239 && (pcm = rif->per_char_metric (font, &char2b,
18240 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18241 {
18242 width = pcm->width;
18243 ascent = pcm->ascent;
18244 descent = pcm->descent;
18245 lbearing = pcm->lbearing;
18246 if (lbearing > 0)
18247 lbearing = 0;
18248 rbearing = pcm->rbearing;
18249 if (rbearing < width)
18250 rbearing = width;
18251 }
18252 else
18253 {
18254 width = FONT_WIDTH (font);
18255 ascent = FONT_BASE (font);
18256 descent = FONT_DESCENT (font);
18257 lbearing = 0;
18258 rbearing = width;
18259 }
18260
18261 rightmost = width;
18262 lowest = - descent + boff;
18263 highest = ascent + boff;
18264 leftmost = 0;
18265
18266 if (font_info
18267 && font_info->default_ascent
18268 && CHAR_TABLE_P (Vuse_default_ascent)
18269 && !NILP (Faref (Vuse_default_ascent,
18270 make_number (it->char_to_display))))
18271 highest = font_info->default_ascent + boff;
18272
18273 /* Draw the first glyph at the normal position. It may be
18274 shifted to right later if some other glyphs are drawn at
18275 the left. */
18276 cmp->offsets[0] = 0;
18277 cmp->offsets[1] = boff;
18278 cmp->lbearing = lbearing;
18279 cmp->rbearing = rbearing;
18280
18281 /* Set cmp->offsets for the remaining glyphs. */
18282 for (i = 1; i < cmp->glyph_len; i++)
18283 {
18284 int left, right, btm, top;
18285 int ch = COMPOSITION_GLYPH (cmp, i);
18286 int face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
18287
18288 face = FACE_FROM_ID (it->f, face_id);
18289 get_char_face_and_encoding (it->f, ch, face->id,
18290 &char2b, it->multibyte_p, 0);
18291 font = face->font;
18292 if (font == NULL)
18293 {
18294 font = FRAME_FONT (it->f);
18295 boff = FRAME_BASELINE_OFFSET (it->f);
18296 font_info = NULL;
18297 }
18298 else
18299 {
18300 font_info
18301 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18302 boff = font_info->baseline_offset;
18303 if (font_info->vertical_centering)
18304 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18305 }
18306
18307 if (font_info
18308 && (pcm = rif->per_char_metric (font, &char2b,
18309 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18310 {
18311 width = pcm->width;
18312 ascent = pcm->ascent;
18313 descent = pcm->descent;
18314 lbearing = pcm->lbearing;
18315 if (lbearing > 0)
18316 lbearing = 0;
18317 rbearing = pcm->rbearing;
18318 if (rbearing < width)
18319 rbearing = width;
18320 }
18321 else
18322 {
18323 width = FONT_WIDTH (font);
18324 ascent = 1;
18325 descent = 0;
18326 lbearing = 0;
18327 rbearing = width;
18328 }
18329
18330 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18331 {
18332 /* Relative composition with or without
18333 alternate chars. */
18334 left = (leftmost + rightmost - width) / 2;
18335 btm = - descent + boff;
18336 if (font_info && font_info->relative_compose
18337 && (! CHAR_TABLE_P (Vignore_relative_composition)
18338 || NILP (Faref (Vignore_relative_composition,
18339 make_number (ch)))))
18340 {
18341
18342 if (- descent >= font_info->relative_compose)
18343 /* One extra pixel between two glyphs. */
18344 btm = highest + 1;
18345 else if (ascent <= 0)
18346 /* One extra pixel between two glyphs. */
18347 btm = lowest - 1 - ascent - descent;
18348 }
18349 }
18350 else
18351 {
18352 /* A composition rule is specified by an integer
18353 value that encodes global and new reference
18354 points (GREF and NREF). GREF and NREF are
18355 specified by numbers as below:
18356
18357 0---1---2 -- ascent
18358 | |
18359 | |
18360 | |
18361 9--10--11 -- center
18362 | |
18363 ---3---4---5--- baseline
18364 | |
18365 6---7---8 -- descent
18366 */
18367 int rule = COMPOSITION_RULE (cmp, i);
18368 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
18369
18370 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
18371 grefx = gref % 3, nrefx = nref % 3;
18372 grefy = gref / 3, nrefy = nref / 3;
18373 if (xoff)
18374 xoff = font_height * (xoff - 128) / 256;
18375 if (yoff)
18376 yoff = font_height * (yoff - 128) / 256;
18377
18378 left = (leftmost
18379 + grefx * (rightmost - leftmost) / 2
18380 - nrefx * width / 2
18381 + xoff);
18382
18383 btm = ((grefy == 0 ? highest
18384 : grefy == 1 ? 0
18385 : grefy == 2 ? lowest
18386 : (highest + lowest) / 2)
18387 - (nrefy == 0 ? ascent + descent
18388 : nrefy == 1 ? descent - boff
18389 : nrefy == 2 ? 0
18390 : (ascent + descent) / 2)
18391 + yoff);
18392 }
18393
18394 cmp->offsets[i * 2] = left;
18395 cmp->offsets[i * 2 + 1] = btm + descent;
18396
18397 /* Update the bounding box of the overall glyphs. */
18398 if (width > 0)
18399 {
18400 right = left + width;
18401 if (left < leftmost)
18402 leftmost = left;
18403 if (right > rightmost)
18404 rightmost = right;
18405 }
18406 top = btm + descent + ascent;
18407 if (top > highest)
18408 highest = top;
18409 if (btm < lowest)
18410 lowest = btm;
18411
18412 if (cmp->lbearing > left + lbearing)
18413 cmp->lbearing = left + lbearing;
18414 if (cmp->rbearing < left + rbearing)
18415 cmp->rbearing = left + rbearing;
18416 }
18417
18418 /* If there are glyphs whose x-offsets are negative,
18419 shift all glyphs to the right and make all x-offsets
18420 non-negative. */
18421 if (leftmost < 0)
18422 {
18423 for (i = 0; i < cmp->glyph_len; i++)
18424 cmp->offsets[i * 2] -= leftmost;
18425 rightmost -= leftmost;
18426 cmp->lbearing -= leftmost;
18427 cmp->rbearing -= leftmost;
18428 }
18429
18430 cmp->pixel_width = rightmost;
18431 cmp->ascent = highest;
18432 cmp->descent = - lowest;
18433 if (cmp->ascent < font_ascent)
18434 cmp->ascent = font_ascent;
18435 if (cmp->descent < font_descent)
18436 cmp->descent = font_descent;
18437 }
18438
18439 if (it->glyph_row
18440 && (cmp->lbearing < 0
18441 || cmp->rbearing > cmp->pixel_width))
18442 it->glyph_row->contains_overlapping_glyphs_p = 1;
18443
18444 it->pixel_width = cmp->pixel_width;
18445 it->ascent = it->phys_ascent = cmp->ascent;
18446 it->descent = it->phys_descent = cmp->descent;
18447
18448 if (face->box != FACE_NO_BOX)
18449 {
18450 int thick = face->box_line_width;
18451
18452 if (thick > 0)
18453 {
18454 it->ascent += thick;
18455 it->descent += thick;
18456 }
18457 else
18458 thick = - thick;
18459
18460 if (it->start_of_box_run_p)
18461 it->pixel_width += thick;
18462 if (it->end_of_box_run_p)
18463 it->pixel_width += thick;
18464 }
18465
18466 /* If face has an overline, add the height of the overline
18467 (1 pixel) and a 1 pixel margin to the character height. */
18468 if (face->overline_p)
18469 it->ascent += 2;
18470
18471 take_vertical_position_into_account (it);
18472
18473 if (it->glyph_row)
18474 append_composite_glyph (it);
18475 }
18476 else if (it->what == IT_IMAGE)
18477 produce_image_glyph (it);
18478 else if (it->what == IT_STRETCH)
18479 produce_stretch_glyph (it);
18480
18481 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18482 because this isn't true for images with `:ascent 100'. */
18483 xassert (it->ascent >= 0 && it->descent >= 0);
18484 if (it->area == TEXT_AREA)
18485 it->current_x += it->pixel_width;
18486
18487 it->descent += it->extra_line_spacing;
18488
18489 it->max_ascent = max (it->max_ascent, it->ascent);
18490 it->max_descent = max (it->max_descent, it->descent);
18491 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18492 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18493 }
18494
18495 /* EXPORT for RIF:
18496 Output LEN glyphs starting at START at the nominal cursor position.
18497 Advance the nominal cursor over the text. The global variable
18498 updated_window contains the window being updated, updated_row is
18499 the glyph row being updated, and updated_area is the area of that
18500 row being updated. */
18501
18502 void
18503 x_write_glyphs (start, len)
18504 struct glyph *start;
18505 int len;
18506 {
18507 int x, hpos;
18508
18509 xassert (updated_window && updated_row);
18510 BLOCK_INPUT;
18511
18512 /* Write glyphs. */
18513
18514 hpos = start - updated_row->glyphs[updated_area];
18515 x = draw_glyphs (updated_window, output_cursor.x,
18516 updated_row, updated_area,
18517 hpos, hpos + len,
18518 DRAW_NORMAL_TEXT, 0);
18519
18520 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18521 if (updated_area == TEXT_AREA
18522 && updated_window->phys_cursor_on_p
18523 && updated_window->phys_cursor.vpos == output_cursor.vpos
18524 && updated_window->phys_cursor.hpos >= hpos
18525 && updated_window->phys_cursor.hpos < hpos + len)
18526 updated_window->phys_cursor_on_p = 0;
18527
18528 UNBLOCK_INPUT;
18529
18530 /* Advance the output cursor. */
18531 output_cursor.hpos += len;
18532 output_cursor.x = x;
18533 }
18534
18535
18536 /* EXPORT for RIF:
18537 Insert LEN glyphs from START at the nominal cursor position. */
18538
18539 void
18540 x_insert_glyphs (start, len)
18541 struct glyph *start;
18542 int len;
18543 {
18544 struct frame *f;
18545 struct window *w;
18546 int line_height, shift_by_width, shifted_region_width;
18547 struct glyph_row *row;
18548 struct glyph *glyph;
18549 int frame_x, frame_y;
18550 EMACS_INT hpos;
18551
18552 xassert (updated_window && updated_row);
18553 BLOCK_INPUT;
18554 w = updated_window;
18555 f = XFRAME (WINDOW_FRAME (w));
18556
18557 /* Get the height of the line we are in. */
18558 row = updated_row;
18559 line_height = row->height;
18560
18561 /* Get the width of the glyphs to insert. */
18562 shift_by_width = 0;
18563 for (glyph = start; glyph < start + len; ++glyph)
18564 shift_by_width += glyph->pixel_width;
18565
18566 /* Get the width of the region to shift right. */
18567 shifted_region_width = (window_box_width (w, updated_area)
18568 - output_cursor.x
18569 - shift_by_width);
18570
18571 /* Shift right. */
18572 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18573 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18574
18575 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18576 line_height, shift_by_width);
18577
18578 /* Write the glyphs. */
18579 hpos = start - row->glyphs[updated_area];
18580 draw_glyphs (w, output_cursor.x, row, updated_area,
18581 hpos, hpos + len,
18582 DRAW_NORMAL_TEXT, 0);
18583
18584 /* Advance the output cursor. */
18585 output_cursor.hpos += len;
18586 output_cursor.x += shift_by_width;
18587 UNBLOCK_INPUT;
18588 }
18589
18590
18591 /* EXPORT for RIF:
18592 Erase the current text line from the nominal cursor position
18593 (inclusive) to pixel column TO_X (exclusive). The idea is that
18594 everything from TO_X onward is already erased.
18595
18596 TO_X is a pixel position relative to updated_area of
18597 updated_window. TO_X == -1 means clear to the end of this area. */
18598
18599 void
18600 x_clear_end_of_line (to_x)
18601 int to_x;
18602 {
18603 struct frame *f;
18604 struct window *w = updated_window;
18605 int max_x, min_y, max_y;
18606 int from_x, from_y, to_y;
18607
18608 xassert (updated_window && updated_row);
18609 f = XFRAME (w->frame);
18610
18611 if (updated_row->full_width_p)
18612 max_x = WINDOW_TOTAL_WIDTH (w);
18613 else
18614 max_x = window_box_width (w, updated_area);
18615 max_y = window_text_bottom_y (w);
18616
18617 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18618 of window. For TO_X > 0, truncate to end of drawing area. */
18619 if (to_x == 0)
18620 return;
18621 else if (to_x < 0)
18622 to_x = max_x;
18623 else
18624 to_x = min (to_x, max_x);
18625
18626 to_y = min (max_y, output_cursor.y + updated_row->height);
18627
18628 /* Notice if the cursor will be cleared by this operation. */
18629 if (!updated_row->full_width_p)
18630 notice_overwritten_cursor (w, updated_area,
18631 output_cursor.x, -1,
18632 updated_row->y,
18633 MATRIX_ROW_BOTTOM_Y (updated_row));
18634
18635 from_x = output_cursor.x;
18636
18637 /* Translate to frame coordinates. */
18638 if (updated_row->full_width_p)
18639 {
18640 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18641 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18642 }
18643 else
18644 {
18645 int area_left = window_box_left (w, updated_area);
18646 from_x += area_left;
18647 to_x += area_left;
18648 }
18649
18650 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18651 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18652 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18653
18654 /* Prevent inadvertently clearing to end of the X window. */
18655 if (to_x > from_x && to_y > from_y)
18656 {
18657 BLOCK_INPUT;
18658 rif->clear_frame_area (f, from_x, from_y,
18659 to_x - from_x, to_y - from_y);
18660 UNBLOCK_INPUT;
18661 }
18662 }
18663
18664 #endif /* HAVE_WINDOW_SYSTEM */
18665
18666
18667 \f
18668 /***********************************************************************
18669 Cursor types
18670 ***********************************************************************/
18671
18672 /* Value is the internal representation of the specified cursor type
18673 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18674 of the bar cursor. */
18675
18676 enum text_cursor_kinds
18677 get_specified_cursor_type (arg, width)
18678 Lisp_Object arg;
18679 int *width;
18680 {
18681 enum text_cursor_kinds type;
18682
18683 if (NILP (arg))
18684 return NO_CURSOR;
18685
18686 if (EQ (arg, Qbox))
18687 return FILLED_BOX_CURSOR;
18688
18689 if (EQ (arg, Qhollow))
18690 return HOLLOW_BOX_CURSOR;
18691
18692 if (EQ (arg, Qbar))
18693 {
18694 *width = 2;
18695 return BAR_CURSOR;
18696 }
18697
18698 if (CONSP (arg)
18699 && EQ (XCAR (arg), Qbar)
18700 && INTEGERP (XCDR (arg))
18701 && XINT (XCDR (arg)) >= 0)
18702 {
18703 *width = XINT (XCDR (arg));
18704 return BAR_CURSOR;
18705 }
18706
18707 if (EQ (arg, Qhbar))
18708 {
18709 *width = 2;
18710 return HBAR_CURSOR;
18711 }
18712
18713 if (CONSP (arg)
18714 && EQ (XCAR (arg), Qhbar)
18715 && INTEGERP (XCDR (arg))
18716 && XINT (XCDR (arg)) >= 0)
18717 {
18718 *width = XINT (XCDR (arg));
18719 return HBAR_CURSOR;
18720 }
18721
18722 /* Treat anything unknown as "hollow box cursor".
18723 It was bad to signal an error; people have trouble fixing
18724 .Xdefaults with Emacs, when it has something bad in it. */
18725 type = HOLLOW_BOX_CURSOR;
18726
18727 return type;
18728 }
18729
18730 /* Set the default cursor types for specified frame. */
18731 void
18732 set_frame_cursor_types (f, arg)
18733 struct frame *f;
18734 Lisp_Object arg;
18735 {
18736 int width;
18737 Lisp_Object tem;
18738
18739 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
18740 FRAME_CURSOR_WIDTH (f) = width;
18741
18742 /* By default, set up the blink-off state depending on the on-state. */
18743
18744 tem = Fassoc (arg, Vblink_cursor_alist);
18745 if (!NILP (tem))
18746 {
18747 FRAME_BLINK_OFF_CURSOR (f)
18748 = get_specified_cursor_type (XCDR (tem), &width);
18749 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
18750 }
18751 else
18752 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
18753 }
18754
18755
18756 /* Return the cursor we want to be displayed in window W. Return
18757 width of bar/hbar cursor through WIDTH arg. Return with
18758 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18759 (i.e. if the `system caret' should track this cursor).
18760
18761 In a mini-buffer window, we want the cursor only to appear if we
18762 are reading input from this window. For the selected window, we
18763 want the cursor type given by the frame parameter or buffer local
18764 setting of cursor-type. If explicitly marked off, draw no cursor.
18765 In all other cases, we want a hollow box cursor. */
18766
18767 enum text_cursor_kinds
18768 get_window_cursor_type (w, width, active_cursor)
18769 struct window *w;
18770 int *width;
18771 int *active_cursor;
18772 {
18773 struct frame *f = XFRAME (w->frame);
18774 struct buffer *b = XBUFFER (w->buffer);
18775 int cursor_type = DEFAULT_CURSOR;
18776 Lisp_Object alt_cursor;
18777 int non_selected = 0;
18778
18779 *active_cursor = 1;
18780
18781 /* Echo area */
18782 if (cursor_in_echo_area
18783 && FRAME_HAS_MINIBUF_P (f)
18784 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
18785 {
18786 if (w == XWINDOW (echo_area_window))
18787 {
18788 *width = FRAME_CURSOR_WIDTH (f);
18789 return FRAME_DESIRED_CURSOR (f);
18790 }
18791
18792 *active_cursor = 0;
18793 non_selected = 1;
18794 }
18795
18796 /* Nonselected window or nonselected frame. */
18797 else if (w != XWINDOW (f->selected_window)
18798 #ifdef HAVE_WINDOW_SYSTEM
18799 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
18800 #endif
18801 )
18802 {
18803 *active_cursor = 0;
18804
18805 if (MINI_WINDOW_P (w) && minibuf_level == 0)
18806 return NO_CURSOR;
18807
18808 non_selected = 1;
18809 }
18810
18811 /* Never display a cursor in a window in which cursor-type is nil. */
18812 if (NILP (b->cursor_type))
18813 return NO_CURSOR;
18814
18815 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
18816 if (non_selected)
18817 {
18818 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
18819 return get_specified_cursor_type (alt_cursor, width);
18820 }
18821
18822 /* Get the normal cursor type for this window. */
18823 if (EQ (b->cursor_type, Qt))
18824 {
18825 cursor_type = FRAME_DESIRED_CURSOR (f);
18826 *width = FRAME_CURSOR_WIDTH (f);
18827 }
18828 else
18829 cursor_type = get_specified_cursor_type (b->cursor_type, width);
18830
18831 /* Use normal cursor if not blinked off. */
18832 if (!w->cursor_off_p)
18833 return cursor_type;
18834
18835 /* Cursor is blinked off, so determine how to "toggle" it. */
18836
18837 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
18838 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
18839 return get_specified_cursor_type (XCDR (alt_cursor), width);
18840
18841 /* Then see if frame has specified a specific blink off cursor type. */
18842 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
18843 {
18844 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
18845 return FRAME_BLINK_OFF_CURSOR (f);
18846 }
18847
18848 /* Finally perform built-in cursor blinking:
18849 filled box <-> hollow box
18850 wide [h]bar <-> narrow [h]bar
18851 narrow [h]bar <-> no cursor
18852 other type <-> no cursor */
18853
18854 if (cursor_type == FILLED_BOX_CURSOR)
18855 return HOLLOW_BOX_CURSOR;
18856
18857 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
18858 {
18859 *width = 1;
18860 return cursor_type;
18861 }
18862
18863 return NO_CURSOR;
18864 }
18865
18866
18867 #ifdef HAVE_WINDOW_SYSTEM
18868
18869 /* Notice when the text cursor of window W has been completely
18870 overwritten by a drawing operation that outputs glyphs in AREA
18871 starting at X0 and ending at X1 in the line starting at Y0 and
18872 ending at Y1. X coordinates are area-relative. X1 < 0 means all
18873 the rest of the line after X0 has been written. Y coordinates
18874 are window-relative. */
18875
18876 static void
18877 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
18878 struct window *w;
18879 enum glyph_row_area area;
18880 int x0, y0, x1, y1;
18881 {
18882 if (area == TEXT_AREA && w->phys_cursor_on_p)
18883 {
18884 int cx0 = w->phys_cursor.x;
18885 int cx1 = cx0 + w->phys_cursor_width;
18886 int cy0 = w->phys_cursor.y;
18887 int cy1 = cy0 + w->phys_cursor_height;
18888
18889 if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
18890 {
18891 /* The cursor image will be completely removed from the
18892 screen if the output area intersects the cursor area in
18893 y-direction. When we draw in [y0 y1[, and some part of
18894 the cursor is at y < y0, that part must have been drawn
18895 before. When scrolling, the cursor is erased before
18896 actually scrolling, so we don't come here. When not
18897 scrolling, the rows above the old cursor row must have
18898 changed, and in this case these rows must have written
18899 over the cursor image.
18900
18901 Likewise if part of the cursor is below y1, with the
18902 exception of the cursor being in the first blank row at
18903 the buffer and window end because update_text_area
18904 doesn't draw that row. (Except when it does, but
18905 that's handled in update_text_area.) */
18906
18907 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
18908 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
18909 w->phys_cursor_on_p = 0;
18910 }
18911 }
18912 }
18913
18914 #endif /* HAVE_WINDOW_SYSTEM */
18915
18916 \f
18917 /************************************************************************
18918 Mouse Face
18919 ************************************************************************/
18920
18921 #ifdef HAVE_WINDOW_SYSTEM
18922
18923 /* EXPORT for RIF:
18924 Fix the display of area AREA of overlapping row ROW in window W. */
18925
18926 void
18927 x_fix_overlapping_area (w, row, area)
18928 struct window *w;
18929 struct glyph_row *row;
18930 enum glyph_row_area area;
18931 {
18932 int i, x;
18933
18934 BLOCK_INPUT;
18935
18936 x = 0;
18937 for (i = 0; i < row->used[area];)
18938 {
18939 if (row->glyphs[area][i].overlaps_vertically_p)
18940 {
18941 int start = i, start_x = x;
18942
18943 do
18944 {
18945 x += row->glyphs[area][i].pixel_width;
18946 ++i;
18947 }
18948 while (i < row->used[area]
18949 && row->glyphs[area][i].overlaps_vertically_p);
18950
18951 draw_glyphs (w, start_x, row, area,
18952 start, i,
18953 DRAW_NORMAL_TEXT, 1);
18954 }
18955 else
18956 {
18957 x += row->glyphs[area][i].pixel_width;
18958 ++i;
18959 }
18960 }
18961
18962 UNBLOCK_INPUT;
18963 }
18964
18965
18966 /* EXPORT:
18967 Draw the cursor glyph of window W in glyph row ROW. See the
18968 comment of draw_glyphs for the meaning of HL. */
18969
18970 void
18971 draw_phys_cursor_glyph (w, row, hl)
18972 struct window *w;
18973 struct glyph_row *row;
18974 enum draw_glyphs_face hl;
18975 {
18976 /* If cursor hpos is out of bounds, don't draw garbage. This can
18977 happen in mini-buffer windows when switching between echo area
18978 glyphs and mini-buffer. */
18979 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
18980 {
18981 int on_p = w->phys_cursor_on_p;
18982 int x1;
18983 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
18984 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
18985 hl, 0);
18986 w->phys_cursor_on_p = on_p;
18987
18988 if (hl == DRAW_CURSOR)
18989 w->phys_cursor_width = x1 - w->phys_cursor.x;
18990 /* When we erase the cursor, and ROW is overlapped by other
18991 rows, make sure that these overlapping parts of other rows
18992 are redrawn. */
18993 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
18994 {
18995 if (row > w->current_matrix->rows
18996 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
18997 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
18998
18999 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19000 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19001 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19002 }
19003 }
19004 }
19005
19006
19007 /* EXPORT:
19008 Erase the image of a cursor of window W from the screen. */
19009
19010 void
19011 erase_phys_cursor (w)
19012 struct window *w;
19013 {
19014 struct frame *f = XFRAME (w->frame);
19015 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19016 int hpos = w->phys_cursor.hpos;
19017 int vpos = w->phys_cursor.vpos;
19018 int mouse_face_here_p = 0;
19019 struct glyph_matrix *active_glyphs = w->current_matrix;
19020 struct glyph_row *cursor_row;
19021 struct glyph *cursor_glyph;
19022 enum draw_glyphs_face hl;
19023
19024 /* No cursor displayed or row invalidated => nothing to do on the
19025 screen. */
19026 if (w->phys_cursor_type == NO_CURSOR)
19027 goto mark_cursor_off;
19028
19029 /* VPOS >= active_glyphs->nrows means that window has been resized.
19030 Don't bother to erase the cursor. */
19031 if (vpos >= active_glyphs->nrows)
19032 goto mark_cursor_off;
19033
19034 /* If row containing cursor is marked invalid, there is nothing we
19035 can do. */
19036 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19037 if (!cursor_row->enabled_p)
19038 goto mark_cursor_off;
19039
19040 /* If row is completely invisible, don't attempt to delete a cursor which
19041 isn't there. This can happen if cursor is at top of a window, and
19042 we switch to a buffer with a header line in that window. */
19043 if (cursor_row->visible_height <= 0)
19044 goto mark_cursor_off;
19045
19046 /* This can happen when the new row is shorter than the old one.
19047 In this case, either draw_glyphs or clear_end_of_line
19048 should have cleared the cursor. Note that we wouldn't be
19049 able to erase the cursor in this case because we don't have a
19050 cursor glyph at hand. */
19051 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19052 goto mark_cursor_off;
19053
19054 /* If the cursor is in the mouse face area, redisplay that when
19055 we clear the cursor. */
19056 if (! NILP (dpyinfo->mouse_face_window)
19057 && w == XWINDOW (dpyinfo->mouse_face_window)
19058 && (vpos > dpyinfo->mouse_face_beg_row
19059 || (vpos == dpyinfo->mouse_face_beg_row
19060 && hpos >= dpyinfo->mouse_face_beg_col))
19061 && (vpos < dpyinfo->mouse_face_end_row
19062 || (vpos == dpyinfo->mouse_face_end_row
19063 && hpos < dpyinfo->mouse_face_end_col))
19064 /* Don't redraw the cursor's spot in mouse face if it is at the
19065 end of a line (on a newline). The cursor appears there, but
19066 mouse highlighting does not. */
19067 && cursor_row->used[TEXT_AREA] > hpos)
19068 mouse_face_here_p = 1;
19069
19070 /* Maybe clear the display under the cursor. */
19071 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19072 {
19073 int x, y;
19074 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19075
19076 cursor_glyph = get_phys_cursor_glyph (w);
19077 if (cursor_glyph == NULL)
19078 goto mark_cursor_off;
19079
19080 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19081 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19082
19083 rif->clear_frame_area (f, x, y,
19084 cursor_glyph->pixel_width, cursor_row->visible_height);
19085 }
19086
19087 /* Erase the cursor by redrawing the character underneath it. */
19088 if (mouse_face_here_p)
19089 hl = DRAW_MOUSE_FACE;
19090 else
19091 hl = DRAW_NORMAL_TEXT;
19092 draw_phys_cursor_glyph (w, cursor_row, hl);
19093
19094 mark_cursor_off:
19095 w->phys_cursor_on_p = 0;
19096 w->phys_cursor_type = NO_CURSOR;
19097 }
19098
19099
19100 /* EXPORT:
19101 Display or clear cursor of window W. If ON is zero, clear the
19102 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19103 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19104
19105 void
19106 display_and_set_cursor (w, on, hpos, vpos, x, y)
19107 struct window *w;
19108 int on, hpos, vpos, x, y;
19109 {
19110 struct frame *f = XFRAME (w->frame);
19111 int new_cursor_type;
19112 int new_cursor_width;
19113 int active_cursor;
19114 struct glyph_matrix *current_glyphs;
19115 struct glyph_row *glyph_row;
19116
19117 /* This is pointless on invisible frames, and dangerous on garbaged
19118 windows and frames; in the latter case, the frame or window may
19119 be in the midst of changing its size, and x and y may be off the
19120 window. */
19121 if (! FRAME_VISIBLE_P (f)
19122 || FRAME_GARBAGED_P (f)
19123 || vpos >= w->current_matrix->nrows
19124 || hpos >= w->current_matrix->matrix_w)
19125 return;
19126
19127 /* If cursor is off and we want it off, return quickly. */
19128 if (!on && !w->phys_cursor_on_p)
19129 return;
19130
19131 current_glyphs = w->current_matrix;
19132 glyph_row = MATRIX_ROW (current_glyphs, vpos);
19133
19134 /* If cursor row is not enabled, we don't really know where to
19135 display the cursor. */
19136 if (!glyph_row->enabled_p)
19137 {
19138 w->phys_cursor_on_p = 0;
19139 return;
19140 }
19141
19142 xassert (interrupt_input_blocked);
19143
19144 /* Set new_cursor_type to the cursor we want to be displayed. */
19145 new_cursor_type = get_window_cursor_type (w, &new_cursor_width, &active_cursor);
19146
19147 /* If cursor is currently being shown and we don't want it to be or
19148 it is in the wrong place, or the cursor type is not what we want,
19149 erase it. */
19150 if (w->phys_cursor_on_p
19151 && (!on
19152 || w->phys_cursor.x != x
19153 || w->phys_cursor.y != y
19154 || new_cursor_type != w->phys_cursor_type
19155 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19156 && new_cursor_width != w->phys_cursor_width)))
19157 erase_phys_cursor (w);
19158
19159 /* Don't check phys_cursor_on_p here because that flag is only set
19160 to zero in some cases where we know that the cursor has been
19161 completely erased, to avoid the extra work of erasing the cursor
19162 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19163 still not be visible, or it has only been partly erased. */
19164 if (on)
19165 {
19166 w->phys_cursor_ascent = glyph_row->ascent;
19167 w->phys_cursor_height = glyph_row->height;
19168
19169 /* Set phys_cursor_.* before x_draw_.* is called because some
19170 of them may need the information. */
19171 w->phys_cursor.x = x;
19172 w->phys_cursor.y = glyph_row->y;
19173 w->phys_cursor.hpos = hpos;
19174 w->phys_cursor.vpos = vpos;
19175 }
19176
19177 rif->draw_window_cursor (w, glyph_row, x, y,
19178 new_cursor_type, new_cursor_width,
19179 on, active_cursor);
19180 }
19181
19182
19183 /* Switch the display of W's cursor on or off, according to the value
19184 of ON. */
19185
19186 static void
19187 update_window_cursor (w, on)
19188 struct window *w;
19189 int on;
19190 {
19191 /* Don't update cursor in windows whose frame is in the process
19192 of being deleted. */
19193 if (w->current_matrix)
19194 {
19195 BLOCK_INPUT;
19196 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19197 w->phys_cursor.x, w->phys_cursor.y);
19198 UNBLOCK_INPUT;
19199 }
19200 }
19201
19202
19203 /* Call update_window_cursor with parameter ON_P on all leaf windows
19204 in the window tree rooted at W. */
19205
19206 static void
19207 update_cursor_in_window_tree (w, on_p)
19208 struct window *w;
19209 int on_p;
19210 {
19211 while (w)
19212 {
19213 if (!NILP (w->hchild))
19214 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19215 else if (!NILP (w->vchild))
19216 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19217 else
19218 update_window_cursor (w, on_p);
19219
19220 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19221 }
19222 }
19223
19224
19225 /* EXPORT:
19226 Display the cursor on window W, or clear it, according to ON_P.
19227 Don't change the cursor's position. */
19228
19229 void
19230 x_update_cursor (f, on_p)
19231 struct frame *f;
19232 int on_p;
19233 {
19234 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19235 }
19236
19237
19238 /* EXPORT:
19239 Clear the cursor of window W to background color, and mark the
19240 cursor as not shown. This is used when the text where the cursor
19241 is is about to be rewritten. */
19242
19243 void
19244 x_clear_cursor (w)
19245 struct window *w;
19246 {
19247 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19248 update_window_cursor (w, 0);
19249 }
19250
19251
19252 /* EXPORT:
19253 Display the active region described by mouse_face_* according to DRAW. */
19254
19255 void
19256 show_mouse_face (dpyinfo, draw)
19257 Display_Info *dpyinfo;
19258 enum draw_glyphs_face draw;
19259 {
19260 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19261 struct frame *f = XFRAME (WINDOW_FRAME (w));
19262
19263 if (/* If window is in the process of being destroyed, don't bother
19264 to do anything. */
19265 w->current_matrix != NULL
19266 /* Don't update mouse highlight if hidden */
19267 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19268 /* Recognize when we are called to operate on rows that don't exist
19269 anymore. This can happen when a window is split. */
19270 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19271 {
19272 int phys_cursor_on_p = w->phys_cursor_on_p;
19273 struct glyph_row *row, *first, *last;
19274
19275 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19276 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19277
19278 for (row = first; row <= last && row->enabled_p; ++row)
19279 {
19280 int start_hpos, end_hpos, start_x;
19281
19282 /* For all but the first row, the highlight starts at column 0. */
19283 if (row == first)
19284 {
19285 start_hpos = dpyinfo->mouse_face_beg_col;
19286 start_x = dpyinfo->mouse_face_beg_x;
19287 }
19288 else
19289 {
19290 start_hpos = 0;
19291 start_x = 0;
19292 }
19293
19294 if (row == last)
19295 end_hpos = dpyinfo->mouse_face_end_col;
19296 else
19297 end_hpos = row->used[TEXT_AREA];
19298
19299 if (end_hpos > start_hpos)
19300 {
19301 draw_glyphs (w, start_x, row, TEXT_AREA,
19302 start_hpos, end_hpos,
19303 draw, 0);
19304
19305 row->mouse_face_p
19306 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19307 }
19308 }
19309
19310 /* When we've written over the cursor, arrange for it to
19311 be displayed again. */
19312 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19313 {
19314 BLOCK_INPUT;
19315 display_and_set_cursor (w, 1,
19316 w->phys_cursor.hpos, w->phys_cursor.vpos,
19317 w->phys_cursor.x, w->phys_cursor.y);
19318 UNBLOCK_INPUT;
19319 }
19320 }
19321
19322 /* Change the mouse cursor. */
19323 if (draw == DRAW_NORMAL_TEXT)
19324 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19325 else if (draw == DRAW_MOUSE_FACE)
19326 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19327 else
19328 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19329 }
19330
19331 /* EXPORT:
19332 Clear out the mouse-highlighted active region.
19333 Redraw it un-highlighted first. Value is non-zero if mouse
19334 face was actually drawn unhighlighted. */
19335
19336 int
19337 clear_mouse_face (dpyinfo)
19338 Display_Info *dpyinfo;
19339 {
19340 int cleared = 0;
19341
19342 if (!NILP (dpyinfo->mouse_face_window))
19343 {
19344 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19345 cleared = 1;
19346 }
19347
19348 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19349 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19350 dpyinfo->mouse_face_window = Qnil;
19351 dpyinfo->mouse_face_overlay = Qnil;
19352 return cleared;
19353 }
19354
19355
19356 /* EXPORT:
19357 Non-zero if physical cursor of window W is within mouse face. */
19358
19359 int
19360 cursor_in_mouse_face_p (w)
19361 struct window *w;
19362 {
19363 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19364 int in_mouse_face = 0;
19365
19366 if (WINDOWP (dpyinfo->mouse_face_window)
19367 && XWINDOW (dpyinfo->mouse_face_window) == w)
19368 {
19369 int hpos = w->phys_cursor.hpos;
19370 int vpos = w->phys_cursor.vpos;
19371
19372 if (vpos >= dpyinfo->mouse_face_beg_row
19373 && vpos <= dpyinfo->mouse_face_end_row
19374 && (vpos > dpyinfo->mouse_face_beg_row
19375 || hpos >= dpyinfo->mouse_face_beg_col)
19376 && (vpos < dpyinfo->mouse_face_end_row
19377 || hpos < dpyinfo->mouse_face_end_col
19378 || dpyinfo->mouse_face_past_end))
19379 in_mouse_face = 1;
19380 }
19381
19382 return in_mouse_face;
19383 }
19384
19385
19386
19387 \f
19388 /* Find the glyph matrix position of buffer position CHARPOS in window
19389 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19390 current glyphs must be up to date. If CHARPOS is above window
19391 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19392 of last line in W. In the row containing CHARPOS, stop before glyphs
19393 having STOP as object. */
19394
19395 #if 1 /* This is a version of fast_find_position that's more correct
19396 in the presence of hscrolling, for example. I didn't install
19397 it right away because the problem fixed is minor, it failed
19398 in 20.x as well, and I think it's too risky to install
19399 so near the release of 21.1. 2001-09-25 gerd. */
19400
19401 static int
19402 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19403 struct window *w;
19404 EMACS_INT charpos;
19405 int *hpos, *vpos, *x, *y;
19406 Lisp_Object stop;
19407 {
19408 struct glyph_row *row, *first;
19409 struct glyph *glyph, *end;
19410 int past_end = 0;
19411
19412 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19413 row = row_containing_pos (w, charpos, first, NULL, 0);
19414 if (row == NULL)
19415 {
19416 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19417 {
19418 *x = *y = *hpos = *vpos = 0;
19419 return 0;
19420 }
19421 else
19422 {
19423 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19424 past_end = 1;
19425 }
19426 }
19427
19428 *x = row->x;
19429 *y = row->y;
19430 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19431
19432 glyph = row->glyphs[TEXT_AREA];
19433 end = glyph + row->used[TEXT_AREA];
19434
19435 /* Skip over glyphs not having an object at the start of the row.
19436 These are special glyphs like truncation marks on terminal
19437 frames. */
19438 if (row->displays_text_p)
19439 while (glyph < end
19440 && INTEGERP (glyph->object)
19441 && !EQ (stop, glyph->object)
19442 && glyph->charpos < 0)
19443 {
19444 *x += glyph->pixel_width;
19445 ++glyph;
19446 }
19447
19448 while (glyph < end
19449 && !INTEGERP (glyph->object)
19450 && !EQ (stop, glyph->object)
19451 && (!BUFFERP (glyph->object)
19452 || glyph->charpos < charpos))
19453 {
19454 *x += glyph->pixel_width;
19455 ++glyph;
19456 }
19457
19458 *hpos = glyph - row->glyphs[TEXT_AREA];
19459 return past_end;
19460 }
19461
19462 #else /* not 1 */
19463
19464 static int
19465 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19466 struct window *w;
19467 EMACS_INT pos;
19468 int *hpos, *vpos, *x, *y;
19469 Lisp_Object stop;
19470 {
19471 int i;
19472 int lastcol;
19473 int maybe_next_line_p = 0;
19474 int line_start_position;
19475 int yb = window_text_bottom_y (w);
19476 struct glyph_row *row, *best_row;
19477 int row_vpos, best_row_vpos;
19478 int current_x;
19479
19480 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19481 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19482
19483 while (row->y < yb)
19484 {
19485 if (row->used[TEXT_AREA])
19486 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19487 else
19488 line_start_position = 0;
19489
19490 if (line_start_position > pos)
19491 break;
19492 /* If the position sought is the end of the buffer,
19493 don't include the blank lines at the bottom of the window. */
19494 else if (line_start_position == pos
19495 && pos == BUF_ZV (XBUFFER (w->buffer)))
19496 {
19497 maybe_next_line_p = 1;
19498 break;
19499 }
19500 else if (line_start_position > 0)
19501 {
19502 best_row = row;
19503 best_row_vpos = row_vpos;
19504 }
19505
19506 if (row->y + row->height >= yb)
19507 break;
19508
19509 ++row;
19510 ++row_vpos;
19511 }
19512
19513 /* Find the right column within BEST_ROW. */
19514 lastcol = 0;
19515 current_x = best_row->x;
19516 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19517 {
19518 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19519 int charpos = glyph->charpos;
19520
19521 if (BUFFERP (glyph->object))
19522 {
19523 if (charpos == pos)
19524 {
19525 *hpos = i;
19526 *vpos = best_row_vpos;
19527 *x = current_x;
19528 *y = best_row->y;
19529 return 1;
19530 }
19531 else if (charpos > pos)
19532 break;
19533 }
19534 else if (EQ (glyph->object, stop))
19535 break;
19536
19537 if (charpos > 0)
19538 lastcol = i;
19539 current_x += glyph->pixel_width;
19540 }
19541
19542 /* If we're looking for the end of the buffer,
19543 and we didn't find it in the line we scanned,
19544 use the start of the following line. */
19545 if (maybe_next_line_p)
19546 {
19547 ++best_row;
19548 ++best_row_vpos;
19549 lastcol = 0;
19550 current_x = best_row->x;
19551 }
19552
19553 *vpos = best_row_vpos;
19554 *hpos = lastcol + 1;
19555 *x = current_x;
19556 *y = best_row->y;
19557 return 0;
19558 }
19559
19560 #endif /* not 1 */
19561
19562
19563 /* Find the position of the glyph for position POS in OBJECT in
19564 window W's current matrix, and return in *X, *Y the pixel
19565 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19566
19567 RIGHT_P non-zero means return the position of the right edge of the
19568 glyph, RIGHT_P zero means return the left edge position.
19569
19570 If no glyph for POS exists in the matrix, return the position of
19571 the glyph with the next smaller position that is in the matrix, if
19572 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19573 exists in the matrix, return the position of the glyph with the
19574 next larger position in OBJECT.
19575
19576 Value is non-zero if a glyph was found. */
19577
19578 static int
19579 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19580 struct window *w;
19581 EMACS_INT pos;
19582 Lisp_Object object;
19583 int *hpos, *vpos, *x, *y;
19584 int right_p;
19585 {
19586 int yb = window_text_bottom_y (w);
19587 struct glyph_row *r;
19588 struct glyph *best_glyph = NULL;
19589 struct glyph_row *best_row = NULL;
19590 int best_x = 0;
19591
19592 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19593 r->enabled_p && r->y < yb;
19594 ++r)
19595 {
19596 struct glyph *g = r->glyphs[TEXT_AREA];
19597 struct glyph *e = g + r->used[TEXT_AREA];
19598 int gx;
19599
19600 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19601 if (EQ (g->object, object))
19602 {
19603 if (g->charpos == pos)
19604 {
19605 best_glyph = g;
19606 best_x = gx;
19607 best_row = r;
19608 goto found;
19609 }
19610 else if (best_glyph == NULL
19611 || ((abs (g->charpos - pos)
19612 < abs (best_glyph->charpos - pos))
19613 && (right_p
19614 ? g->charpos < pos
19615 : g->charpos > pos)))
19616 {
19617 best_glyph = g;
19618 best_x = gx;
19619 best_row = r;
19620 }
19621 }
19622 }
19623
19624 found:
19625
19626 if (best_glyph)
19627 {
19628 *x = best_x;
19629 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19630
19631 if (right_p)
19632 {
19633 *x += best_glyph->pixel_width;
19634 ++*hpos;
19635 }
19636
19637 *y = best_row->y;
19638 *vpos = best_row - w->current_matrix->rows;
19639 }
19640
19641 return best_glyph != NULL;
19642 }
19643
19644
19645 /* Take proper action when mouse has moved to the mode or header line
19646 or marginal area AREA of window W, x-position X and y-position Y.
19647 X is relative to the start of the text display area of W, so the
19648 width of bitmap areas and scroll bars must be subtracted to get a
19649 position relative to the start of the mode line. */
19650
19651 static void
19652 note_mode_line_or_margin_highlight (w, x, y, area)
19653 struct window *w;
19654 int x, y;
19655 enum window_part area;
19656 {
19657 struct frame *f = XFRAME (w->frame);
19658 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19659 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
19660 int charpos;
19661 Lisp_Object string, help, map, pos;
19662
19663 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
19664 string = mode_line_string (w, x, y, area, &charpos);
19665 else
19666 string = marginal_area_string (w, x, y, area, &charpos);
19667
19668 if (STRINGP (string))
19669 {
19670 pos = make_number (charpos);
19671
19672 /* If we're on a string with `help-echo' text property, arrange
19673 for the help to be displayed. This is done by setting the
19674 global variable help_echo_string to the help string. */
19675 help = Fget_text_property (pos, Qhelp_echo, string);
19676 if (!NILP (help))
19677 {
19678 help_echo_string = help;
19679 XSETWINDOW (help_echo_window, w);
19680 help_echo_object = string;
19681 help_echo_pos = charpos;
19682 }
19683
19684 /* Change the mouse pointer according to what is under X/Y. */
19685 map = Fget_text_property (pos, Qlocal_map, string);
19686 if (!KEYMAPP (map))
19687 map = Fget_text_property (pos, Qkeymap, string);
19688 if (KEYMAPP (map))
19689 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
19690 }
19691
19692 rif->define_frame_cursor (f, cursor);
19693 }
19694
19695
19696 /* EXPORT:
19697 Take proper action when the mouse has moved to position X, Y on
19698 frame F as regards highlighting characters that have mouse-face
19699 properties. Also de-highlighting chars where the mouse was before.
19700 X and Y can be negative or out of range. */
19701
19702 void
19703 note_mouse_highlight (f, x, y)
19704 struct frame *f;
19705 int x, y;
19706 {
19707 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19708 enum window_part part;
19709 Lisp_Object window;
19710 struct window *w;
19711 Cursor cursor = No_Cursor;
19712 struct buffer *b;
19713
19714 /* When a menu is active, don't highlight because this looks odd. */
19715 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
19716 if (popup_activated ())
19717 return;
19718 #endif
19719
19720 if (NILP (Vmouse_highlight)
19721 || !f->glyphs_initialized_p)
19722 return;
19723
19724 dpyinfo->mouse_face_mouse_x = x;
19725 dpyinfo->mouse_face_mouse_y = y;
19726 dpyinfo->mouse_face_mouse_frame = f;
19727
19728 if (dpyinfo->mouse_face_defer)
19729 return;
19730
19731 if (gc_in_progress)
19732 {
19733 dpyinfo->mouse_face_deferred_gc = 1;
19734 return;
19735 }
19736
19737 /* Which window is that in? */
19738 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
19739
19740 /* If we were displaying active text in another window, clear that. */
19741 if (! EQ (window, dpyinfo->mouse_face_window))
19742 clear_mouse_face (dpyinfo);
19743
19744 /* Not on a window -> return. */
19745 if (!WINDOWP (window))
19746 return;
19747
19748 /* Reset help_echo_string. It will get recomputed below. */
19749 /* ++KFS: X version didn't do this, but it looks harmless. */
19750 help_echo_string = Qnil;
19751
19752 /* Convert to window-relative pixel coordinates. */
19753 w = XWINDOW (window);
19754 frame_to_window_pixel_xy (w, &x, &y);
19755
19756 /* Handle tool-bar window differently since it doesn't display a
19757 buffer. */
19758 if (EQ (window, f->tool_bar_window))
19759 {
19760 note_tool_bar_highlight (f, x, y);
19761 return;
19762 }
19763
19764 /* Mouse is on the mode, header line or margin? */
19765 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
19766 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
19767 {
19768 note_mode_line_or_margin_highlight (w, x, y, part);
19769 return;
19770 }
19771
19772 if (part == ON_VERTICAL_BORDER)
19773 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
19774 else
19775 cursor = FRAME_X_OUTPUT (f)->text_cursor;
19776
19777 /* Are we in a window whose display is up to date?
19778 And verify the buffer's text has not changed. */
19779 b = XBUFFER (w->buffer);
19780 if (part == ON_TEXT
19781 && EQ (w->window_end_valid, w->buffer)
19782 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
19783 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
19784 {
19785 int hpos, vpos, pos, i, area;
19786 struct glyph *glyph;
19787 Lisp_Object object;
19788 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
19789 Lisp_Object *overlay_vec = NULL;
19790 int len, noverlays;
19791 struct buffer *obuf;
19792 int obegv, ozv, same_region;
19793
19794 /* Find the glyph under X/Y. */
19795 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area, 0);
19796
19797 /* Clear mouse face if X/Y not over text. */
19798 if (glyph == NULL
19799 || area != TEXT_AREA
19800 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
19801 {
19802 #if defined (HAVE_NTGUI)
19803 /* ++KFS: Why is this necessary on W32 ? */
19804 clear_mouse_face (dpyinfo);
19805 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
19806 #else
19807 if (clear_mouse_face (dpyinfo))
19808 cursor = No_Cursor;
19809 #endif
19810 goto set_cursor;
19811 }
19812
19813 pos = glyph->charpos;
19814 object = glyph->object;
19815 if (!STRINGP (object) && !BUFFERP (object))
19816 goto set_cursor;
19817
19818 /* If we get an out-of-range value, return now; avoid an error. */
19819 if (BUFFERP (object) && pos > BUF_Z (b))
19820 goto set_cursor;
19821
19822 /* Make the window's buffer temporarily current for
19823 overlays_at and compute_char_face. */
19824 obuf = current_buffer;
19825 current_buffer = b;
19826 obegv = BEGV;
19827 ozv = ZV;
19828 BEGV = BEG;
19829 ZV = Z;
19830
19831 /* Is this char mouse-active or does it have help-echo? */
19832 position = make_number (pos);
19833
19834 if (BUFFERP (object))
19835 {
19836 /* Put all the overlays we want in a vector in overlay_vec.
19837 Store the length in len. If there are more than 10, make
19838 enough space for all, and try again. */
19839 len = 10;
19840 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
19841 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
19842 if (noverlays > len)
19843 {
19844 len = noverlays;
19845 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
19846 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
19847 }
19848
19849 /* Sort overlays into increasing priority order. */
19850 noverlays = sort_overlays (overlay_vec, noverlays, w);
19851 }
19852 else
19853 noverlays = 0;
19854
19855 same_region = (EQ (window, dpyinfo->mouse_face_window)
19856 && vpos >= dpyinfo->mouse_face_beg_row
19857 && vpos <= dpyinfo->mouse_face_end_row
19858 && (vpos > dpyinfo->mouse_face_beg_row
19859 || hpos >= dpyinfo->mouse_face_beg_col)
19860 && (vpos < dpyinfo->mouse_face_end_row
19861 || hpos < dpyinfo->mouse_face_end_col
19862 || dpyinfo->mouse_face_past_end));
19863
19864 if (same_region)
19865 cursor = No_Cursor;
19866
19867 /* Check mouse-face highlighting. */
19868 if (! same_region
19869 /* If there exists an overlay with mouse-face overlapping
19870 the one we are currently highlighting, we have to
19871 check if we enter the overlapping overlay, and then
19872 highlight only that. */
19873 || (OVERLAYP (dpyinfo->mouse_face_overlay)
19874 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
19875 {
19876 /* Find the highest priority overlay that has a mouse-face
19877 property. */
19878 overlay = Qnil;
19879 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
19880 {
19881 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
19882 if (!NILP (mouse_face))
19883 overlay = overlay_vec[i];
19884 }
19885
19886 /* If we're actually highlighting the same overlay as
19887 before, there's no need to do that again. */
19888 if (!NILP (overlay)
19889 && EQ (overlay, dpyinfo->mouse_face_overlay))
19890 goto check_help_echo;
19891
19892 dpyinfo->mouse_face_overlay = overlay;
19893
19894 /* Clear the display of the old active region, if any. */
19895 if (clear_mouse_face (dpyinfo))
19896 cursor = No_Cursor;
19897
19898 /* If no overlay applies, get a text property. */
19899 if (NILP (overlay))
19900 mouse_face = Fget_text_property (position, Qmouse_face, object);
19901
19902 /* Handle the overlay case. */
19903 if (!NILP (overlay))
19904 {
19905 /* Find the range of text around this char that
19906 should be active. */
19907 Lisp_Object before, after;
19908 int ignore;
19909
19910 before = Foverlay_start (overlay);
19911 after = Foverlay_end (overlay);
19912 /* Record this as the current active region. */
19913 fast_find_position (w, XFASTINT (before),
19914 &dpyinfo->mouse_face_beg_col,
19915 &dpyinfo->mouse_face_beg_row,
19916 &dpyinfo->mouse_face_beg_x,
19917 &dpyinfo->mouse_face_beg_y, Qnil);
19918
19919 dpyinfo->mouse_face_past_end
19920 = !fast_find_position (w, XFASTINT (after),
19921 &dpyinfo->mouse_face_end_col,
19922 &dpyinfo->mouse_face_end_row,
19923 &dpyinfo->mouse_face_end_x,
19924 &dpyinfo->mouse_face_end_y, Qnil);
19925 dpyinfo->mouse_face_window = window;
19926
19927 dpyinfo->mouse_face_face_id
19928 = face_at_buffer_position (w, pos, 0, 0,
19929 &ignore, pos + 1,
19930 !dpyinfo->mouse_face_hidden);
19931
19932 /* Display it as active. */
19933 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19934 cursor = No_Cursor;
19935 }
19936 /* Handle the text property case. */
19937 else if (!NILP (mouse_face) && BUFFERP (object))
19938 {
19939 /* Find the range of text around this char that
19940 should be active. */
19941 Lisp_Object before, after, beginning, end;
19942 int ignore;
19943
19944 beginning = Fmarker_position (w->start);
19945 end = make_number (BUF_Z (XBUFFER (object))
19946 - XFASTINT (w->window_end_pos));
19947 before
19948 = Fprevious_single_property_change (make_number (pos + 1),
19949 Qmouse_face,
19950 object, beginning);
19951 after
19952 = Fnext_single_property_change (position, Qmouse_face,
19953 object, end);
19954
19955 /* Record this as the current active region. */
19956 fast_find_position (w, XFASTINT (before),
19957 &dpyinfo->mouse_face_beg_col,
19958 &dpyinfo->mouse_face_beg_row,
19959 &dpyinfo->mouse_face_beg_x,
19960 &dpyinfo->mouse_face_beg_y, Qnil);
19961 dpyinfo->mouse_face_past_end
19962 = !fast_find_position (w, XFASTINT (after),
19963 &dpyinfo->mouse_face_end_col,
19964 &dpyinfo->mouse_face_end_row,
19965 &dpyinfo->mouse_face_end_x,
19966 &dpyinfo->mouse_face_end_y, Qnil);
19967 dpyinfo->mouse_face_window = window;
19968
19969 if (BUFFERP (object))
19970 dpyinfo->mouse_face_face_id
19971 = face_at_buffer_position (w, pos, 0, 0,
19972 &ignore, pos + 1,
19973 !dpyinfo->mouse_face_hidden);
19974
19975 /* Display it as active. */
19976 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
19977 cursor = No_Cursor;
19978 }
19979 else if (!NILP (mouse_face) && STRINGP (object))
19980 {
19981 Lisp_Object b, e;
19982 int ignore;
19983
19984 b = Fprevious_single_property_change (make_number (pos + 1),
19985 Qmouse_face,
19986 object, Qnil);
19987 e = Fnext_single_property_change (position, Qmouse_face,
19988 object, Qnil);
19989 if (NILP (b))
19990 b = make_number (0);
19991 if (NILP (e))
19992 e = make_number (SCHARS (object) - 1);
19993 fast_find_string_pos (w, XINT (b), object,
19994 &dpyinfo->mouse_face_beg_col,
19995 &dpyinfo->mouse_face_beg_row,
19996 &dpyinfo->mouse_face_beg_x,
19997 &dpyinfo->mouse_face_beg_y, 0);
19998 fast_find_string_pos (w, XINT (e), object,
19999 &dpyinfo->mouse_face_end_col,
20000 &dpyinfo->mouse_face_end_row,
20001 &dpyinfo->mouse_face_end_x,
20002 &dpyinfo->mouse_face_end_y, 1);
20003 dpyinfo->mouse_face_past_end = 0;
20004 dpyinfo->mouse_face_window = window;
20005 dpyinfo->mouse_face_face_id
20006 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20007 glyph->face_id, 1);
20008 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20009 cursor = No_Cursor;
20010 }
20011 else if (STRINGP (object) && NILP (mouse_face))
20012 {
20013 /* A string which doesn't have mouse-face, but
20014 the text ``under'' it might have. */
20015 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20016 int start = MATRIX_ROW_START_CHARPOS (r);
20017
20018 pos = string_buffer_position (w, object, start);
20019 if (pos > 0)
20020 mouse_face = get_char_property_and_overlay (make_number (pos),
20021 Qmouse_face,
20022 w->buffer,
20023 &overlay);
20024 if (!NILP (mouse_face) && !NILP (overlay))
20025 {
20026 Lisp_Object before = Foverlay_start (overlay);
20027 Lisp_Object after = Foverlay_end (overlay);
20028 int ignore;
20029
20030 /* Note that we might not be able to find position
20031 BEFORE in the glyph matrix if the overlay is
20032 entirely covered by a `display' property. In
20033 this case, we overshoot. So let's stop in
20034 the glyph matrix before glyphs for OBJECT. */
20035 fast_find_position (w, XFASTINT (before),
20036 &dpyinfo->mouse_face_beg_col,
20037 &dpyinfo->mouse_face_beg_row,
20038 &dpyinfo->mouse_face_beg_x,
20039 &dpyinfo->mouse_face_beg_y,
20040 object);
20041
20042 dpyinfo->mouse_face_past_end
20043 = !fast_find_position (w, XFASTINT (after),
20044 &dpyinfo->mouse_face_end_col,
20045 &dpyinfo->mouse_face_end_row,
20046 &dpyinfo->mouse_face_end_x,
20047 &dpyinfo->mouse_face_end_y,
20048 Qnil);
20049 dpyinfo->mouse_face_window = window;
20050 dpyinfo->mouse_face_face_id
20051 = face_at_buffer_position (w, pos, 0, 0,
20052 &ignore, pos + 1,
20053 !dpyinfo->mouse_face_hidden);
20054
20055 /* Display it as active. */
20056 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20057 cursor = No_Cursor;
20058 }
20059 }
20060 }
20061
20062 check_help_echo:
20063
20064 /* Look for a `help-echo' property. */
20065 {
20066 Lisp_Object help, overlay;
20067
20068 /* Check overlays first. */
20069 help = overlay = Qnil;
20070 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20071 {
20072 overlay = overlay_vec[i];
20073 help = Foverlay_get (overlay, Qhelp_echo);
20074 }
20075
20076 if (!NILP (help))
20077 {
20078 help_echo_string = help;
20079 help_echo_window = window;
20080 help_echo_object = overlay;
20081 help_echo_pos = pos;
20082 }
20083 else
20084 {
20085 Lisp_Object object = glyph->object;
20086 int charpos = glyph->charpos;
20087
20088 /* Try text properties. */
20089 if (STRINGP (object)
20090 && charpos >= 0
20091 && charpos < SCHARS (object))
20092 {
20093 help = Fget_text_property (make_number (charpos),
20094 Qhelp_echo, object);
20095 if (NILP (help))
20096 {
20097 /* If the string itself doesn't specify a help-echo,
20098 see if the buffer text ``under'' it does. */
20099 struct glyph_row *r
20100 = MATRIX_ROW (w->current_matrix, vpos);
20101 int start = MATRIX_ROW_START_CHARPOS (r);
20102 int pos = string_buffer_position (w, object, start);
20103 if (pos > 0)
20104 {
20105 help = Fget_char_property (make_number (pos),
20106 Qhelp_echo, w->buffer);
20107 if (!NILP (help))
20108 {
20109 charpos = pos;
20110 object = w->buffer;
20111 }
20112 }
20113 }
20114 }
20115 else if (BUFFERP (object)
20116 && charpos >= BEGV
20117 && charpos < ZV)
20118 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20119 object);
20120
20121 if (!NILP (help))
20122 {
20123 help_echo_string = help;
20124 help_echo_window = window;
20125 help_echo_object = object;
20126 help_echo_pos = charpos;
20127 }
20128 }
20129 }
20130
20131 BEGV = obegv;
20132 ZV = ozv;
20133 current_buffer = obuf;
20134 }
20135
20136 set_cursor:
20137
20138 #ifndef HAVE_CARBON
20139 if (cursor != No_Cursor)
20140 #else
20141 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20142 #endif
20143 rif->define_frame_cursor (f, cursor);
20144 }
20145
20146
20147 /* EXPORT for RIF:
20148 Clear any mouse-face on window W. This function is part of the
20149 redisplay interface, and is called from try_window_id and similar
20150 functions to ensure the mouse-highlight is off. */
20151
20152 void
20153 x_clear_window_mouse_face (w)
20154 struct window *w;
20155 {
20156 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20157 Lisp_Object window;
20158
20159 BLOCK_INPUT;
20160 XSETWINDOW (window, w);
20161 if (EQ (window, dpyinfo->mouse_face_window))
20162 clear_mouse_face (dpyinfo);
20163 UNBLOCK_INPUT;
20164 }
20165
20166
20167 /* EXPORT:
20168 Just discard the mouse face information for frame F, if any.
20169 This is used when the size of F is changed. */
20170
20171 void
20172 cancel_mouse_face (f)
20173 struct frame *f;
20174 {
20175 Lisp_Object window;
20176 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20177
20178 window = dpyinfo->mouse_face_window;
20179 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20180 {
20181 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20182 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20183 dpyinfo->mouse_face_window = Qnil;
20184 }
20185 }
20186
20187
20188 #endif /* HAVE_WINDOW_SYSTEM */
20189
20190 \f
20191 /***********************************************************************
20192 Exposure Events
20193 ***********************************************************************/
20194
20195 #ifdef HAVE_WINDOW_SYSTEM
20196
20197 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20198 which intersects rectangle R. R is in window-relative coordinates. */
20199
20200 static void
20201 expose_area (w, row, r, area)
20202 struct window *w;
20203 struct glyph_row *row;
20204 XRectangle *r;
20205 enum glyph_row_area area;
20206 {
20207 struct glyph *first = row->glyphs[area];
20208 struct glyph *end = row->glyphs[area] + row->used[area];
20209 struct glyph *last;
20210 int first_x, start_x, x;
20211
20212 if (area == TEXT_AREA && row->fill_line_p)
20213 /* If row extends face to end of line write the whole line. */
20214 draw_glyphs (w, 0, row, area,
20215 0, row->used[area],
20216 DRAW_NORMAL_TEXT, 0);
20217 else
20218 {
20219 /* Set START_X to the window-relative start position for drawing glyphs of
20220 AREA. The first glyph of the text area can be partially visible.
20221 The first glyphs of other areas cannot. */
20222 start_x = window_box_left_offset (w, area);
20223 if (area == TEXT_AREA)
20224 start_x += row->x;
20225 x = start_x;
20226
20227 /* Find the first glyph that must be redrawn. */
20228 while (first < end
20229 && x + first->pixel_width < r->x)
20230 {
20231 x += first->pixel_width;
20232 ++first;
20233 }
20234
20235 /* Find the last one. */
20236 last = first;
20237 first_x = x;
20238 while (last < end
20239 && x < r->x + r->width)
20240 {
20241 x += last->pixel_width;
20242 ++last;
20243 }
20244
20245 /* Repaint. */
20246 if (last > first)
20247 draw_glyphs (w, first_x - start_x, row, area,
20248 first - row->glyphs[area], last - row->glyphs[area],
20249 DRAW_NORMAL_TEXT, 0);
20250 }
20251 }
20252
20253
20254 /* Redraw the parts of the glyph row ROW on window W intersecting
20255 rectangle R. R is in window-relative coordinates. Value is
20256 non-zero if mouse-face was overwritten. */
20257
20258 static int
20259 expose_line (w, row, r)
20260 struct window *w;
20261 struct glyph_row *row;
20262 XRectangle *r;
20263 {
20264 xassert (row->enabled_p);
20265
20266 if (row->mode_line_p || w->pseudo_window_p)
20267 draw_glyphs (w, 0, row, TEXT_AREA,
20268 0, row->used[TEXT_AREA],
20269 DRAW_NORMAL_TEXT, 0);
20270 else
20271 {
20272 if (row->used[LEFT_MARGIN_AREA])
20273 expose_area (w, row, r, LEFT_MARGIN_AREA);
20274 if (row->used[TEXT_AREA])
20275 expose_area (w, row, r, TEXT_AREA);
20276 if (row->used[RIGHT_MARGIN_AREA])
20277 expose_area (w, row, r, RIGHT_MARGIN_AREA);
20278 draw_row_fringe_bitmaps (w, row);
20279 }
20280
20281 return row->mouse_face_p;
20282 }
20283
20284
20285 /* Redraw those parts of glyphs rows during expose event handling that
20286 overlap other rows. Redrawing of an exposed line writes over parts
20287 of lines overlapping that exposed line; this function fixes that.
20288
20289 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20290 row in W's current matrix that is exposed and overlaps other rows.
20291 LAST_OVERLAPPING_ROW is the last such row. */
20292
20293 static void
20294 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20295 struct window *w;
20296 struct glyph_row *first_overlapping_row;
20297 struct glyph_row *last_overlapping_row;
20298 {
20299 struct glyph_row *row;
20300
20301 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20302 if (row->overlapping_p)
20303 {
20304 xassert (row->enabled_p && !row->mode_line_p);
20305
20306 if (row->used[LEFT_MARGIN_AREA])
20307 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20308
20309 if (row->used[TEXT_AREA])
20310 x_fix_overlapping_area (w, row, TEXT_AREA);
20311
20312 if (row->used[RIGHT_MARGIN_AREA])
20313 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20314 }
20315 }
20316
20317
20318 /* Return non-zero if W's cursor intersects rectangle R. */
20319
20320 static int
20321 phys_cursor_in_rect_p (w, r)
20322 struct window *w;
20323 XRectangle *r;
20324 {
20325 XRectangle cr, result;
20326 struct glyph *cursor_glyph;
20327
20328 cursor_glyph = get_phys_cursor_glyph (w);
20329 if (cursor_glyph)
20330 {
20331 /* r is relative to W's box, but w->phys_cursor.x is relative
20332 to left edge of W's TEXT area. Adjust it. */
20333 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
20334 cr.y = w->phys_cursor.y;
20335 cr.width = cursor_glyph->pixel_width;
20336 cr.height = w->phys_cursor_height;
20337 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20338 I assume the effect is the same -- and this is portable. */
20339 return x_intersect_rectangles (&cr, r, &result);
20340 }
20341 else
20342 return 0;
20343 }
20344
20345
20346 /* EXPORT:
20347 Draw a vertical window border to the right of window W if W doesn't
20348 have vertical scroll bars. */
20349
20350 void
20351 x_draw_vertical_border (w)
20352 struct window *w;
20353 {
20354 /* We could do better, if we knew what type of scroll-bar the adjacent
20355 windows (on either side) have... But we don't :-(
20356 However, I think this works ok. ++KFS 2003-04-25 */
20357
20358 /* Redraw borders between horizontally adjacent windows. Don't
20359 do it for frames with vertical scroll bars because either the
20360 right scroll bar of a window, or the left scroll bar of its
20361 neighbor will suffice as a border. */
20362 if (!WINDOW_RIGHTMOST_P (w)
20363 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
20364 {
20365 int x0, x1, y0, y1;
20366
20367 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20368 y1 -= 1;
20369
20370 rif->draw_vertical_window_border (w, x1, y0, y1);
20371 }
20372 else if (!WINDOW_LEFTMOST_P (w)
20373 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
20374 {
20375 int x0, x1, y0, y1;
20376
20377 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20378 y1 -= 1;
20379
20380 rif->draw_vertical_window_border (w, x0, y0, y1);
20381 }
20382 }
20383
20384
20385 /* Redraw the part of window W intersection rectangle FR. Pixel
20386 coordinates in FR are frame-relative. Call this function with
20387 input blocked. Value is non-zero if the exposure overwrites
20388 mouse-face. */
20389
20390 static int
20391 expose_window (w, fr)
20392 struct window *w;
20393 XRectangle *fr;
20394 {
20395 struct frame *f = XFRAME (w->frame);
20396 XRectangle wr, r;
20397 int mouse_face_overwritten_p = 0;
20398
20399 /* If window is not yet fully initialized, do nothing. This can
20400 happen when toolkit scroll bars are used and a window is split.
20401 Reconfiguring the scroll bar will generate an expose for a newly
20402 created window. */
20403 if (w->current_matrix == NULL)
20404 return 0;
20405
20406 /* When we're currently updating the window, display and current
20407 matrix usually don't agree. Arrange for a thorough display
20408 later. */
20409 if (w == updated_window)
20410 {
20411 SET_FRAME_GARBAGED (f);
20412 return 0;
20413 }
20414
20415 /* Frame-relative pixel rectangle of W. */
20416 wr.x = WINDOW_LEFT_EDGE_X (w);
20417 wr.y = WINDOW_TOP_EDGE_Y (w);
20418 wr.width = WINDOW_TOTAL_WIDTH (w);
20419 wr.height = WINDOW_TOTAL_HEIGHT (w);
20420
20421 if (x_intersect_rectangles (fr, &wr, &r))
20422 {
20423 int yb = window_text_bottom_y (w);
20424 struct glyph_row *row;
20425 int cursor_cleared_p;
20426 struct glyph_row *first_overlapping_row, *last_overlapping_row;
20427
20428 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
20429 r.x, r.y, r.width, r.height));
20430
20431 /* Convert to window coordinates. */
20432 r.x -= WINDOW_LEFT_EDGE_X (w);
20433 r.y -= WINDOW_TOP_EDGE_Y (w);
20434
20435 /* Turn off the cursor. */
20436 if (!w->pseudo_window_p
20437 && phys_cursor_in_rect_p (w, &r))
20438 {
20439 x_clear_cursor (w);
20440 cursor_cleared_p = 1;
20441 }
20442 else
20443 cursor_cleared_p = 0;
20444
20445 /* Update lines intersecting rectangle R. */
20446 first_overlapping_row = last_overlapping_row = NULL;
20447 for (row = w->current_matrix->rows;
20448 row->enabled_p;
20449 ++row)
20450 {
20451 int y0 = row->y;
20452 int y1 = MATRIX_ROW_BOTTOM_Y (row);
20453
20454 if ((y0 >= r.y && y0 < r.y + r.height)
20455 || (y1 > r.y && y1 < r.y + r.height)
20456 || (r.y >= y0 && r.y < y1)
20457 || (r.y + r.height > y0 && r.y + r.height < y1))
20458 {
20459 if (row->overlapping_p)
20460 {
20461 if (first_overlapping_row == NULL)
20462 first_overlapping_row = row;
20463 last_overlapping_row = row;
20464 }
20465
20466 if (expose_line (w, row, &r))
20467 mouse_face_overwritten_p = 1;
20468 }
20469
20470 if (y1 >= yb)
20471 break;
20472 }
20473
20474 /* Display the mode line if there is one. */
20475 if (WINDOW_WANTS_MODELINE_P (w)
20476 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
20477 row->enabled_p)
20478 && row->y < r.y + r.height)
20479 {
20480 if (expose_line (w, row, &r))
20481 mouse_face_overwritten_p = 1;
20482 }
20483
20484 if (!w->pseudo_window_p)
20485 {
20486 /* Fix the display of overlapping rows. */
20487 if (first_overlapping_row)
20488 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
20489
20490 /* Draw border between windows. */
20491 x_draw_vertical_border (w);
20492
20493 /* Turn the cursor on again. */
20494 if (cursor_cleared_p)
20495 update_window_cursor (w, 1);
20496 }
20497 }
20498
20499 #ifdef HAVE_CARBON
20500 /* Display scroll bar for this window. */
20501 if (!NILP (w->vertical_scroll_bar))
20502 {
20503 /* ++KFS:
20504 If this doesn't work here (maybe some header files are missing),
20505 make a function in macterm.c and call it to do the job! */
20506 ControlHandle ch
20507 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
20508
20509 Draw1Control (ch);
20510 }
20511 #endif
20512
20513 return mouse_face_overwritten_p;
20514 }
20515
20516
20517
20518 /* Redraw (parts) of all windows in the window tree rooted at W that
20519 intersect R. R contains frame pixel coordinates. Value is
20520 non-zero if the exposure overwrites mouse-face. */
20521
20522 static int
20523 expose_window_tree (w, r)
20524 struct window *w;
20525 XRectangle *r;
20526 {
20527 struct frame *f = XFRAME (w->frame);
20528 int mouse_face_overwritten_p = 0;
20529
20530 while (w && !FRAME_GARBAGED_P (f))
20531 {
20532 if (!NILP (w->hchild))
20533 mouse_face_overwritten_p
20534 |= expose_window_tree (XWINDOW (w->hchild), r);
20535 else if (!NILP (w->vchild))
20536 mouse_face_overwritten_p
20537 |= expose_window_tree (XWINDOW (w->vchild), r);
20538 else
20539 mouse_face_overwritten_p |= expose_window (w, r);
20540
20541 w = NILP (w->next) ? NULL : XWINDOW (w->next);
20542 }
20543
20544 return mouse_face_overwritten_p;
20545 }
20546
20547
20548 /* EXPORT:
20549 Redisplay an exposed area of frame F. X and Y are the upper-left
20550 corner of the exposed rectangle. W and H are width and height of
20551 the exposed area. All are pixel values. W or H zero means redraw
20552 the entire frame. */
20553
20554 void
20555 expose_frame (f, x, y, w, h)
20556 struct frame *f;
20557 int x, y, w, h;
20558 {
20559 XRectangle r;
20560 int mouse_face_overwritten_p = 0;
20561
20562 TRACE ((stderr, "expose_frame "));
20563
20564 /* No need to redraw if frame will be redrawn soon. */
20565 if (FRAME_GARBAGED_P (f))
20566 {
20567 TRACE ((stderr, " garbaged\n"));
20568 return;
20569 }
20570
20571 #ifdef HAVE_CARBON
20572 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
20573 or deactivated here, for unknown reasons, activated scroll bars
20574 are shown in deactivated frames in some instances. */
20575 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
20576 activate_scroll_bars (f);
20577 else
20578 deactivate_scroll_bars (f);
20579 #endif
20580
20581 /* If basic faces haven't been realized yet, there is no point in
20582 trying to redraw anything. This can happen when we get an expose
20583 event while Emacs is starting, e.g. by moving another window. */
20584 if (FRAME_FACE_CACHE (f) == NULL
20585 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
20586 {
20587 TRACE ((stderr, " no faces\n"));
20588 return;
20589 }
20590
20591 if (w == 0 || h == 0)
20592 {
20593 r.x = r.y = 0;
20594 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
20595 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
20596 }
20597 else
20598 {
20599 r.x = x;
20600 r.y = y;
20601 r.width = w;
20602 r.height = h;
20603 }
20604
20605 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
20606 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
20607
20608 if (WINDOWP (f->tool_bar_window))
20609 mouse_face_overwritten_p
20610 |= expose_window (XWINDOW (f->tool_bar_window), &r);
20611
20612 #ifdef HAVE_X_WINDOWS
20613 #ifndef MSDOS
20614 #ifndef USE_X_TOOLKIT
20615 if (WINDOWP (f->menu_bar_window))
20616 mouse_face_overwritten_p
20617 |= expose_window (XWINDOW (f->menu_bar_window), &r);
20618 #endif /* not USE_X_TOOLKIT */
20619 #endif
20620 #endif
20621
20622 /* Some window managers support a focus-follows-mouse style with
20623 delayed raising of frames. Imagine a partially obscured frame,
20624 and moving the mouse into partially obscured mouse-face on that
20625 frame. The visible part of the mouse-face will be highlighted,
20626 then the WM raises the obscured frame. With at least one WM, KDE
20627 2.1, Emacs is not getting any event for the raising of the frame
20628 (even tried with SubstructureRedirectMask), only Expose events.
20629 These expose events will draw text normally, i.e. not
20630 highlighted. Which means we must redo the highlight here.
20631 Subsume it under ``we love X''. --gerd 2001-08-15 */
20632 /* Included in Windows version because Windows most likely does not
20633 do the right thing if any third party tool offers
20634 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
20635 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
20636 {
20637 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20638 if (f == dpyinfo->mouse_face_mouse_frame)
20639 {
20640 int x = dpyinfo->mouse_face_mouse_x;
20641 int y = dpyinfo->mouse_face_mouse_y;
20642 clear_mouse_face (dpyinfo);
20643 note_mouse_highlight (f, x, y);
20644 }
20645 }
20646 }
20647
20648
20649 /* EXPORT:
20650 Determine the intersection of two rectangles R1 and R2. Return
20651 the intersection in *RESULT. Value is non-zero if RESULT is not
20652 empty. */
20653
20654 int
20655 x_intersect_rectangles (r1, r2, result)
20656 XRectangle *r1, *r2, *result;
20657 {
20658 XRectangle *left, *right;
20659 XRectangle *upper, *lower;
20660 int intersection_p = 0;
20661
20662 /* Rearrange so that R1 is the left-most rectangle. */
20663 if (r1->x < r2->x)
20664 left = r1, right = r2;
20665 else
20666 left = r2, right = r1;
20667
20668 /* X0 of the intersection is right.x0, if this is inside R1,
20669 otherwise there is no intersection. */
20670 if (right->x <= left->x + left->width)
20671 {
20672 result->x = right->x;
20673
20674 /* The right end of the intersection is the minimum of the
20675 the right ends of left and right. */
20676 result->width = (min (left->x + left->width, right->x + right->width)
20677 - result->x);
20678
20679 /* Same game for Y. */
20680 if (r1->y < r2->y)
20681 upper = r1, lower = r2;
20682 else
20683 upper = r2, lower = r1;
20684
20685 /* The upper end of the intersection is lower.y0, if this is inside
20686 of upper. Otherwise, there is no intersection. */
20687 if (lower->y <= upper->y + upper->height)
20688 {
20689 result->y = lower->y;
20690
20691 /* The lower end of the intersection is the minimum of the lower
20692 ends of upper and lower. */
20693 result->height = (min (lower->y + lower->height,
20694 upper->y + upper->height)
20695 - result->y);
20696 intersection_p = 1;
20697 }
20698 }
20699
20700 return intersection_p;
20701 }
20702
20703 #endif /* HAVE_WINDOW_SYSTEM */
20704
20705 \f
20706 /***********************************************************************
20707 Initialization
20708 ***********************************************************************/
20709
20710 void
20711 syms_of_xdisp ()
20712 {
20713 Vwith_echo_area_save_vector = Qnil;
20714 staticpro (&Vwith_echo_area_save_vector);
20715
20716 Vmessage_stack = Qnil;
20717 staticpro (&Vmessage_stack);
20718
20719 Qinhibit_redisplay = intern ("inhibit-redisplay");
20720 staticpro (&Qinhibit_redisplay);
20721
20722 message_dolog_marker1 = Fmake_marker ();
20723 staticpro (&message_dolog_marker1);
20724 message_dolog_marker2 = Fmake_marker ();
20725 staticpro (&message_dolog_marker2);
20726 message_dolog_marker3 = Fmake_marker ();
20727 staticpro (&message_dolog_marker3);
20728
20729 #if GLYPH_DEBUG
20730 defsubr (&Sdump_frame_glyph_matrix);
20731 defsubr (&Sdump_glyph_matrix);
20732 defsubr (&Sdump_glyph_row);
20733 defsubr (&Sdump_tool_bar_row);
20734 defsubr (&Strace_redisplay);
20735 defsubr (&Strace_to_stderr);
20736 #endif
20737 #ifdef HAVE_WINDOW_SYSTEM
20738 defsubr (&Stool_bar_lines_needed);
20739 #endif
20740 defsubr (&Sformat_mode_line);
20741
20742 staticpro (&Qmenu_bar_update_hook);
20743 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
20744
20745 staticpro (&Qoverriding_terminal_local_map);
20746 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
20747
20748 staticpro (&Qoverriding_local_map);
20749 Qoverriding_local_map = intern ("overriding-local-map");
20750
20751 staticpro (&Qwindow_scroll_functions);
20752 Qwindow_scroll_functions = intern ("window-scroll-functions");
20753
20754 staticpro (&Qredisplay_end_trigger_functions);
20755 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
20756
20757 staticpro (&Qinhibit_point_motion_hooks);
20758 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
20759
20760 QCdata = intern (":data");
20761 staticpro (&QCdata);
20762 Qdisplay = intern ("display");
20763 staticpro (&Qdisplay);
20764 Qspace_width = intern ("space-width");
20765 staticpro (&Qspace_width);
20766 Qraise = intern ("raise");
20767 staticpro (&Qraise);
20768 Qspace = intern ("space");
20769 staticpro (&Qspace);
20770 Qmargin = intern ("margin");
20771 staticpro (&Qmargin);
20772 Qleft_margin = intern ("left-margin");
20773 staticpro (&Qleft_margin);
20774 Qright_margin = intern ("right-margin");
20775 staticpro (&Qright_margin);
20776 Qalign_to = intern ("align-to");
20777 staticpro (&Qalign_to);
20778 QCalign_to = intern (":align-to");
20779 staticpro (&QCalign_to);
20780 Qrelative_width = intern ("relative-width");
20781 staticpro (&Qrelative_width);
20782 QCrelative_width = intern (":relative-width");
20783 staticpro (&QCrelative_width);
20784 QCrelative_height = intern (":relative-height");
20785 staticpro (&QCrelative_height);
20786 QCeval = intern (":eval");
20787 staticpro (&QCeval);
20788 QCpropertize = intern (":propertize");
20789 staticpro (&QCpropertize);
20790 QCfile = intern (":file");
20791 staticpro (&QCfile);
20792 Qfontified = intern ("fontified");
20793 staticpro (&Qfontified);
20794 Qfontification_functions = intern ("fontification-functions");
20795 staticpro (&Qfontification_functions);
20796 Qtrailing_whitespace = intern ("trailing-whitespace");
20797 staticpro (&Qtrailing_whitespace);
20798 Qimage = intern ("image");
20799 staticpro (&Qimage);
20800 Qmessage_truncate_lines = intern ("message-truncate-lines");
20801 staticpro (&Qmessage_truncate_lines);
20802 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
20803 staticpro (&Qcursor_in_non_selected_windows);
20804 Qgrow_only = intern ("grow-only");
20805 staticpro (&Qgrow_only);
20806 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
20807 staticpro (&Qinhibit_menubar_update);
20808 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
20809 staticpro (&Qinhibit_eval_during_redisplay);
20810 Qposition = intern ("position");
20811 staticpro (&Qposition);
20812 Qbuffer_position = intern ("buffer-position");
20813 staticpro (&Qbuffer_position);
20814 Qobject = intern ("object");
20815 staticpro (&Qobject);
20816 Qbar = intern ("bar");
20817 staticpro (&Qbar);
20818 Qhbar = intern ("hbar");
20819 staticpro (&Qhbar);
20820 Qbox = intern ("box");
20821 staticpro (&Qbox);
20822 Qhollow = intern ("hollow");
20823 staticpro (&Qhollow);
20824 Qrisky_local_variable = intern ("risky-local-variable");
20825 staticpro (&Qrisky_local_variable);
20826 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
20827 staticpro (&Qinhibit_free_realized_faces);
20828
20829 list_of_error = Fcons (intern ("error"), Qnil);
20830 staticpro (&list_of_error);
20831
20832 last_arrow_position = Qnil;
20833 last_arrow_string = Qnil;
20834 staticpro (&last_arrow_position);
20835 staticpro (&last_arrow_string);
20836
20837 echo_buffer[0] = echo_buffer[1] = Qnil;
20838 staticpro (&echo_buffer[0]);
20839 staticpro (&echo_buffer[1]);
20840
20841 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
20842 staticpro (&echo_area_buffer[0]);
20843 staticpro (&echo_area_buffer[1]);
20844
20845 Vmessages_buffer_name = build_string ("*Messages*");
20846 staticpro (&Vmessages_buffer_name);
20847
20848 mode_line_proptrans_alist = Qnil;
20849 staticpro (&mode_line_proptrans_alist);
20850
20851 mode_line_string_list = Qnil;
20852 staticpro (&mode_line_string_list);
20853
20854 help_echo_string = Qnil;
20855 staticpro (&help_echo_string);
20856 help_echo_object = Qnil;
20857 staticpro (&help_echo_object);
20858 help_echo_window = Qnil;
20859 staticpro (&help_echo_window);
20860 previous_help_echo_string = Qnil;
20861 staticpro (&previous_help_echo_string);
20862 help_echo_pos = -1;
20863
20864 #ifdef HAVE_WINDOW_SYSTEM
20865 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
20866 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
20867 For example, if a block cursor is over a tab, it will be drawn as
20868 wide as that tab on the display. */);
20869 x_stretch_cursor_p = 0;
20870 #endif
20871
20872 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
20873 doc: /* Non-nil means highlight trailing whitespace.
20874 The face used for trailing whitespace is `trailing-whitespace'. */);
20875 Vshow_trailing_whitespace = Qnil;
20876
20877 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
20878 doc: /* Non-nil means don't actually do any redisplay.
20879 This is used for internal purposes. */);
20880 Vinhibit_redisplay = Qnil;
20881
20882 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
20883 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
20884 Vglobal_mode_string = Qnil;
20885
20886 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
20887 doc: /* Marker for where to display an arrow on top of the buffer text.
20888 This must be the beginning of a line in order to work.
20889 See also `overlay-arrow-string'. */);
20890 Voverlay_arrow_position = Qnil;
20891
20892 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
20893 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
20894 Voverlay_arrow_string = Qnil;
20895
20896 DEFVAR_INT ("scroll-step", &scroll_step,
20897 doc: /* *The number of lines to try scrolling a window by when point moves out.
20898 If that fails to bring point back on frame, point is centered instead.
20899 If this is zero, point is always centered after it moves off frame.
20900 If you want scrolling to always be a line at a time, you should set
20901 `scroll-conservatively' to a large value rather than set this to 1. */);
20902
20903 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
20904 doc: /* *Scroll up to this many lines, to bring point back on screen.
20905 A value of zero means to scroll the text to center point vertically
20906 in the window. */);
20907 scroll_conservatively = 0;
20908
20909 DEFVAR_INT ("scroll-margin", &scroll_margin,
20910 doc: /* *Number of lines of margin at the top and bottom of a window.
20911 Recenter the window whenever point gets within this many lines
20912 of the top or bottom of the window. */);
20913 scroll_margin = 0;
20914
20915 #if GLYPH_DEBUG
20916 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
20917 #endif
20918
20919 DEFVAR_BOOL ("truncate-partial-width-windows",
20920 &truncate_partial_width_windows,
20921 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
20922 truncate_partial_width_windows = 1;
20923
20924 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
20925 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
20926 Any other value means to use the appropriate face, `mode-line',
20927 `header-line', or `menu' respectively. */);
20928 mode_line_inverse_video = 1;
20929
20930 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
20931 doc: /* *Maximum buffer size for which line number should be displayed.
20932 If the buffer is bigger than this, the line number does not appear
20933 in the mode line. A value of nil means no limit. */);
20934 Vline_number_display_limit = Qnil;
20935
20936 DEFVAR_INT ("line-number-display-limit-width",
20937 &line_number_display_limit_width,
20938 doc: /* *Maximum line width (in characters) for line number display.
20939 If the average length of the lines near point is bigger than this, then the
20940 line number may be omitted from the mode line. */);
20941 line_number_display_limit_width = 200;
20942
20943 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
20944 doc: /* *Non-nil means highlight region even in nonselected windows. */);
20945 highlight_nonselected_windows = 0;
20946
20947 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
20948 doc: /* Non-nil if more than one frame is visible on this display.
20949 Minibuffer-only frames don't count, but iconified frames do.
20950 This variable is not guaranteed to be accurate except while processing
20951 `frame-title-format' and `icon-title-format'. */);
20952
20953 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
20954 doc: /* Template for displaying the title bar of visible frames.
20955 \(Assuming the window manager supports this feature.)
20956 This variable has the same structure as `mode-line-format' (which see),
20957 and is used only on frames for which no explicit name has been set
20958 \(see `modify-frame-parameters'). */);
20959 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
20960 doc: /* Template for displaying the title bar of an iconified frame.
20961 \(Assuming the window manager supports this feature.)
20962 This variable has the same structure as `mode-line-format' (which see),
20963 and is used only on frames for which no explicit name has been set
20964 \(see `modify-frame-parameters'). */);
20965 Vicon_title_format
20966 = Vframe_title_format
20967 = Fcons (intern ("multiple-frames"),
20968 Fcons (build_string ("%b"),
20969 Fcons (Fcons (empty_string,
20970 Fcons (intern ("invocation-name"),
20971 Fcons (build_string ("@"),
20972 Fcons (intern ("system-name"),
20973 Qnil)))),
20974 Qnil)));
20975
20976 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
20977 doc: /* Maximum number of lines to keep in the message log buffer.
20978 If nil, disable message logging. If t, log messages but don't truncate
20979 the buffer when it becomes large. */);
20980 Vmessage_log_max = make_number (50);
20981
20982 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
20983 doc: /* Functions called before redisplay, if window sizes have changed.
20984 The value should be a list of functions that take one argument.
20985 Just before redisplay, for each frame, if any of its windows have changed
20986 size since the last redisplay, or have been split or deleted,
20987 all the functions in the list are called, with the frame as argument. */);
20988 Vwindow_size_change_functions = Qnil;
20989
20990 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
20991 doc: /* List of Functions to call before redisplaying a window with scrolling.
20992 Each function is called with two arguments, the window
20993 and its new display-start position. Note that the value of `window-end'
20994 is not valid when these functions are called. */);
20995 Vwindow_scroll_functions = Qnil;
20996
20997 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
20998 doc: /* *Non-nil means autoselect window with mouse pointer. */);
20999 mouse_autoselect_window = 0;
21000
21001 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21002 doc: /* *Non-nil means automatically resize tool-bars.
21003 This increases a tool-bar's height if not all tool-bar items are visible.
21004 It decreases a tool-bar's height when it would display blank lines
21005 otherwise. */);
21006 auto_resize_tool_bars_p = 1;
21007
21008 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21009 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21010 auto_raise_tool_bar_buttons_p = 1;
21011
21012 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21013 doc: /* *Margin around tool-bar buttons in pixels.
21014 If an integer, use that for both horizontal and vertical margins.
21015 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21016 HORZ specifying the horizontal margin, and VERT specifying the
21017 vertical margin. */);
21018 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21019
21020 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21021 doc: /* *Relief thickness of tool-bar buttons. */);
21022 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21023
21024 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21025 doc: /* List of functions to call to fontify regions of text.
21026 Each function is called with one argument POS. Functions must
21027 fontify a region starting at POS in the current buffer, and give
21028 fontified regions the property `fontified'. */);
21029 Vfontification_functions = Qnil;
21030 Fmake_variable_buffer_local (Qfontification_functions);
21031
21032 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21033 &unibyte_display_via_language_environment,
21034 doc: /* *Non-nil means display unibyte text according to language environment.
21035 Specifically this means that unibyte non-ASCII characters
21036 are displayed by converting them to the equivalent multibyte characters
21037 according to the current language environment. As a result, they are
21038 displayed according to the current fontset. */);
21039 unibyte_display_via_language_environment = 0;
21040
21041 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21042 doc: /* *Maximum height for resizing mini-windows.
21043 If a float, it specifies a fraction of the mini-window frame's height.
21044 If an integer, it specifies a number of lines. */);
21045 Vmax_mini_window_height = make_float (0.25);
21046
21047 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21048 doc: /* *How to resize mini-windows.
21049 A value of nil means don't automatically resize mini-windows.
21050 A value of t means resize them to fit the text displayed in them.
21051 A value of `grow-only', the default, means let mini-windows grow
21052 only, until their display becomes empty, at which point the windows
21053 go back to their normal size. */);
21054 Vresize_mini_windows = Qgrow_only;
21055
21056 DEFVAR_LISP ("cursor-in-non-selected-windows",
21057 &Vcursor_in_non_selected_windows,
21058 doc: /* *Cursor type to display in non-selected windows.
21059 t means to use hollow box cursor. See `cursor-type' for other values. */);
21060 Vcursor_in_non_selected_windows = Qt;
21061
21062 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21063 doc: /* Alist specifying how to blink the cursor off.
21064 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21065 `cursor-type' frame-parameter or variable equals ON-STATE,
21066 comparing using `equal', Emacs uses OFF-STATE to specify
21067 how to blink it off. */);
21068 Vblink_cursor_alist = Qnil;
21069
21070 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21071 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21072 automatic_hscrolling_p = 1;
21073
21074 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21075 doc: /* *How many columns away from the window edge point is allowed to get
21076 before automatic hscrolling will horizontally scroll the window. */);
21077 hscroll_margin = 5;
21078
21079 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21080 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21081 When point is less than `automatic-hscroll-margin' columns from the window
21082 edge, automatic hscrolling will scroll the window by the amount of columns
21083 determined by this variable. If its value is a positive integer, scroll that
21084 many columns. If it's a positive floating-point number, it specifies the
21085 fraction of the window's width to scroll. If it's nil or zero, point will be
21086 centered horizontally after the scroll. Any other value, including negative
21087 numbers, are treated as if the value were zero.
21088
21089 Automatic hscrolling always moves point outside the scroll margin, so if
21090 point was more than scroll step columns inside the margin, the window will
21091 scroll more than the value given by the scroll step.
21092
21093 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21094 and `scroll-right' overrides this variable's effect. */);
21095 Vhscroll_step = make_number (0);
21096
21097 DEFVAR_LISP ("image-types", &Vimage_types,
21098 doc: /* List of supported image types.
21099 Each element of the list is a symbol for a supported image type. */);
21100 Vimage_types = Qnil;
21101
21102 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21103 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21104 Bind this around calls to `message' to let it take effect. */);
21105 message_truncate_lines = 0;
21106
21107 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21108 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21109 Can be used to update submenus whose contents should vary. */);
21110 Vmenu_bar_update_hook = Qnil;
21111
21112 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21113 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21114 inhibit_menubar_update = 0;
21115
21116 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21117 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21118 inhibit_eval_during_redisplay = 0;
21119
21120 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21121 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21122 inhibit_free_realized_faces = 0;
21123
21124 #if GLYPH_DEBUG
21125 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21126 doc: /* Inhibit try_window_id display optimization. */);
21127 inhibit_try_window_id = 0;
21128
21129 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21130 doc: /* Inhibit try_window_reusing display optimization. */);
21131 inhibit_try_window_reusing = 0;
21132
21133 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21134 doc: /* Inhibit try_cursor_movement display optimization. */);
21135 inhibit_try_cursor_movement = 0;
21136 #endif /* GLYPH_DEBUG */
21137 }
21138
21139
21140 /* Initialize this module when Emacs starts. */
21141
21142 void
21143 init_xdisp ()
21144 {
21145 Lisp_Object root_window;
21146 struct window *mini_w;
21147
21148 current_header_line_height = current_mode_line_height = -1;
21149
21150 CHARPOS (this_line_start_pos) = 0;
21151
21152 mini_w = XWINDOW (minibuf_window);
21153 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21154
21155 if (!noninteractive)
21156 {
21157 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21158 int i;
21159
21160 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
21161 set_window_height (root_window,
21162 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
21163 0);
21164 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
21165 set_window_height (minibuf_window, 1, 0);
21166
21167 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
21168 mini_w->total_cols = make_number (FRAME_COLS (f));
21169
21170 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21171 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21172 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21173
21174 /* The default ellipsis glyphs `...'. */
21175 for (i = 0; i < 3; ++i)
21176 default_invis_vector[i] = make_number ('.');
21177 }
21178
21179 {
21180 /* Allocate the buffer for frame titles.
21181 Also used for `format-mode-line'. */
21182 int size = 100;
21183 frame_title_buf = (char *) xmalloc (size);
21184 frame_title_buf_end = frame_title_buf + size;
21185 frame_title_ptr = NULL;
21186 }
21187
21188 help_echo_showing_p = 0;
21189 }
21190
21191