Merged in changes from CVS HEAD
[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,04
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 "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201
202 Cursor No_Cursor;
203 #endif
204
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
208
209 #define INFINITY 10000000
210
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
216
217 extern int interrupt_input;
218 extern int command_loop_level;
219
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
222
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
231
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
241
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
247
248 Lisp_Object Qrisky_local_variable;
249
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
252
253 /* Functions called to fontify regions of text. */
254
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
257
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
261
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
264
265 int auto_raise_tool_bar_buttons_p;
266
267 /* Margin around tool bar buttons in pixels. */
268
269 Lisp_Object Vtool_bar_button_margin;
270
271 /* Thickness of shadow to draw around tool bar buttons. */
272
273 EMACS_INT tool_bar_button_relief;
274
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
277
278 int auto_resize_tool_bars_p;
279
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
283
284 int x_stretch_cursor_p;
285
286 /* Non-nil means don't actually do any redisplay. */
287
288 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
289
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
291
292 int inhibit_eval_during_redisplay;
293
294 /* Names of text properties relevant for redisplay. */
295
296 Lisp_Object Qdisplay;
297 extern Lisp_Object Qface, Qinvisible, Qwidth;
298
299 /* Symbols used in text property values. */
300
301 Lisp_Object Vdisplay_pixels_per_inch;
302 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304 Lisp_Object Qmargin, Qpointer;
305 extern Lisp_Object Qheight;
306 extern Lisp_Object QCwidth, QCheight, QCascent;
307 extern Lisp_Object Qscroll_bar;
308
309 /* Non-nil means highlight trailing whitespace. */
310
311 Lisp_Object Vshow_trailing_whitespace;
312
313 #ifdef HAVE_WINDOW_SYSTEM
314 extern Lisp_Object Voverflow_newline_into_fringe;
315
316 /* Test if overflow newline into fringe. Called with iterator IT
317 at or past right window margin, and with IT->current_x set. */
318
319 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
320 (!NILP (Voverflow_newline_into_fringe) \
321 && FRAME_WINDOW_P (it->f) \
322 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
323 && it->current_x == it->last_visible_x)
324
325 #endif /* HAVE_WINDOW_SYSTEM */
326
327 /* Non-nil means show the text cursor in void text areas
328 i.e. in blank areas after eol and eob. This used to be
329 the default in 21.3. */
330
331 Lisp_Object Vvoid_text_area_pointer;
332
333 /* Name of the face used to highlight trailing whitespace. */
334
335 Lisp_Object Qtrailing_whitespace;
336
337 /* The symbol `image' which is the car of the lists used to represent
338 images in Lisp. */
339
340 Lisp_Object Qimage;
341
342 /* The image map types. */
343 Lisp_Object QCmap, QCpointer;
344 Lisp_Object Qrect, Qcircle, Qpoly;
345
346 /* Non-zero means print newline to stdout before next mini-buffer
347 message. */
348
349 int noninteractive_need_newline;
350
351 /* Non-zero means print newline to message log before next message. */
352
353 static int message_log_need_newline;
354
355 /* Three markers that message_dolog uses.
356 It could allocate them itself, but that causes trouble
357 in handling memory-full errors. */
358 static Lisp_Object message_dolog_marker1;
359 static Lisp_Object message_dolog_marker2;
360 static Lisp_Object message_dolog_marker3;
361 \f
362 /* The buffer position of the first character appearing entirely or
363 partially on the line of the selected window which contains the
364 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
365 redisplay optimization in redisplay_internal. */
366
367 static struct text_pos this_line_start_pos;
368
369 /* Number of characters past the end of the line above, including the
370 terminating newline. */
371
372 static struct text_pos this_line_end_pos;
373
374 /* The vertical positions and the height of this line. */
375
376 static int this_line_vpos;
377 static int this_line_y;
378 static int this_line_pixel_height;
379
380 /* X position at which this display line starts. Usually zero;
381 negative if first character is partially visible. */
382
383 static int this_line_start_x;
384
385 /* Buffer that this_line_.* variables are referring to. */
386
387 static struct buffer *this_line_buffer;
388
389 /* Nonzero means truncate lines in all windows less wide than the
390 frame. */
391
392 int truncate_partial_width_windows;
393
394 /* A flag to control how to display unibyte 8-bit character. */
395
396 int unibyte_display_via_language_environment;
397
398 /* Nonzero means we have more than one non-mini-buffer-only frame.
399 Not guaranteed to be accurate except while parsing
400 frame-title-format. */
401
402 int multiple_frames;
403
404 Lisp_Object Vglobal_mode_string;
405
406 /* Marker for where to display an arrow on top of the buffer text. */
407
408 Lisp_Object Voverlay_arrow_position;
409
410 /* String to display for the arrow. Only used on terminal frames. */
411
412 Lisp_Object Voverlay_arrow_string;
413
414 /* Values of those variables at last redisplay. However, if
415 Voverlay_arrow_position is a marker, last_arrow_position is its
416 numerical position. */
417
418 static Lisp_Object last_arrow_position, last_arrow_string;
419
420 /* Like mode-line-format, but for the title bar on a visible frame. */
421
422 Lisp_Object Vframe_title_format;
423
424 /* Like mode-line-format, but for the title bar on an iconified frame. */
425
426 Lisp_Object Vicon_title_format;
427
428 /* List of functions to call when a window's size changes. These
429 functions get one arg, a frame on which one or more windows' sizes
430 have changed. */
431
432 static Lisp_Object Vwindow_size_change_functions;
433
434 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
435
436 /* Nonzero if overlay arrow has been displayed once in this window. */
437
438 static int overlay_arrow_seen;
439
440 /* Nonzero means highlight the region even in nonselected windows. */
441
442 int highlight_nonselected_windows;
443
444 /* If cursor motion alone moves point off frame, try scrolling this
445 many lines up or down if that will bring it back. */
446
447 static EMACS_INT scroll_step;
448
449 /* Nonzero means scroll just far enough to bring point back on the
450 screen, when appropriate. */
451
452 static EMACS_INT scroll_conservatively;
453
454 /* Recenter the window whenever point gets within this many lines of
455 the top or bottom of the window. This value is translated into a
456 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
457 that there is really a fixed pixel height scroll margin. */
458
459 EMACS_INT scroll_margin;
460
461 /* Number of windows showing the buffer of the selected window (or
462 another buffer with the same base buffer). keyboard.c refers to
463 this. */
464
465 int buffer_shared;
466
467 /* Vector containing glyphs for an ellipsis `...'. */
468
469 static Lisp_Object default_invis_vector[3];
470
471 /* Zero means display the mode-line/header-line/menu-bar in the default face
472 (this slightly odd definition is for compatibility with previous versions
473 of emacs), non-zero means display them using their respective faces.
474
475 This variable is deprecated. */
476
477 int mode_line_inverse_video;
478
479 /* Prompt to display in front of the mini-buffer contents. */
480
481 Lisp_Object minibuf_prompt;
482
483 /* Width of current mini-buffer prompt. Only set after display_line
484 of the line that contains the prompt. */
485
486 int minibuf_prompt_width;
487
488 /* This is the window where the echo area message was displayed. It
489 is always a mini-buffer window, but it may not be the same window
490 currently active as a mini-buffer. */
491
492 Lisp_Object echo_area_window;
493
494 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
495 pushes the current message and the value of
496 message_enable_multibyte on the stack, the function restore_message
497 pops the stack and displays MESSAGE again. */
498
499 Lisp_Object Vmessage_stack;
500
501 /* Nonzero means multibyte characters were enabled when the echo area
502 message was specified. */
503
504 int message_enable_multibyte;
505
506 /* Nonzero if we should redraw the mode lines on the next redisplay. */
507
508 int update_mode_lines;
509
510 /* Nonzero if window sizes or contents have changed since last
511 redisplay that finished. */
512
513 int windows_or_buffers_changed;
514
515 /* Nonzero means a frame's cursor type has been changed. */
516
517 int cursor_type_changed;
518
519 /* Nonzero after display_mode_line if %l was used and it displayed a
520 line number. */
521
522 int line_number_displayed;
523
524 /* Maximum buffer size for which to display line numbers. */
525
526 Lisp_Object Vline_number_display_limit;
527
528 /* Line width to consider when repositioning for line number display. */
529
530 static EMACS_INT line_number_display_limit_width;
531
532 /* Number of lines to keep in the message log buffer. t means
533 infinite. nil means don't log at all. */
534
535 Lisp_Object Vmessage_log_max;
536
537 /* The name of the *Messages* buffer, a string. */
538
539 static Lisp_Object Vmessages_buffer_name;
540
541 /* Current, index 0, and last displayed echo area message. Either
542 buffers from echo_buffers, or nil to indicate no message. */
543
544 Lisp_Object echo_area_buffer[2];
545
546 /* The buffers referenced from echo_area_buffer. */
547
548 static Lisp_Object echo_buffer[2];
549
550 /* A vector saved used in with_area_buffer to reduce consing. */
551
552 static Lisp_Object Vwith_echo_area_save_vector;
553
554 /* Non-zero means display_echo_area should display the last echo area
555 message again. Set by redisplay_preserve_echo_area. */
556
557 static int display_last_displayed_message_p;
558
559 /* Nonzero if echo area is being used by print; zero if being used by
560 message. */
561
562 int message_buf_print;
563
564 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
565
566 Lisp_Object Qinhibit_menubar_update;
567 int inhibit_menubar_update;
568
569 /* Maximum height for resizing mini-windows. Either a float
570 specifying a fraction of the available height, or an integer
571 specifying a number of lines. */
572
573 Lisp_Object Vmax_mini_window_height;
574
575 /* Non-zero means messages should be displayed with truncated
576 lines instead of being continued. */
577
578 int message_truncate_lines;
579 Lisp_Object Qmessage_truncate_lines;
580
581 /* Set to 1 in clear_message to make redisplay_internal aware
582 of an emptied echo area. */
583
584 static int message_cleared_p;
585
586 /* Non-zero means we want a hollow cursor in windows that are not
587 selected. Zero means there's no cursor in such windows. */
588
589 Lisp_Object Vcursor_in_non_selected_windows;
590 Lisp_Object Qcursor_in_non_selected_windows;
591
592 /* How to blink the default frame cursor off. */
593 Lisp_Object Vblink_cursor_alist;
594
595 /* A scratch glyph row with contents used for generating truncation
596 glyphs. Also used in direct_output_for_insert. */
597
598 #define MAX_SCRATCH_GLYPHS 100
599 struct glyph_row scratch_glyph_row;
600 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
601
602 /* Ascent and height of the last line processed by move_it_to. */
603
604 static int last_max_ascent, last_height;
605
606 /* Non-zero if there's a help-echo in the echo area. */
607
608 int help_echo_showing_p;
609
610 /* If >= 0, computed, exact values of mode-line and header-line height
611 to use in the macros CURRENT_MODE_LINE_HEIGHT and
612 CURRENT_HEADER_LINE_HEIGHT. */
613
614 int current_mode_line_height, current_header_line_height;
615
616 /* The maximum distance to look ahead for text properties. Values
617 that are too small let us call compute_char_face and similar
618 functions too often which is expensive. Values that are too large
619 let us call compute_char_face and alike too often because we
620 might not be interested in text properties that far away. */
621
622 #define TEXT_PROP_DISTANCE_LIMIT 100
623
624 #if GLYPH_DEBUG
625
626 /* Variables to turn off display optimizations from Lisp. */
627
628 int inhibit_try_window_id, inhibit_try_window_reusing;
629 int inhibit_try_cursor_movement;
630
631 /* Non-zero means print traces of redisplay if compiled with
632 GLYPH_DEBUG != 0. */
633
634 int trace_redisplay_p;
635
636 #endif /* GLYPH_DEBUG */
637
638 #ifdef DEBUG_TRACE_MOVE
639 /* Non-zero means trace with TRACE_MOVE to stderr. */
640 int trace_move;
641
642 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
643 #else
644 #define TRACE_MOVE(x) (void) 0
645 #endif
646
647 /* Non-zero means automatically scroll windows horizontally to make
648 point visible. */
649
650 int automatic_hscrolling_p;
651
652 /* How close to the margin can point get before the window is scrolled
653 horizontally. */
654 EMACS_INT hscroll_margin;
655
656 /* How much to scroll horizontally when point is inside the above margin. */
657 Lisp_Object Vhscroll_step;
658
659 /* A list of symbols, one for each supported image type. */
660
661 Lisp_Object Vimage_types;
662
663 /* The variable `resize-mini-windows'. If nil, don't resize
664 mini-windows. If t, always resize them to fit the text they
665 display. If `grow-only', let mini-windows grow only until they
666 become empty. */
667
668 Lisp_Object Vresize_mini_windows;
669
670 /* Buffer being redisplayed -- for redisplay_window_error. */
671
672 struct buffer *displayed_buffer;
673
674 /* Value returned from text property handlers (see below). */
675
676 enum prop_handled
677 {
678 HANDLED_NORMALLY,
679 HANDLED_RECOMPUTE_PROPS,
680 HANDLED_OVERLAY_STRING_CONSUMED,
681 HANDLED_RETURN
682 };
683
684 /* A description of text properties that redisplay is interested
685 in. */
686
687 struct props
688 {
689 /* The name of the property. */
690 Lisp_Object *name;
691
692 /* A unique index for the property. */
693 enum prop_idx idx;
694
695 /* A handler function called to set up iterator IT from the property
696 at IT's current position. Value is used to steer handle_stop. */
697 enum prop_handled (*handler) P_ ((struct it *it));
698 };
699
700 static enum prop_handled handle_face_prop P_ ((struct it *));
701 static enum prop_handled handle_invisible_prop P_ ((struct it *));
702 static enum prop_handled handle_display_prop P_ ((struct it *));
703 static enum prop_handled handle_composition_prop P_ ((struct it *));
704 static enum prop_handled handle_overlay_change P_ ((struct it *));
705 static enum prop_handled handle_fontified_prop P_ ((struct it *));
706
707 /* Properties handled by iterators. */
708
709 static struct props it_props[] =
710 {
711 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
712 /* Handle `face' before `display' because some sub-properties of
713 `display' need to know the face. */
714 {&Qface, FACE_PROP_IDX, handle_face_prop},
715 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
716 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
717 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
718 {NULL, 0, NULL}
719 };
720
721 /* Value is the position described by X. If X is a marker, value is
722 the marker_position of X. Otherwise, value is X. */
723
724 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
725
726 /* Enumeration returned by some move_it_.* functions internally. */
727
728 enum move_it_result
729 {
730 /* Not used. Undefined value. */
731 MOVE_UNDEFINED,
732
733 /* Move ended at the requested buffer position or ZV. */
734 MOVE_POS_MATCH_OR_ZV,
735
736 /* Move ended at the requested X pixel position. */
737 MOVE_X_REACHED,
738
739 /* Move within a line ended at the end of a line that must be
740 continued. */
741 MOVE_LINE_CONTINUED,
742
743 /* Move within a line ended at the end of a line that would
744 be displayed truncated. */
745 MOVE_LINE_TRUNCATED,
746
747 /* Move within a line ended at a line end. */
748 MOVE_NEWLINE_OR_CR
749 };
750
751 /* This counter is used to clear the face cache every once in a while
752 in redisplay_internal. It is incremented for each redisplay.
753 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
754 cleared. */
755
756 #define CLEAR_FACE_CACHE_COUNT 500
757 static int clear_face_cache_count;
758
759 /* Non-zero while redisplay_internal is in progress. */
760
761 int redisplaying_p;
762
763 /* Non-zero means don't free realized faces. Bound while freeing
764 realized faces is dangerous because glyph matrices might still
765 reference them. */
766
767 int inhibit_free_realized_faces;
768 Lisp_Object Qinhibit_free_realized_faces;
769
770 /* If a string, XTread_socket generates an event to display that string.
771 (The display is done in read_char.) */
772
773 Lisp_Object help_echo_string;
774 Lisp_Object help_echo_window;
775 Lisp_Object help_echo_object;
776 int help_echo_pos;
777
778 /* Temporary variable for XTread_socket. */
779
780 Lisp_Object previous_help_echo_string;
781
782
783 \f
784 /* Function prototypes. */
785
786 static void setup_for_ellipsis P_ ((struct it *));
787 static void mark_window_display_accurate_1 P_ ((struct window *, int));
788 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
789 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
790 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
791 static int redisplay_mode_lines P_ ((Lisp_Object, int));
792 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
793
794 #if 0
795 static int invisible_text_between_p P_ ((struct it *, int, int));
796 #endif
797
798 static int next_element_from_ellipsis P_ ((struct it *));
799 static void pint2str P_ ((char *, int, int));
800 static void pint2hrstr P_ ((char *, int, int));
801 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
802 struct text_pos));
803 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
804 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
805 static void store_frame_title_char P_ ((char));
806 static int store_frame_title P_ ((const unsigned char *, int, int));
807 static void x_consider_frame_title P_ ((Lisp_Object));
808 static void handle_stop P_ ((struct it *));
809 static int tool_bar_lines_needed P_ ((struct frame *));
810 static int single_display_prop_intangible_p P_ ((Lisp_Object));
811 static void ensure_echo_area_buffers P_ ((void));
812 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
813 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
814 static int with_echo_area_buffer P_ ((struct window *, int,
815 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
816 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
817 static void clear_garbaged_frames P_ ((void));
818 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
819 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
820 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
821 static int display_echo_area P_ ((struct window *));
822 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
823 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
824 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
825 static int string_char_and_length P_ ((const unsigned char *, int, int *));
826 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
827 struct text_pos));
828 static int compute_window_start_on_continuation_line P_ ((struct window *));
829 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
830 static void insert_left_trunc_glyphs P_ ((struct it *));
831 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
832 static void extend_face_to_end_of_line P_ ((struct it *));
833 static int append_space P_ ((struct it *, int));
834 static int make_cursor_line_fully_visible P_ ((struct window *));
835 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
836 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
837 static int trailing_whitespace_p P_ ((int));
838 static int message_log_check_duplicate P_ ((int, int, int, int));
839 static void push_it P_ ((struct it *));
840 static void pop_it P_ ((struct it *));
841 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
842 static void select_frame_for_redisplay P_ ((Lisp_Object));
843 static void redisplay_internal P_ ((int));
844 static int echo_area_display P_ ((int));
845 static void redisplay_windows P_ ((Lisp_Object));
846 static void redisplay_window P_ ((Lisp_Object, int));
847 static Lisp_Object redisplay_window_error ();
848 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
849 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
850 static void update_menu_bar P_ ((struct frame *, int));
851 static int try_window_reusing_current_matrix P_ ((struct window *));
852 static int try_window_id P_ ((struct window *));
853 static int display_line P_ ((struct it *));
854 static int display_mode_lines P_ ((struct window *));
855 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
856 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
857 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
858 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
859 static void display_menu_bar P_ ((struct window *));
860 static int display_count_lines P_ ((int, int, int, int, int *));
861 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
862 int, int, struct it *, int, int, int, int));
863 static void compute_line_metrics P_ ((struct it *));
864 static void run_redisplay_end_trigger_hook P_ ((struct it *));
865 static int get_overlay_strings P_ ((struct it *, int));
866 static void next_overlay_string P_ ((struct it *));
867 static void reseat P_ ((struct it *, struct text_pos, int));
868 static void reseat_1 P_ ((struct it *, struct text_pos, int));
869 static void back_to_previous_visible_line_start P_ ((struct it *));
870 static void reseat_at_previous_visible_line_start P_ ((struct it *));
871 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
872 static int next_element_from_display_vector P_ ((struct it *));
873 static int next_element_from_string P_ ((struct it *));
874 static int next_element_from_c_string P_ ((struct it *));
875 static int next_element_from_buffer P_ ((struct it *));
876 static int next_element_from_composition P_ ((struct it *));
877 static int next_element_from_image P_ ((struct it *));
878 static int next_element_from_stretch P_ ((struct it *));
879 static void load_overlay_strings P_ ((struct it *, int));
880 static int init_from_display_pos P_ ((struct it *, struct window *,
881 struct display_pos *));
882 static void reseat_to_string P_ ((struct it *, unsigned char *,
883 Lisp_Object, int, int, int, int));
884 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
885 int, int, int));
886 void move_it_vertically_backward P_ ((struct it *, int));
887 static void init_to_row_start P_ ((struct it *, struct window *,
888 struct glyph_row *));
889 static int init_to_row_end P_ ((struct it *, struct window *,
890 struct glyph_row *));
891 static void back_to_previous_line_start P_ ((struct it *));
892 static int forward_to_next_line_start P_ ((struct it *, int *));
893 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
894 Lisp_Object, int));
895 static struct text_pos string_pos P_ ((int, Lisp_Object));
896 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
897 static int number_of_chars P_ ((unsigned char *, int));
898 static void compute_stop_pos P_ ((struct it *));
899 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
900 Lisp_Object));
901 static int face_before_or_after_it_pos P_ ((struct it *, int));
902 static int next_overlay_change P_ ((int));
903 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
904 Lisp_Object, struct text_pos *,
905 int));
906 static int underlying_face_id P_ ((struct it *));
907 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
908 struct window *));
909
910 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
911 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
912
913 #ifdef HAVE_WINDOW_SYSTEM
914
915 static void update_tool_bar P_ ((struct frame *, int));
916 static void build_desired_tool_bar_string P_ ((struct frame *f));
917 static int redisplay_tool_bar P_ ((struct frame *));
918 static void display_tool_bar_line P_ ((struct it *));
919 static void notice_overwritten_cursor P_ ((struct window *,
920 enum glyph_row_area,
921 int, int, int, int));
922
923
924
925 #endif /* HAVE_WINDOW_SYSTEM */
926
927 \f
928 /***********************************************************************
929 Window display dimensions
930 ***********************************************************************/
931
932 /* Return the bottom boundary y-position for text lines in window W.
933 This is the first y position at which a line cannot start.
934 It is relative to the top of the window.
935
936 This is the height of W minus the height of a mode line, if any. */
937
938 INLINE int
939 window_text_bottom_y (w)
940 struct window *w;
941 {
942 int height = WINDOW_TOTAL_HEIGHT (w);
943
944 if (WINDOW_WANTS_MODELINE_P (w))
945 height -= CURRENT_MODE_LINE_HEIGHT (w);
946 return height;
947 }
948
949 /* Return the pixel width of display area AREA of window W. AREA < 0
950 means return the total width of W, not including fringes to
951 the left and right of the window. */
952
953 INLINE int
954 window_box_width (w, area)
955 struct window *w;
956 int area;
957 {
958 int cols = XFASTINT (w->total_cols);
959 int pixels = 0;
960
961 if (!w->pseudo_window_p)
962 {
963 cols -= WINDOW_SCROLL_BAR_COLS (w);
964
965 if (area == TEXT_AREA)
966 {
967 if (INTEGERP (w->left_margin_cols))
968 cols -= XFASTINT (w->left_margin_cols);
969 if (INTEGERP (w->right_margin_cols))
970 cols -= XFASTINT (w->right_margin_cols);
971 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
972 }
973 else if (area == LEFT_MARGIN_AREA)
974 {
975 cols = (INTEGERP (w->left_margin_cols)
976 ? XFASTINT (w->left_margin_cols) : 0);
977 pixels = 0;
978 }
979 else if (area == RIGHT_MARGIN_AREA)
980 {
981 cols = (INTEGERP (w->right_margin_cols)
982 ? XFASTINT (w->right_margin_cols) : 0);
983 pixels = 0;
984 }
985 }
986
987 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
988 }
989
990
991 /* Return the pixel height of the display area of window W, not
992 including mode lines of W, if any. */
993
994 INLINE int
995 window_box_height (w)
996 struct window *w;
997 {
998 struct frame *f = XFRAME (w->frame);
999 int height = WINDOW_TOTAL_HEIGHT (w);
1000
1001 xassert (height >= 0);
1002
1003 /* Note: the code below that determines the mode-line/header-line
1004 height is essentially the same as that contained in the macro
1005 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1006 the appropriate glyph row has its `mode_line_p' flag set,
1007 and if it doesn't, uses estimate_mode_line_height instead. */
1008
1009 if (WINDOW_WANTS_MODELINE_P (w))
1010 {
1011 struct glyph_row *ml_row
1012 = (w->current_matrix && w->current_matrix->rows
1013 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1014 : 0);
1015 if (ml_row && ml_row->mode_line_p)
1016 height -= ml_row->height;
1017 else
1018 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1019 }
1020
1021 if (WINDOW_WANTS_HEADER_LINE_P (w))
1022 {
1023 struct glyph_row *hl_row
1024 = (w->current_matrix && w->current_matrix->rows
1025 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1026 : 0);
1027 if (hl_row && hl_row->mode_line_p)
1028 height -= hl_row->height;
1029 else
1030 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1031 }
1032
1033 /* With a very small font and a mode-line that's taller than
1034 default, we might end up with a negative height. */
1035 return max (0, height);
1036 }
1037
1038 /* Return the window-relative coordinate of the left edge of display
1039 area AREA of window W. AREA < 0 means return the left edge of the
1040 whole window, to the right of the left fringe of W. */
1041
1042 INLINE int
1043 window_box_left_offset (w, area)
1044 struct window *w;
1045 int area;
1046 {
1047 int x;
1048
1049 if (w->pseudo_window_p)
1050 return 0;
1051
1052 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1053
1054 if (area == TEXT_AREA)
1055 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1056 + window_box_width (w, LEFT_MARGIN_AREA));
1057 else if (area == RIGHT_MARGIN_AREA)
1058 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1059 + window_box_width (w, LEFT_MARGIN_AREA)
1060 + window_box_width (w, TEXT_AREA)
1061 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1062 ? 0
1063 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1064 else if (area == LEFT_MARGIN_AREA
1065 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1066 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1067
1068 return x;
1069 }
1070
1071
1072 /* Return the window-relative coordinate of the right edge of display
1073 area AREA of window W. AREA < 0 means return the left edge of the
1074 whole window, to the left of the right fringe of W. */
1075
1076 INLINE int
1077 window_box_right_offset (w, area)
1078 struct window *w;
1079 int area;
1080 {
1081 return window_box_left_offset (w, area) + window_box_width (w, area);
1082 }
1083
1084 /* Return the frame-relative coordinate of the left edge of display
1085 area AREA of window W. AREA < 0 means return the left edge of the
1086 whole window, to the right of the left fringe of W. */
1087
1088 INLINE int
1089 window_box_left (w, area)
1090 struct window *w;
1091 int area;
1092 {
1093 struct frame *f = XFRAME (w->frame);
1094 int x;
1095
1096 if (w->pseudo_window_p)
1097 return FRAME_INTERNAL_BORDER_WIDTH (f);
1098
1099 x = (WINDOW_LEFT_EDGE_X (w)
1100 + window_box_left_offset (w, area));
1101
1102 return x;
1103 }
1104
1105
1106 /* Return the frame-relative coordinate of the right edge of display
1107 area AREA of window W. AREA < 0 means return the left edge of the
1108 whole window, to the left of the right fringe of W. */
1109
1110 INLINE int
1111 window_box_right (w, area)
1112 struct window *w;
1113 int area;
1114 {
1115 return window_box_left (w, area) + window_box_width (w, area);
1116 }
1117
1118 /* Get the bounding box of the display area AREA of window W, without
1119 mode lines, in frame-relative coordinates. AREA < 0 means the
1120 whole window, not including the left and right fringes of
1121 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1122 coordinates of the upper-left corner of the box. Return in
1123 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1124
1125 INLINE void
1126 window_box (w, area, box_x, box_y, box_width, box_height)
1127 struct window *w;
1128 int area;
1129 int *box_x, *box_y, *box_width, *box_height;
1130 {
1131 if (box_width)
1132 *box_width = window_box_width (w, area);
1133 if (box_height)
1134 *box_height = window_box_height (w);
1135 if (box_x)
1136 *box_x = window_box_left (w, area);
1137 if (box_y)
1138 {
1139 *box_y = WINDOW_TOP_EDGE_Y (w);
1140 if (WINDOW_WANTS_HEADER_LINE_P (w))
1141 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1142 }
1143 }
1144
1145
1146 /* Get the bounding box of the display area AREA of window W, without
1147 mode lines. AREA < 0 means the whole window, not including the
1148 left and right fringe of the window. Return in *TOP_LEFT_X
1149 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1150 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1151 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1152 box. */
1153
1154 INLINE void
1155 window_box_edges (w, area, top_left_x, top_left_y,
1156 bottom_right_x, bottom_right_y)
1157 struct window *w;
1158 int area;
1159 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1160 {
1161 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1162 bottom_right_y);
1163 *bottom_right_x += *top_left_x;
1164 *bottom_right_y += *top_left_y;
1165 }
1166
1167
1168 \f
1169 /***********************************************************************
1170 Utilities
1171 ***********************************************************************/
1172
1173 /* Return the bottom y-position of the line the iterator IT is in.
1174 This can modify IT's settings. */
1175
1176 int
1177 line_bottom_y (it)
1178 struct it *it;
1179 {
1180 int line_height = it->max_ascent + it->max_descent;
1181 int line_top_y = it->current_y;
1182
1183 if (line_height == 0)
1184 {
1185 if (last_height)
1186 line_height = last_height;
1187 else if (IT_CHARPOS (*it) < ZV)
1188 {
1189 move_it_by_lines (it, 1, 1);
1190 line_height = (it->max_ascent || it->max_descent
1191 ? it->max_ascent + it->max_descent
1192 : last_height);
1193 }
1194 else
1195 {
1196 struct glyph_row *row = it->glyph_row;
1197
1198 /* Use the default character height. */
1199 it->glyph_row = NULL;
1200 it->what = IT_CHARACTER;
1201 it->c = ' ';
1202 it->len = 1;
1203 PRODUCE_GLYPHS (it);
1204 line_height = it->ascent + it->descent;
1205 it->glyph_row = row;
1206 }
1207 }
1208
1209 return line_top_y + line_height;
1210 }
1211
1212
1213 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1214 1 if POS is visible and the line containing POS is fully visible.
1215 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1216 and header-lines heights. */
1217
1218 int
1219 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1220 struct window *w;
1221 int charpos, *fully, exact_mode_line_heights_p;
1222 {
1223 struct it it;
1224 struct text_pos top;
1225 int visible_p;
1226 struct buffer *old_buffer = NULL;
1227
1228 if (XBUFFER (w->buffer) != current_buffer)
1229 {
1230 old_buffer = current_buffer;
1231 set_buffer_internal_1 (XBUFFER (w->buffer));
1232 }
1233
1234 *fully = visible_p = 0;
1235 SET_TEXT_POS_FROM_MARKER (top, w->start);
1236
1237 /* Compute exact mode line heights, if requested. */
1238 if (exact_mode_line_heights_p)
1239 {
1240 if (WINDOW_WANTS_MODELINE_P (w))
1241 current_mode_line_height
1242 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1243 current_buffer->mode_line_format);
1244
1245 if (WINDOW_WANTS_HEADER_LINE_P (w))
1246 current_header_line_height
1247 = display_mode_line (w, HEADER_LINE_FACE_ID,
1248 current_buffer->header_line_format);
1249 }
1250
1251 start_display (&it, w, top);
1252 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1253 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1254
1255 /* Note that we may overshoot because of invisible text. */
1256 if (IT_CHARPOS (it) >= charpos)
1257 {
1258 int top_y = it.current_y;
1259 int bottom_y = line_bottom_y (&it);
1260 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1261
1262 if (top_y < window_top_y)
1263 visible_p = bottom_y > window_top_y;
1264 else if (top_y < it.last_visible_y)
1265 {
1266 visible_p = 1;
1267 *fully = bottom_y <= it.last_visible_y;
1268 }
1269 }
1270 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1271 {
1272 move_it_by_lines (&it, 1, 0);
1273 if (charpos < IT_CHARPOS (it))
1274 {
1275 visible_p = 1;
1276 *fully = 0;
1277 }
1278 }
1279
1280 if (old_buffer)
1281 set_buffer_internal_1 (old_buffer);
1282
1283 current_header_line_height = current_mode_line_height = -1;
1284 return visible_p;
1285 }
1286
1287
1288 /* Return the next character from STR which is MAXLEN bytes long.
1289 Return in *LEN the length of the character. This is like
1290 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1291 we find one, we return a `?', but with the length of the invalid
1292 character. */
1293
1294 static INLINE int
1295 string_char_and_length (str, maxlen, len)
1296 const unsigned char *str;
1297 int maxlen, *len;
1298 {
1299 int c;
1300
1301 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1302 if (!CHAR_VALID_P (c, 1))
1303 /* We may not change the length here because other places in Emacs
1304 don't use this function, i.e. they silently accept invalid
1305 characters. */
1306 c = '?';
1307
1308 return c;
1309 }
1310
1311
1312
1313 /* Given a position POS containing a valid character and byte position
1314 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1315
1316 static struct text_pos
1317 string_pos_nchars_ahead (pos, string, nchars)
1318 struct text_pos pos;
1319 Lisp_Object string;
1320 int nchars;
1321 {
1322 xassert (STRINGP (string) && nchars >= 0);
1323
1324 if (STRING_MULTIBYTE (string))
1325 {
1326 int rest = SBYTES (string) - BYTEPOS (pos);
1327 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1328 int len;
1329
1330 while (nchars--)
1331 {
1332 string_char_and_length (p, rest, &len);
1333 p += len, rest -= len;
1334 xassert (rest >= 0);
1335 CHARPOS (pos) += 1;
1336 BYTEPOS (pos) += len;
1337 }
1338 }
1339 else
1340 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1341
1342 return pos;
1343 }
1344
1345
1346 /* Value is the text position, i.e. character and byte position,
1347 for character position CHARPOS in STRING. */
1348
1349 static INLINE struct text_pos
1350 string_pos (charpos, string)
1351 int charpos;
1352 Lisp_Object string;
1353 {
1354 struct text_pos pos;
1355 xassert (STRINGP (string));
1356 xassert (charpos >= 0);
1357 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1358 return pos;
1359 }
1360
1361
1362 /* Value is a text position, i.e. character and byte position, for
1363 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1364 means recognize multibyte characters. */
1365
1366 static struct text_pos
1367 c_string_pos (charpos, s, multibyte_p)
1368 int charpos;
1369 unsigned char *s;
1370 int multibyte_p;
1371 {
1372 struct text_pos pos;
1373
1374 xassert (s != NULL);
1375 xassert (charpos >= 0);
1376
1377 if (multibyte_p)
1378 {
1379 int rest = strlen (s), len;
1380
1381 SET_TEXT_POS (pos, 0, 0);
1382 while (charpos--)
1383 {
1384 string_char_and_length (s, rest, &len);
1385 s += len, rest -= len;
1386 xassert (rest >= 0);
1387 CHARPOS (pos) += 1;
1388 BYTEPOS (pos) += len;
1389 }
1390 }
1391 else
1392 SET_TEXT_POS (pos, charpos, charpos);
1393
1394 return pos;
1395 }
1396
1397
1398 /* Value is the number of characters in C string S. MULTIBYTE_P
1399 non-zero means recognize multibyte characters. */
1400
1401 static int
1402 number_of_chars (s, multibyte_p)
1403 unsigned char *s;
1404 int multibyte_p;
1405 {
1406 int nchars;
1407
1408 if (multibyte_p)
1409 {
1410 int rest = strlen (s), len;
1411 unsigned char *p = (unsigned char *) s;
1412
1413 for (nchars = 0; rest > 0; ++nchars)
1414 {
1415 string_char_and_length (p, rest, &len);
1416 rest -= len, p += len;
1417 }
1418 }
1419 else
1420 nchars = strlen (s);
1421
1422 return nchars;
1423 }
1424
1425
1426 /* Compute byte position NEWPOS->bytepos corresponding to
1427 NEWPOS->charpos. POS is a known position in string STRING.
1428 NEWPOS->charpos must be >= POS.charpos. */
1429
1430 static void
1431 compute_string_pos (newpos, pos, string)
1432 struct text_pos *newpos, pos;
1433 Lisp_Object string;
1434 {
1435 xassert (STRINGP (string));
1436 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1437
1438 if (STRING_MULTIBYTE (string))
1439 *newpos = string_pos_nchars_ahead (pos, string,
1440 CHARPOS (*newpos) - CHARPOS (pos));
1441 else
1442 BYTEPOS (*newpos) = CHARPOS (*newpos);
1443 }
1444
1445 /* EXPORT:
1446 Return an estimation of the pixel height of mode or top lines on
1447 frame F. FACE_ID specifies what line's height to estimate. */
1448
1449 int
1450 estimate_mode_line_height (f, face_id)
1451 struct frame *f;
1452 enum face_id face_id;
1453 {
1454 #ifdef HAVE_WINDOW_SYSTEM
1455 if (FRAME_WINDOW_P (f))
1456 {
1457 int height = FONT_HEIGHT (FRAME_FONT (f));
1458
1459 /* This function is called so early when Emacs starts that the face
1460 cache and mode line face are not yet initialized. */
1461 if (FRAME_FACE_CACHE (f))
1462 {
1463 struct face *face = FACE_FROM_ID (f, face_id);
1464 if (face)
1465 {
1466 if (face->font)
1467 height = FONT_HEIGHT (face->font);
1468 if (face->box_line_width > 0)
1469 height += 2 * face->box_line_width;
1470 }
1471 }
1472
1473 return height;
1474 }
1475 #endif
1476
1477 return 1;
1478 }
1479
1480 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1481 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1482 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1483 not force the value into range. */
1484
1485 void
1486 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1487 FRAME_PTR f;
1488 register int pix_x, pix_y;
1489 int *x, *y;
1490 NativeRectangle *bounds;
1491 int noclip;
1492 {
1493
1494 #ifdef HAVE_WINDOW_SYSTEM
1495 if (FRAME_WINDOW_P (f))
1496 {
1497 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1498 even for negative values. */
1499 if (pix_x < 0)
1500 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1501 if (pix_y < 0)
1502 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1503
1504 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1505 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1506
1507 if (bounds)
1508 STORE_NATIVE_RECT (*bounds,
1509 FRAME_COL_TO_PIXEL_X (f, pix_x),
1510 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1511 FRAME_COLUMN_WIDTH (f) - 1,
1512 FRAME_LINE_HEIGHT (f) - 1);
1513
1514 if (!noclip)
1515 {
1516 if (pix_x < 0)
1517 pix_x = 0;
1518 else if (pix_x > FRAME_TOTAL_COLS (f))
1519 pix_x = FRAME_TOTAL_COLS (f);
1520
1521 if (pix_y < 0)
1522 pix_y = 0;
1523 else if (pix_y > FRAME_LINES (f))
1524 pix_y = FRAME_LINES (f);
1525 }
1526 }
1527 #endif
1528
1529 *x = pix_x;
1530 *y = pix_y;
1531 }
1532
1533
1534 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1535 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1536 can't tell the positions because W's display is not up to date,
1537 return 0. */
1538
1539 int
1540 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1541 struct window *w;
1542 int hpos, vpos;
1543 int *frame_x, *frame_y;
1544 {
1545 #ifdef HAVE_WINDOW_SYSTEM
1546 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1547 {
1548 int success_p;
1549
1550 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1551 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1552
1553 if (display_completed)
1554 {
1555 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1556 struct glyph *glyph = row->glyphs[TEXT_AREA];
1557 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1558
1559 hpos = row->x;
1560 vpos = row->y;
1561 while (glyph < end)
1562 {
1563 hpos += glyph->pixel_width;
1564 ++glyph;
1565 }
1566
1567 /* If first glyph is partially visible, its first visible position is still 0. */
1568 if (hpos < 0)
1569 hpos = 0;
1570
1571 success_p = 1;
1572 }
1573 else
1574 {
1575 hpos = vpos = 0;
1576 success_p = 0;
1577 }
1578
1579 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1580 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1581 return success_p;
1582 }
1583 #endif
1584
1585 *frame_x = hpos;
1586 *frame_y = vpos;
1587 return 1;
1588 }
1589
1590
1591 #ifdef HAVE_WINDOW_SYSTEM
1592
1593 /* Find the glyph under window-relative coordinates X/Y in window W.
1594 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1595 strings. Return in *HPOS and *VPOS the row and column number of
1596 the glyph found. Return in *AREA the glyph area containing X.
1597 Value is a pointer to the glyph found or null if X/Y is not on
1598 text, or we can't tell because W's current matrix is not up to
1599 date. */
1600
1601 static struct glyph *
1602 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1603 struct window *w;
1604 int x, y;
1605 int *hpos, *vpos, *dx, *dy, *area;
1606 {
1607 struct glyph *glyph, *end;
1608 struct glyph_row *row = NULL;
1609 int x0, i;
1610
1611 /* Find row containing Y. Give up if some row is not enabled. */
1612 for (i = 0; i < w->current_matrix->nrows; ++i)
1613 {
1614 row = MATRIX_ROW (w->current_matrix, i);
1615 if (!row->enabled_p)
1616 return NULL;
1617 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1618 break;
1619 }
1620
1621 *vpos = i;
1622 *hpos = 0;
1623
1624 /* Give up if Y is not in the window. */
1625 if (i == w->current_matrix->nrows)
1626 return NULL;
1627
1628 /* Get the glyph area containing X. */
1629 if (w->pseudo_window_p)
1630 {
1631 *area = TEXT_AREA;
1632 x0 = 0;
1633 }
1634 else
1635 {
1636 if (x < window_box_left_offset (w, TEXT_AREA))
1637 {
1638 *area = LEFT_MARGIN_AREA;
1639 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1640 }
1641 else if (x < window_box_right_offset (w, TEXT_AREA))
1642 {
1643 *area = TEXT_AREA;
1644 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1645 }
1646 else
1647 {
1648 *area = RIGHT_MARGIN_AREA;
1649 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1650 }
1651 }
1652
1653 /* Find glyph containing X. */
1654 glyph = row->glyphs[*area];
1655 end = glyph + row->used[*area];
1656 x -= x0;
1657 while (glyph < end && x >= glyph->pixel_width)
1658 {
1659 x -= glyph->pixel_width;
1660 ++glyph;
1661 }
1662
1663 if (glyph == end)
1664 return NULL;
1665
1666 if (dx)
1667 {
1668 *dx = x;
1669 *dy = y - (row->y + row->ascent - glyph->ascent);
1670 }
1671
1672 *hpos = glyph - row->glyphs[*area];
1673 return glyph;
1674 }
1675
1676
1677 /* EXPORT:
1678 Convert frame-relative x/y to coordinates relative to window W.
1679 Takes pseudo-windows into account. */
1680
1681 void
1682 frame_to_window_pixel_xy (w, x, y)
1683 struct window *w;
1684 int *x, *y;
1685 {
1686 if (w->pseudo_window_p)
1687 {
1688 /* A pseudo-window is always full-width, and starts at the
1689 left edge of the frame, plus a frame border. */
1690 struct frame *f = XFRAME (w->frame);
1691 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1692 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1693 }
1694 else
1695 {
1696 *x -= WINDOW_LEFT_EDGE_X (w);
1697 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1698 }
1699 }
1700
1701 /* EXPORT:
1702 Return in *R the clipping rectangle for glyph string S. */
1703
1704 void
1705 get_glyph_string_clip_rect (s, nr)
1706 struct glyph_string *s;
1707 NativeRectangle *nr;
1708 {
1709 XRectangle r;
1710
1711 if (s->row->full_width_p)
1712 {
1713 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1714 r.x = WINDOW_LEFT_EDGE_X (s->w);
1715 r.width = WINDOW_TOTAL_WIDTH (s->w);
1716
1717 /* Unless displaying a mode or menu bar line, which are always
1718 fully visible, clip to the visible part of the row. */
1719 if (s->w->pseudo_window_p)
1720 r.height = s->row->visible_height;
1721 else
1722 r.height = s->height;
1723 }
1724 else
1725 {
1726 /* This is a text line that may be partially visible. */
1727 r.x = window_box_left (s->w, s->area);
1728 r.width = window_box_width (s->w, s->area);
1729 r.height = s->row->visible_height;
1730 }
1731
1732 /* If S draws overlapping rows, it's sufficient to use the top and
1733 bottom of the window for clipping because this glyph string
1734 intentionally draws over other lines. */
1735 if (s->for_overlaps_p)
1736 {
1737 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1738 r.height = window_text_bottom_y (s->w) - r.y;
1739 }
1740 else
1741 {
1742 /* Don't use S->y for clipping because it doesn't take partially
1743 visible lines into account. For example, it can be negative for
1744 partially visible lines at the top of a window. */
1745 if (!s->row->full_width_p
1746 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1747 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1748 else
1749 r.y = max (0, s->row->y);
1750
1751 /* If drawing a tool-bar window, draw it over the internal border
1752 at the top of the window. */
1753 if (s->w == XWINDOW (s->f->tool_bar_window))
1754 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1755 }
1756
1757 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1758
1759 /* If drawing the cursor, don't let glyph draw outside its
1760 advertised boundaries. Cleartype does this under some circumstances. */
1761 if (s->hl == DRAW_CURSOR)
1762 {
1763 struct glyph *glyph = s->first_glyph;
1764 int height;
1765
1766 if (s->x > r.x)
1767 {
1768 r.width -= s->x - r.x;
1769 r.x = s->x;
1770 }
1771 r.width = min (r.width, glyph->pixel_width);
1772
1773 /* Don't draw cursor glyph taller than our actual glyph. */
1774 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1775 if (height < r.height)
1776 {
1777 r.y = s->ybase + glyph->descent - height;
1778 r.height = height;
1779 }
1780 }
1781
1782 #ifdef CONVERT_FROM_XRECT
1783 CONVERT_FROM_XRECT (r, *nr);
1784 #else
1785 *nr = r;
1786 #endif
1787 }
1788
1789 #endif /* HAVE_WINDOW_SYSTEM */
1790
1791 \f
1792 /***********************************************************************
1793 Lisp form evaluation
1794 ***********************************************************************/
1795
1796 /* Error handler for safe_eval and safe_call. */
1797
1798 static Lisp_Object
1799 safe_eval_handler (arg)
1800 Lisp_Object arg;
1801 {
1802 add_to_log ("Error during redisplay: %s", arg, Qnil);
1803 return Qnil;
1804 }
1805
1806
1807 /* Evaluate SEXPR and return the result, or nil if something went
1808 wrong. Prevent redisplay during the evaluation. */
1809
1810 Lisp_Object
1811 safe_eval (sexpr)
1812 Lisp_Object sexpr;
1813 {
1814 Lisp_Object val;
1815
1816 if (inhibit_eval_during_redisplay)
1817 val = Qnil;
1818 else
1819 {
1820 int count = SPECPDL_INDEX ();
1821 struct gcpro gcpro1;
1822
1823 GCPRO1 (sexpr);
1824 specbind (Qinhibit_redisplay, Qt);
1825 /* Use Qt to ensure debugger does not run,
1826 so there is no possibility of wanting to redisplay. */
1827 val = internal_condition_case_1 (Feval, sexpr, Qt,
1828 safe_eval_handler);
1829 UNGCPRO;
1830 val = unbind_to (count, val);
1831 }
1832
1833 return val;
1834 }
1835
1836
1837 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1838 Return the result, or nil if something went wrong. Prevent
1839 redisplay during the evaluation. */
1840
1841 Lisp_Object
1842 safe_call (nargs, args)
1843 int nargs;
1844 Lisp_Object *args;
1845 {
1846 Lisp_Object val;
1847
1848 if (inhibit_eval_during_redisplay)
1849 val = Qnil;
1850 else
1851 {
1852 int count = SPECPDL_INDEX ();
1853 struct gcpro gcpro1;
1854
1855 GCPRO1 (args[0]);
1856 gcpro1.nvars = nargs;
1857 specbind (Qinhibit_redisplay, Qt);
1858 /* Use Qt to ensure debugger does not run,
1859 so there is no possibility of wanting to redisplay. */
1860 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1861 safe_eval_handler);
1862 UNGCPRO;
1863 val = unbind_to (count, val);
1864 }
1865
1866 return val;
1867 }
1868
1869
1870 /* Call function FN with one argument ARG.
1871 Return the result, or nil if something went wrong. */
1872
1873 Lisp_Object
1874 safe_call1 (fn, arg)
1875 Lisp_Object fn, arg;
1876 {
1877 Lisp_Object args[2];
1878 args[0] = fn;
1879 args[1] = arg;
1880 return safe_call (2, args);
1881 }
1882
1883
1884 \f
1885 /***********************************************************************
1886 Debugging
1887 ***********************************************************************/
1888
1889 #if 0
1890
1891 /* Define CHECK_IT to perform sanity checks on iterators.
1892 This is for debugging. It is too slow to do unconditionally. */
1893
1894 static void
1895 check_it (it)
1896 struct it *it;
1897 {
1898 if (it->method == next_element_from_string)
1899 {
1900 xassert (STRINGP (it->string));
1901 xassert (IT_STRING_CHARPOS (*it) >= 0);
1902 }
1903 else if (it->method == next_element_from_buffer)
1904 {
1905 /* Check that character and byte positions agree. */
1906 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1907 }
1908
1909 if (it->dpvec)
1910 xassert (it->current.dpvec_index >= 0);
1911 else
1912 xassert (it->current.dpvec_index < 0);
1913 }
1914
1915 #define CHECK_IT(IT) check_it ((IT))
1916
1917 #else /* not 0 */
1918
1919 #define CHECK_IT(IT) (void) 0
1920
1921 #endif /* not 0 */
1922
1923
1924 #if GLYPH_DEBUG
1925
1926 /* Check that the window end of window W is what we expect it
1927 to be---the last row in the current matrix displaying text. */
1928
1929 static void
1930 check_window_end (w)
1931 struct window *w;
1932 {
1933 if (!MINI_WINDOW_P (w)
1934 && !NILP (w->window_end_valid))
1935 {
1936 struct glyph_row *row;
1937 xassert ((row = MATRIX_ROW (w->current_matrix,
1938 XFASTINT (w->window_end_vpos)),
1939 !row->enabled_p
1940 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1941 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1942 }
1943 }
1944
1945 #define CHECK_WINDOW_END(W) check_window_end ((W))
1946
1947 #else /* not GLYPH_DEBUG */
1948
1949 #define CHECK_WINDOW_END(W) (void) 0
1950
1951 #endif /* not GLYPH_DEBUG */
1952
1953
1954 \f
1955 /***********************************************************************
1956 Iterator initialization
1957 ***********************************************************************/
1958
1959 /* Initialize IT for displaying current_buffer in window W, starting
1960 at character position CHARPOS. CHARPOS < 0 means that no buffer
1961 position is specified which is useful when the iterator is assigned
1962 a position later. BYTEPOS is the byte position corresponding to
1963 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1964
1965 If ROW is not null, calls to produce_glyphs with IT as parameter
1966 will produce glyphs in that row.
1967
1968 BASE_FACE_ID is the id of a base face to use. It must be one of
1969 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1970 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1971 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1972
1973 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1974 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1975 will be initialized to use the corresponding mode line glyph row of
1976 the desired matrix of W. */
1977
1978 void
1979 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1980 struct it *it;
1981 struct window *w;
1982 int charpos, bytepos;
1983 struct glyph_row *row;
1984 enum face_id base_face_id;
1985 {
1986 int highlight_region_p;
1987
1988 /* Some precondition checks. */
1989 xassert (w != NULL && it != NULL);
1990 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1991 && charpos <= ZV));
1992
1993 /* If face attributes have been changed since the last redisplay,
1994 free realized faces now because they depend on face definitions
1995 that might have changed. Don't free faces while there might be
1996 desired matrices pending which reference these faces. */
1997 if (face_change_count && !inhibit_free_realized_faces)
1998 {
1999 face_change_count = 0;
2000 free_all_realized_faces (Qnil);
2001 }
2002
2003 /* Use one of the mode line rows of W's desired matrix if
2004 appropriate. */
2005 if (row == NULL)
2006 {
2007 if (base_face_id == MODE_LINE_FACE_ID
2008 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2009 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2010 else if (base_face_id == HEADER_LINE_FACE_ID)
2011 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2012 }
2013
2014 /* Clear IT. */
2015 bzero (it, sizeof *it);
2016 it->current.overlay_string_index = -1;
2017 it->current.dpvec_index = -1;
2018 it->base_face_id = base_face_id;
2019
2020 /* The window in which we iterate over current_buffer: */
2021 XSETWINDOW (it->window, w);
2022 it->w = w;
2023 it->f = XFRAME (w->frame);
2024
2025 /* Extra space between lines (on window systems only). */
2026 if (base_face_id == DEFAULT_FACE_ID
2027 && FRAME_WINDOW_P (it->f))
2028 {
2029 if (NATNUMP (current_buffer->extra_line_spacing))
2030 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2031 else if (it->f->extra_line_spacing > 0)
2032 it->extra_line_spacing = it->f->extra_line_spacing;
2033 }
2034
2035 /* If realized faces have been removed, e.g. because of face
2036 attribute changes of named faces, recompute them. When running
2037 in batch mode, the face cache of the initial frame is null. If
2038 we happen to get called, make a dummy face cache. */
2039 if (FRAME_FACE_CACHE (it->f) == NULL)
2040 init_frame_faces (it->f);
2041 if (FRAME_FACE_CACHE (it->f)->used == 0)
2042 recompute_basic_faces (it->f);
2043
2044 /* Current value of the `space-width', and 'height' properties. */
2045 it->space_width = Qnil;
2046 it->font_height = Qnil;
2047
2048 /* Are control characters displayed as `^C'? */
2049 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2050
2051 /* -1 means everything between a CR and the following line end
2052 is invisible. >0 means lines indented more than this value are
2053 invisible. */
2054 it->selective = (INTEGERP (current_buffer->selective_display)
2055 ? XFASTINT (current_buffer->selective_display)
2056 : (!NILP (current_buffer->selective_display)
2057 ? -1 : 0));
2058 it->selective_display_ellipsis_p
2059 = !NILP (current_buffer->selective_display_ellipses);
2060
2061 /* Display table to use. */
2062 it->dp = window_display_table (w);
2063
2064 /* Are multibyte characters enabled in current_buffer? */
2065 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2066
2067 /* Non-zero if we should highlight the region. */
2068 highlight_region_p
2069 = (!NILP (Vtransient_mark_mode)
2070 && !NILP (current_buffer->mark_active)
2071 && XMARKER (current_buffer->mark)->buffer != 0);
2072
2073 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2074 start and end of a visible region in window IT->w. Set both to
2075 -1 to indicate no region. */
2076 if (highlight_region_p
2077 /* Maybe highlight only in selected window. */
2078 && (/* Either show region everywhere. */
2079 highlight_nonselected_windows
2080 /* Or show region in the selected window. */
2081 || w == XWINDOW (selected_window)
2082 /* Or show the region if we are in the mini-buffer and W is
2083 the window the mini-buffer refers to. */
2084 || (MINI_WINDOW_P (XWINDOW (selected_window))
2085 && WINDOWP (minibuf_selected_window)
2086 && w == XWINDOW (minibuf_selected_window))))
2087 {
2088 int charpos = marker_position (current_buffer->mark);
2089 it->region_beg_charpos = min (PT, charpos);
2090 it->region_end_charpos = max (PT, charpos);
2091 }
2092 else
2093 it->region_beg_charpos = it->region_end_charpos = -1;
2094
2095 /* Get the position at which the redisplay_end_trigger hook should
2096 be run, if it is to be run at all. */
2097 if (MARKERP (w->redisplay_end_trigger)
2098 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2099 it->redisplay_end_trigger_charpos
2100 = marker_position (w->redisplay_end_trigger);
2101 else if (INTEGERP (w->redisplay_end_trigger))
2102 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2103
2104 /* Correct bogus values of tab_width. */
2105 it->tab_width = XINT (current_buffer->tab_width);
2106 if (it->tab_width <= 0 || it->tab_width > 1000)
2107 it->tab_width = 8;
2108
2109 /* Are lines in the display truncated? */
2110 it->truncate_lines_p
2111 = (base_face_id != DEFAULT_FACE_ID
2112 || XINT (it->w->hscroll)
2113 || (truncate_partial_width_windows
2114 && !WINDOW_FULL_WIDTH_P (it->w))
2115 || !NILP (current_buffer->truncate_lines));
2116
2117 /* Get dimensions of truncation and continuation glyphs. These are
2118 displayed as fringe bitmaps under X, so we don't need them for such
2119 frames. */
2120 if (!FRAME_WINDOW_P (it->f))
2121 {
2122 if (it->truncate_lines_p)
2123 {
2124 /* We will need the truncation glyph. */
2125 xassert (it->glyph_row == NULL);
2126 produce_special_glyphs (it, IT_TRUNCATION);
2127 it->truncation_pixel_width = it->pixel_width;
2128 }
2129 else
2130 {
2131 /* We will need the continuation glyph. */
2132 xassert (it->glyph_row == NULL);
2133 produce_special_glyphs (it, IT_CONTINUATION);
2134 it->continuation_pixel_width = it->pixel_width;
2135 }
2136
2137 /* Reset these values to zero because the produce_special_glyphs
2138 above has changed them. */
2139 it->pixel_width = it->ascent = it->descent = 0;
2140 it->phys_ascent = it->phys_descent = 0;
2141 }
2142
2143 /* Set this after getting the dimensions of truncation and
2144 continuation glyphs, so that we don't produce glyphs when calling
2145 produce_special_glyphs, above. */
2146 it->glyph_row = row;
2147 it->area = TEXT_AREA;
2148
2149 /* Get the dimensions of the display area. The display area
2150 consists of the visible window area plus a horizontally scrolled
2151 part to the left of the window. All x-values are relative to the
2152 start of this total display area. */
2153 if (base_face_id != DEFAULT_FACE_ID)
2154 {
2155 /* Mode lines, menu bar in terminal frames. */
2156 it->first_visible_x = 0;
2157 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2158 }
2159 else
2160 {
2161 it->first_visible_x
2162 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2163 it->last_visible_x = (it->first_visible_x
2164 + window_box_width (w, TEXT_AREA));
2165
2166 /* If we truncate lines, leave room for the truncator glyph(s) at
2167 the right margin. Otherwise, leave room for the continuation
2168 glyph(s). Truncation and continuation glyphs are not inserted
2169 for window-based redisplay. */
2170 if (!FRAME_WINDOW_P (it->f))
2171 {
2172 if (it->truncate_lines_p)
2173 it->last_visible_x -= it->truncation_pixel_width;
2174 else
2175 it->last_visible_x -= it->continuation_pixel_width;
2176 }
2177
2178 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2179 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2180 }
2181
2182 /* Leave room for a border glyph. */
2183 if (!FRAME_WINDOW_P (it->f)
2184 && !WINDOW_RIGHTMOST_P (it->w))
2185 it->last_visible_x -= 1;
2186
2187 it->last_visible_y = window_text_bottom_y (w);
2188
2189 /* For mode lines and alike, arrange for the first glyph having a
2190 left box line if the face specifies a box. */
2191 if (base_face_id != DEFAULT_FACE_ID)
2192 {
2193 struct face *face;
2194
2195 it->face_id = base_face_id;
2196
2197 /* If we have a boxed mode line, make the first character appear
2198 with a left box line. */
2199 face = FACE_FROM_ID (it->f, base_face_id);
2200 if (face->box != FACE_NO_BOX)
2201 it->start_of_box_run_p = 1;
2202 }
2203
2204 /* If a buffer position was specified, set the iterator there,
2205 getting overlays and face properties from that position. */
2206 if (charpos >= BUF_BEG (current_buffer))
2207 {
2208 it->end_charpos = ZV;
2209 it->face_id = -1;
2210 IT_CHARPOS (*it) = charpos;
2211
2212 /* Compute byte position if not specified. */
2213 if (bytepos < charpos)
2214 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2215 else
2216 IT_BYTEPOS (*it) = bytepos;
2217
2218 it->start = it->current;
2219
2220 /* Compute faces etc. */
2221 reseat (it, it->current.pos, 1);
2222 }
2223
2224 CHECK_IT (it);
2225 }
2226
2227
2228 /* Initialize IT for the display of window W with window start POS. */
2229
2230 void
2231 start_display (it, w, pos)
2232 struct it *it;
2233 struct window *w;
2234 struct text_pos pos;
2235 {
2236 struct glyph_row *row;
2237 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2238
2239 row = w->desired_matrix->rows + first_vpos;
2240 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2241 it->first_vpos = first_vpos;
2242
2243 if (!it->truncate_lines_p)
2244 {
2245 int start_at_line_beg_p;
2246 int first_y = it->current_y;
2247
2248 /* If window start is not at a line start, skip forward to POS to
2249 get the correct continuation lines width. */
2250 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2251 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2252 if (!start_at_line_beg_p)
2253 {
2254 int new_x;
2255
2256 reseat_at_previous_visible_line_start (it);
2257 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2258
2259 new_x = it->current_x + it->pixel_width;
2260
2261 /* If lines are continued, this line may end in the middle
2262 of a multi-glyph character (e.g. a control character
2263 displayed as \003, or in the middle of an overlay
2264 string). In this case move_it_to above will not have
2265 taken us to the start of the continuation line but to the
2266 end of the continued line. */
2267 if (it->current_x > 0
2268 && !it->truncate_lines_p /* Lines are continued. */
2269 && (/* And glyph doesn't fit on the line. */
2270 new_x > it->last_visible_x
2271 /* Or it fits exactly and we're on a window
2272 system frame. */
2273 || (new_x == it->last_visible_x
2274 && FRAME_WINDOW_P (it->f))))
2275 {
2276 if (it->current.dpvec_index >= 0
2277 || it->current.overlay_string_index >= 0)
2278 {
2279 set_iterator_to_next (it, 1);
2280 move_it_in_display_line_to (it, -1, -1, 0);
2281 }
2282
2283 it->continuation_lines_width += it->current_x;
2284 }
2285
2286 /* We're starting a new display line, not affected by the
2287 height of the continued line, so clear the appropriate
2288 fields in the iterator structure. */
2289 it->max_ascent = it->max_descent = 0;
2290 it->max_phys_ascent = it->max_phys_descent = 0;
2291
2292 it->current_y = first_y;
2293 it->vpos = 0;
2294 it->current_x = it->hpos = 0;
2295 }
2296 }
2297
2298 #if 0 /* Don't assert the following because start_display is sometimes
2299 called intentionally with a window start that is not at a
2300 line start. Please leave this code in as a comment. */
2301
2302 /* Window start should be on a line start, now. */
2303 xassert (it->continuation_lines_width
2304 || IT_CHARPOS (it) == BEGV
2305 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2306 #endif /* 0 */
2307 }
2308
2309
2310 /* Return 1 if POS is a position in ellipses displayed for invisible
2311 text. W is the window we display, for text property lookup. */
2312
2313 static int
2314 in_ellipses_for_invisible_text_p (pos, w)
2315 struct display_pos *pos;
2316 struct window *w;
2317 {
2318 Lisp_Object prop, window;
2319 int ellipses_p = 0;
2320 int charpos = CHARPOS (pos->pos);
2321
2322 /* If POS specifies a position in a display vector, this might
2323 be for an ellipsis displayed for invisible text. We won't
2324 get the iterator set up for delivering that ellipsis unless
2325 we make sure that it gets aware of the invisible text. */
2326 if (pos->dpvec_index >= 0
2327 && pos->overlay_string_index < 0
2328 && CHARPOS (pos->string_pos) < 0
2329 && charpos > BEGV
2330 && (XSETWINDOW (window, w),
2331 prop = Fget_char_property (make_number (charpos),
2332 Qinvisible, window),
2333 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2334 {
2335 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2336 window);
2337 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2338 }
2339
2340 return ellipses_p;
2341 }
2342
2343
2344 /* Initialize IT for stepping through current_buffer in window W,
2345 starting at position POS that includes overlay string and display
2346 vector/ control character translation position information. Value
2347 is zero if there are overlay strings with newlines at POS. */
2348
2349 static int
2350 init_from_display_pos (it, w, pos)
2351 struct it *it;
2352 struct window *w;
2353 struct display_pos *pos;
2354 {
2355 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2356 int i, overlay_strings_with_newlines = 0;
2357
2358 /* If POS specifies a position in a display vector, this might
2359 be for an ellipsis displayed for invisible text. We won't
2360 get the iterator set up for delivering that ellipsis unless
2361 we make sure that it gets aware of the invisible text. */
2362 if (in_ellipses_for_invisible_text_p (pos, w))
2363 {
2364 --charpos;
2365 bytepos = 0;
2366 }
2367
2368 /* Keep in mind: the call to reseat in init_iterator skips invisible
2369 text, so we might end up at a position different from POS. This
2370 is only a problem when POS is a row start after a newline and an
2371 overlay starts there with an after-string, and the overlay has an
2372 invisible property. Since we don't skip invisible text in
2373 display_line and elsewhere immediately after consuming the
2374 newline before the row start, such a POS will not be in a string,
2375 but the call to init_iterator below will move us to the
2376 after-string. */
2377 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2378
2379 for (i = 0; i < it->n_overlay_strings; ++i)
2380 {
2381 const char *s = SDATA (it->overlay_strings[i]);
2382 const char *e = s + SBYTES (it->overlay_strings[i]);
2383
2384 while (s < e && *s != '\n')
2385 ++s;
2386
2387 if (s < e)
2388 {
2389 overlay_strings_with_newlines = 1;
2390 break;
2391 }
2392 }
2393
2394 /* If position is within an overlay string, set up IT to the right
2395 overlay string. */
2396 if (pos->overlay_string_index >= 0)
2397 {
2398 int relative_index;
2399
2400 /* If the first overlay string happens to have a `display'
2401 property for an image, the iterator will be set up for that
2402 image, and we have to undo that setup first before we can
2403 correct the overlay string index. */
2404 if (it->method == next_element_from_image)
2405 pop_it (it);
2406
2407 /* We already have the first chunk of overlay strings in
2408 IT->overlay_strings. Load more until the one for
2409 pos->overlay_string_index is in IT->overlay_strings. */
2410 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2411 {
2412 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2413 it->current.overlay_string_index = 0;
2414 while (n--)
2415 {
2416 load_overlay_strings (it, 0);
2417 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2418 }
2419 }
2420
2421 it->current.overlay_string_index = pos->overlay_string_index;
2422 relative_index = (it->current.overlay_string_index
2423 % OVERLAY_STRING_CHUNK_SIZE);
2424 it->string = it->overlay_strings[relative_index];
2425 xassert (STRINGP (it->string));
2426 it->current.string_pos = pos->string_pos;
2427 it->method = next_element_from_string;
2428 }
2429
2430 #if 0 /* This is bogus because POS not having an overlay string
2431 position does not mean it's after the string. Example: A
2432 line starting with a before-string and initialization of IT
2433 to the previous row's end position. */
2434 else if (it->current.overlay_string_index >= 0)
2435 {
2436 /* If POS says we're already after an overlay string ending at
2437 POS, make sure to pop the iterator because it will be in
2438 front of that overlay string. When POS is ZV, we've thereby
2439 also ``processed'' overlay strings at ZV. */
2440 while (it->sp)
2441 pop_it (it);
2442 it->current.overlay_string_index = -1;
2443 it->method = next_element_from_buffer;
2444 if (CHARPOS (pos->pos) == ZV)
2445 it->overlay_strings_at_end_processed_p = 1;
2446 }
2447 #endif /* 0 */
2448
2449 if (CHARPOS (pos->string_pos) >= 0)
2450 {
2451 /* Recorded position is not in an overlay string, but in another
2452 string. This can only be a string from a `display' property.
2453 IT should already be filled with that string. */
2454 it->current.string_pos = pos->string_pos;
2455 xassert (STRINGP (it->string));
2456 }
2457
2458 /* Restore position in display vector translations, control
2459 character translations or ellipses. */
2460 if (pos->dpvec_index >= 0)
2461 {
2462 if (it->dpvec == NULL)
2463 get_next_display_element (it);
2464 xassert (it->dpvec && it->current.dpvec_index == 0);
2465 it->current.dpvec_index = pos->dpvec_index;
2466 }
2467
2468 CHECK_IT (it);
2469 return !overlay_strings_with_newlines;
2470 }
2471
2472
2473 /* Initialize IT for stepping through current_buffer in window W
2474 starting at ROW->start. */
2475
2476 static void
2477 init_to_row_start (it, w, row)
2478 struct it *it;
2479 struct window *w;
2480 struct glyph_row *row;
2481 {
2482 init_from_display_pos (it, w, &row->start);
2483 it->start = row->start;
2484 it->continuation_lines_width = row->continuation_lines_width;
2485 CHECK_IT (it);
2486 }
2487
2488
2489 /* Initialize IT for stepping through current_buffer in window W
2490 starting in the line following ROW, i.e. starting at ROW->end.
2491 Value is zero if there are overlay strings with newlines at ROW's
2492 end position. */
2493
2494 static int
2495 init_to_row_end (it, w, row)
2496 struct it *it;
2497 struct window *w;
2498 struct glyph_row *row;
2499 {
2500 int success = 0;
2501
2502 if (init_from_display_pos (it, w, &row->end))
2503 {
2504 if (row->continued_p)
2505 it->continuation_lines_width
2506 = row->continuation_lines_width + row->pixel_width;
2507 CHECK_IT (it);
2508 success = 1;
2509 }
2510
2511 return success;
2512 }
2513
2514
2515
2516 \f
2517 /***********************************************************************
2518 Text properties
2519 ***********************************************************************/
2520
2521 /* Called when IT reaches IT->stop_charpos. Handle text property and
2522 overlay changes. Set IT->stop_charpos to the next position where
2523 to stop. */
2524
2525 static void
2526 handle_stop (it)
2527 struct it *it;
2528 {
2529 enum prop_handled handled;
2530 int handle_overlay_change_p = 1;
2531 struct props *p;
2532
2533 it->dpvec = NULL;
2534 it->current.dpvec_index = -1;
2535
2536 do
2537 {
2538 handled = HANDLED_NORMALLY;
2539
2540 /* Call text property handlers. */
2541 for (p = it_props; p->handler; ++p)
2542 {
2543 handled = p->handler (it);
2544
2545 if (handled == HANDLED_RECOMPUTE_PROPS)
2546 break;
2547 else if (handled == HANDLED_RETURN)
2548 return;
2549 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2550 handle_overlay_change_p = 0;
2551 }
2552
2553 if (handled != HANDLED_RECOMPUTE_PROPS)
2554 {
2555 /* Don't check for overlay strings below when set to deliver
2556 characters from a display vector. */
2557 if (it->method == next_element_from_display_vector)
2558 handle_overlay_change_p = 0;
2559
2560 /* Handle overlay changes. */
2561 if (handle_overlay_change_p)
2562 handled = handle_overlay_change (it);
2563
2564 /* Determine where to stop next. */
2565 if (handled == HANDLED_NORMALLY)
2566 compute_stop_pos (it);
2567 }
2568 }
2569 while (handled == HANDLED_RECOMPUTE_PROPS);
2570 }
2571
2572
2573 /* Compute IT->stop_charpos from text property and overlay change
2574 information for IT's current position. */
2575
2576 static void
2577 compute_stop_pos (it)
2578 struct it *it;
2579 {
2580 register INTERVAL iv, next_iv;
2581 Lisp_Object object, limit, position;
2582
2583 /* If nowhere else, stop at the end. */
2584 it->stop_charpos = it->end_charpos;
2585
2586 if (STRINGP (it->string))
2587 {
2588 /* Strings are usually short, so don't limit the search for
2589 properties. */
2590 object = it->string;
2591 limit = Qnil;
2592 position = make_number (IT_STRING_CHARPOS (*it));
2593 }
2594 else
2595 {
2596 int charpos;
2597
2598 /* If next overlay change is in front of the current stop pos
2599 (which is IT->end_charpos), stop there. Note: value of
2600 next_overlay_change is point-max if no overlay change
2601 follows. */
2602 charpos = next_overlay_change (IT_CHARPOS (*it));
2603 if (charpos < it->stop_charpos)
2604 it->stop_charpos = charpos;
2605
2606 /* If showing the region, we have to stop at the region
2607 start or end because the face might change there. */
2608 if (it->region_beg_charpos > 0)
2609 {
2610 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2611 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2612 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2613 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2614 }
2615
2616 /* Set up variables for computing the stop position from text
2617 property changes. */
2618 XSETBUFFER (object, current_buffer);
2619 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2620 position = make_number (IT_CHARPOS (*it));
2621
2622 }
2623
2624 /* Get the interval containing IT's position. Value is a null
2625 interval if there isn't such an interval. */
2626 iv = validate_interval_range (object, &position, &position, 0);
2627 if (!NULL_INTERVAL_P (iv))
2628 {
2629 Lisp_Object values_here[LAST_PROP_IDX];
2630 struct props *p;
2631
2632 /* Get properties here. */
2633 for (p = it_props; p->handler; ++p)
2634 values_here[p->idx] = textget (iv->plist, *p->name);
2635
2636 /* Look for an interval following iv that has different
2637 properties. */
2638 for (next_iv = next_interval (iv);
2639 (!NULL_INTERVAL_P (next_iv)
2640 && (NILP (limit)
2641 || XFASTINT (limit) > next_iv->position));
2642 next_iv = next_interval (next_iv))
2643 {
2644 for (p = it_props; p->handler; ++p)
2645 {
2646 Lisp_Object new_value;
2647
2648 new_value = textget (next_iv->plist, *p->name);
2649 if (!EQ (values_here[p->idx], new_value))
2650 break;
2651 }
2652
2653 if (p->handler)
2654 break;
2655 }
2656
2657 if (!NULL_INTERVAL_P (next_iv))
2658 {
2659 if (INTEGERP (limit)
2660 && next_iv->position >= XFASTINT (limit))
2661 /* No text property change up to limit. */
2662 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2663 else
2664 /* Text properties change in next_iv. */
2665 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2666 }
2667 }
2668
2669 xassert (STRINGP (it->string)
2670 || (it->stop_charpos >= BEGV
2671 && it->stop_charpos >= IT_CHARPOS (*it)));
2672 }
2673
2674
2675 /* Return the position of the next overlay change after POS in
2676 current_buffer. Value is point-max if no overlay change
2677 follows. This is like `next-overlay-change' but doesn't use
2678 xmalloc. */
2679
2680 static int
2681 next_overlay_change (pos)
2682 int pos;
2683 {
2684 int noverlays;
2685 int endpos;
2686 Lisp_Object *overlays;
2687 int len;
2688 int i;
2689
2690 /* Get all overlays at the given position. */
2691 len = 10;
2692 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2693 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2694 if (noverlays > len)
2695 {
2696 len = noverlays;
2697 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2698 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2699 }
2700
2701 /* If any of these overlays ends before endpos,
2702 use its ending point instead. */
2703 for (i = 0; i < noverlays; ++i)
2704 {
2705 Lisp_Object oend;
2706 int oendpos;
2707
2708 oend = OVERLAY_END (overlays[i]);
2709 oendpos = OVERLAY_POSITION (oend);
2710 endpos = min (endpos, oendpos);
2711 }
2712
2713 return endpos;
2714 }
2715
2716
2717 \f
2718 /***********************************************************************
2719 Fontification
2720 ***********************************************************************/
2721
2722 /* Handle changes in the `fontified' property of the current buffer by
2723 calling hook functions from Qfontification_functions to fontify
2724 regions of text. */
2725
2726 static enum prop_handled
2727 handle_fontified_prop (it)
2728 struct it *it;
2729 {
2730 Lisp_Object prop, pos;
2731 enum prop_handled handled = HANDLED_NORMALLY;
2732
2733 /* Get the value of the `fontified' property at IT's current buffer
2734 position. (The `fontified' property doesn't have a special
2735 meaning in strings.) If the value is nil, call functions from
2736 Qfontification_functions. */
2737 if (!STRINGP (it->string)
2738 && it->s == NULL
2739 && !NILP (Vfontification_functions)
2740 && !NILP (Vrun_hooks)
2741 && (pos = make_number (IT_CHARPOS (*it)),
2742 prop = Fget_char_property (pos, Qfontified, Qnil),
2743 NILP (prop)))
2744 {
2745 int count = SPECPDL_INDEX ();
2746 Lisp_Object val;
2747
2748 val = Vfontification_functions;
2749 specbind (Qfontification_functions, Qnil);
2750
2751 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2752 safe_call1 (val, pos);
2753 else
2754 {
2755 Lisp_Object globals, fn;
2756 struct gcpro gcpro1, gcpro2;
2757
2758 globals = Qnil;
2759 GCPRO2 (val, globals);
2760
2761 for (; CONSP (val); val = XCDR (val))
2762 {
2763 fn = XCAR (val);
2764
2765 if (EQ (fn, Qt))
2766 {
2767 /* A value of t indicates this hook has a local
2768 binding; it means to run the global binding too.
2769 In a global value, t should not occur. If it
2770 does, we must ignore it to avoid an endless
2771 loop. */
2772 for (globals = Fdefault_value (Qfontification_functions);
2773 CONSP (globals);
2774 globals = XCDR (globals))
2775 {
2776 fn = XCAR (globals);
2777 if (!EQ (fn, Qt))
2778 safe_call1 (fn, pos);
2779 }
2780 }
2781 else
2782 safe_call1 (fn, pos);
2783 }
2784
2785 UNGCPRO;
2786 }
2787
2788 unbind_to (count, Qnil);
2789
2790 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2791 something. This avoids an endless loop if they failed to
2792 fontify the text for which reason ever. */
2793 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2794 handled = HANDLED_RECOMPUTE_PROPS;
2795 }
2796
2797 return handled;
2798 }
2799
2800
2801 \f
2802 /***********************************************************************
2803 Faces
2804 ***********************************************************************/
2805
2806 /* Set up iterator IT from face properties at its current position.
2807 Called from handle_stop. */
2808
2809 static enum prop_handled
2810 handle_face_prop (it)
2811 struct it *it;
2812 {
2813 int new_face_id, next_stop;
2814
2815 if (!STRINGP (it->string))
2816 {
2817 new_face_id
2818 = face_at_buffer_position (it->w,
2819 IT_CHARPOS (*it),
2820 it->region_beg_charpos,
2821 it->region_end_charpos,
2822 &next_stop,
2823 (IT_CHARPOS (*it)
2824 + TEXT_PROP_DISTANCE_LIMIT),
2825 0);
2826
2827 /* Is this a start of a run of characters with box face?
2828 Caveat: this can be called for a freshly initialized
2829 iterator; face_id is -1 in this case. We know that the new
2830 face will not change until limit, i.e. if the new face has a
2831 box, all characters up to limit will have one. But, as
2832 usual, we don't know whether limit is really the end. */
2833 if (new_face_id != it->face_id)
2834 {
2835 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2836
2837 /* If new face has a box but old face has not, this is
2838 the start of a run of characters with box, i.e. it has
2839 a shadow on the left side. The value of face_id of the
2840 iterator will be -1 if this is the initial call that gets
2841 the face. In this case, we have to look in front of IT's
2842 position and see whether there is a face != new_face_id. */
2843 it->start_of_box_run_p
2844 = (new_face->box != FACE_NO_BOX
2845 && (it->face_id >= 0
2846 || IT_CHARPOS (*it) == BEG
2847 || new_face_id != face_before_it_pos (it)));
2848 it->face_box_p = new_face->box != FACE_NO_BOX;
2849 }
2850 }
2851 else
2852 {
2853 int base_face_id, bufpos;
2854
2855 if (it->current.overlay_string_index >= 0)
2856 bufpos = IT_CHARPOS (*it);
2857 else
2858 bufpos = 0;
2859
2860 /* For strings from a buffer, i.e. overlay strings or strings
2861 from a `display' property, use the face at IT's current
2862 buffer position as the base face to merge with, so that
2863 overlay strings appear in the same face as surrounding
2864 text, unless they specify their own faces. */
2865 base_face_id = underlying_face_id (it);
2866
2867 new_face_id = face_at_string_position (it->w,
2868 it->string,
2869 IT_STRING_CHARPOS (*it),
2870 bufpos,
2871 it->region_beg_charpos,
2872 it->region_end_charpos,
2873 &next_stop,
2874 base_face_id, 0);
2875
2876 #if 0 /* This shouldn't be neccessary. Let's check it. */
2877 /* If IT is used to display a mode line we would really like to
2878 use the mode line face instead of the frame's default face. */
2879 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2880 && new_face_id == DEFAULT_FACE_ID)
2881 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2882 #endif
2883
2884 /* Is this a start of a run of characters with box? Caveat:
2885 this can be called for a freshly allocated iterator; face_id
2886 is -1 is this case. We know that the new face will not
2887 change until the next check pos, i.e. if the new face has a
2888 box, all characters up to that position will have a
2889 box. But, as usual, we don't know whether that position
2890 is really the end. */
2891 if (new_face_id != it->face_id)
2892 {
2893 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2894 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2895
2896 /* If new face has a box but old face hasn't, this is the
2897 start of a run of characters with box, i.e. it has a
2898 shadow on the left side. */
2899 it->start_of_box_run_p
2900 = new_face->box && (old_face == NULL || !old_face->box);
2901 it->face_box_p = new_face->box != FACE_NO_BOX;
2902 }
2903 }
2904
2905 it->face_id = new_face_id;
2906 return HANDLED_NORMALLY;
2907 }
2908
2909
2910 /* Return the ID of the face ``underlying'' IT's current position,
2911 which is in a string. If the iterator is associated with a
2912 buffer, return the face at IT's current buffer position.
2913 Otherwise, use the iterator's base_face_id. */
2914
2915 static int
2916 underlying_face_id (it)
2917 struct it *it;
2918 {
2919 int face_id = it->base_face_id, i;
2920
2921 xassert (STRINGP (it->string));
2922
2923 for (i = it->sp - 1; i >= 0; --i)
2924 if (NILP (it->stack[i].string))
2925 face_id = it->stack[i].face_id;
2926
2927 return face_id;
2928 }
2929
2930
2931 /* Compute the face one character before or after the current position
2932 of IT. BEFORE_P non-zero means get the face in front of IT's
2933 position. Value is the id of the face. */
2934
2935 static int
2936 face_before_or_after_it_pos (it, before_p)
2937 struct it *it;
2938 int before_p;
2939 {
2940 int face_id, limit;
2941 int next_check_charpos;
2942 struct text_pos pos;
2943
2944 xassert (it->s == NULL);
2945
2946 if (STRINGP (it->string))
2947 {
2948 int bufpos, base_face_id;
2949
2950 /* No face change past the end of the string (for the case
2951 we are padding with spaces). No face change before the
2952 string start. */
2953 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2954 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2955 return it->face_id;
2956
2957 /* Set pos to the position before or after IT's current position. */
2958 if (before_p)
2959 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2960 else
2961 /* For composition, we must check the character after the
2962 composition. */
2963 pos = (it->what == IT_COMPOSITION
2964 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2965 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2966
2967 if (it->current.overlay_string_index >= 0)
2968 bufpos = IT_CHARPOS (*it);
2969 else
2970 bufpos = 0;
2971
2972 base_face_id = underlying_face_id (it);
2973
2974 /* Get the face for ASCII, or unibyte. */
2975 face_id = face_at_string_position (it->w,
2976 it->string,
2977 CHARPOS (pos),
2978 bufpos,
2979 it->region_beg_charpos,
2980 it->region_end_charpos,
2981 &next_check_charpos,
2982 base_face_id, 0);
2983
2984 /* Correct the face for charsets different from ASCII. Do it
2985 for the multibyte case only. The face returned above is
2986 suitable for unibyte text if IT->string is unibyte. */
2987 if (STRING_MULTIBYTE (it->string))
2988 {
2989 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2990 int rest = SBYTES (it->string) - BYTEPOS (pos);
2991 int c, len;
2992 struct face *face = FACE_FROM_ID (it->f, face_id);
2993
2994 c = string_char_and_length (p, rest, &len);
2995 face_id = FACE_FOR_CHAR (it->f, face, c);
2996 }
2997 }
2998 else
2999 {
3000 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3001 || (IT_CHARPOS (*it) <= BEGV && before_p))
3002 return it->face_id;
3003
3004 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3005 pos = it->current.pos;
3006
3007 if (before_p)
3008 DEC_TEXT_POS (pos, it->multibyte_p);
3009 else
3010 {
3011 if (it->what == IT_COMPOSITION)
3012 /* For composition, we must check the position after the
3013 composition. */
3014 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3015 else
3016 INC_TEXT_POS (pos, it->multibyte_p);
3017 }
3018
3019 /* Determine face for CHARSET_ASCII, or unibyte. */
3020 face_id = face_at_buffer_position (it->w,
3021 CHARPOS (pos),
3022 it->region_beg_charpos,
3023 it->region_end_charpos,
3024 &next_check_charpos,
3025 limit, 0);
3026
3027 /* Correct the face for charsets different from ASCII. Do it
3028 for the multibyte case only. The face returned above is
3029 suitable for unibyte text if current_buffer is unibyte. */
3030 if (it->multibyte_p)
3031 {
3032 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3033 struct face *face = FACE_FROM_ID (it->f, face_id);
3034 face_id = FACE_FOR_CHAR (it->f, face, c);
3035 }
3036 }
3037
3038 return face_id;
3039 }
3040
3041
3042 \f
3043 /***********************************************************************
3044 Invisible text
3045 ***********************************************************************/
3046
3047 /* Set up iterator IT from invisible properties at its current
3048 position. Called from handle_stop. */
3049
3050 static enum prop_handled
3051 handle_invisible_prop (it)
3052 struct it *it;
3053 {
3054 enum prop_handled handled = HANDLED_NORMALLY;
3055
3056 if (STRINGP (it->string))
3057 {
3058 extern Lisp_Object Qinvisible;
3059 Lisp_Object prop, end_charpos, limit, charpos;
3060
3061 /* Get the value of the invisible text property at the
3062 current position. Value will be nil if there is no such
3063 property. */
3064 charpos = make_number (IT_STRING_CHARPOS (*it));
3065 prop = Fget_text_property (charpos, Qinvisible, it->string);
3066
3067 if (!NILP (prop)
3068 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3069 {
3070 handled = HANDLED_RECOMPUTE_PROPS;
3071
3072 /* Get the position at which the next change of the
3073 invisible text property can be found in IT->string.
3074 Value will be nil if the property value is the same for
3075 all the rest of IT->string. */
3076 XSETINT (limit, SCHARS (it->string));
3077 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3078 it->string, limit);
3079
3080 /* Text at current position is invisible. The next
3081 change in the property is at position end_charpos.
3082 Move IT's current position to that position. */
3083 if (INTEGERP (end_charpos)
3084 && XFASTINT (end_charpos) < XFASTINT (limit))
3085 {
3086 struct text_pos old;
3087 old = it->current.string_pos;
3088 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3089 compute_string_pos (&it->current.string_pos, old, it->string);
3090 }
3091 else
3092 {
3093 /* The rest of the string is invisible. If this is an
3094 overlay string, proceed with the next overlay string
3095 or whatever comes and return a character from there. */
3096 if (it->current.overlay_string_index >= 0)
3097 {
3098 next_overlay_string (it);
3099 /* Don't check for overlay strings when we just
3100 finished processing them. */
3101 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3102 }
3103 else
3104 {
3105 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3106 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3107 }
3108 }
3109 }
3110 }
3111 else
3112 {
3113 int invis_p, newpos, next_stop, start_charpos;
3114 Lisp_Object pos, prop, overlay;
3115
3116 /* First of all, is there invisible text at this position? */
3117 start_charpos = IT_CHARPOS (*it);
3118 pos = make_number (IT_CHARPOS (*it));
3119 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3120 &overlay);
3121 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3122
3123 /* If we are on invisible text, skip over it. */
3124 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3125 {
3126 /* Record whether we have to display an ellipsis for the
3127 invisible text. */
3128 int display_ellipsis_p = invis_p == 2;
3129
3130 handled = HANDLED_RECOMPUTE_PROPS;
3131
3132 /* Loop skipping over invisible text. The loop is left at
3133 ZV or with IT on the first char being visible again. */
3134 do
3135 {
3136 /* Try to skip some invisible text. Return value is the
3137 position reached which can be equal to IT's position
3138 if there is nothing invisible here. This skips both
3139 over invisible text properties and overlays with
3140 invisible property. */
3141 newpos = skip_invisible (IT_CHARPOS (*it),
3142 &next_stop, ZV, it->window);
3143
3144 /* If we skipped nothing at all we weren't at invisible
3145 text in the first place. If everything to the end of
3146 the buffer was skipped, end the loop. */
3147 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3148 invis_p = 0;
3149 else
3150 {
3151 /* We skipped some characters but not necessarily
3152 all there are. Check if we ended up on visible
3153 text. Fget_char_property returns the property of
3154 the char before the given position, i.e. if we
3155 get invis_p = 0, this means that the char at
3156 newpos is visible. */
3157 pos = make_number (newpos);
3158 prop = Fget_char_property (pos, Qinvisible, it->window);
3159 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3160 }
3161
3162 /* If we ended up on invisible text, proceed to
3163 skip starting with next_stop. */
3164 if (invis_p)
3165 IT_CHARPOS (*it) = next_stop;
3166 }
3167 while (invis_p);
3168
3169 /* The position newpos is now either ZV or on visible text. */
3170 IT_CHARPOS (*it) = newpos;
3171 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3172
3173 /* If there are before-strings at the start of invisible
3174 text, and the text is invisible because of a text
3175 property, arrange to show before-strings because 20.x did
3176 it that way. (If the text is invisible because of an
3177 overlay property instead of a text property, this is
3178 already handled in the overlay code.) */
3179 if (NILP (overlay)
3180 && get_overlay_strings (it, start_charpos))
3181 {
3182 handled = HANDLED_RECOMPUTE_PROPS;
3183 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3184 }
3185 else if (display_ellipsis_p)
3186 setup_for_ellipsis (it);
3187 }
3188 }
3189
3190 return handled;
3191 }
3192
3193
3194 /* Make iterator IT return `...' next. */
3195
3196 static void
3197 setup_for_ellipsis (it)
3198 struct it *it;
3199 {
3200 if (it->dp
3201 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3202 {
3203 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3204 it->dpvec = v->contents;
3205 it->dpend = v->contents + v->size;
3206 }
3207 else
3208 {
3209 /* Default `...'. */
3210 it->dpvec = default_invis_vector;
3211 it->dpend = default_invis_vector + 3;
3212 }
3213
3214 /* The ellipsis display does not replace the display of the
3215 character at the new position. Indicate this by setting
3216 IT->dpvec_char_len to zero. */
3217 it->dpvec_char_len = 0;
3218
3219 it->current.dpvec_index = 0;
3220 it->method = next_element_from_display_vector;
3221 }
3222
3223
3224 \f
3225 /***********************************************************************
3226 'display' property
3227 ***********************************************************************/
3228
3229 /* Set up iterator IT from `display' property at its current position.
3230 Called from handle_stop. */
3231
3232 static enum prop_handled
3233 handle_display_prop (it)
3234 struct it *it;
3235 {
3236 Lisp_Object prop, object;
3237 struct text_pos *position;
3238 int display_replaced_p = 0;
3239
3240 if (STRINGP (it->string))
3241 {
3242 object = it->string;
3243 position = &it->current.string_pos;
3244 }
3245 else
3246 {
3247 object = it->w->buffer;
3248 position = &it->current.pos;
3249 }
3250
3251 /* Reset those iterator values set from display property values. */
3252 it->font_height = Qnil;
3253 it->space_width = Qnil;
3254 it->voffset = 0;
3255
3256 /* We don't support recursive `display' properties, i.e. string
3257 values that have a string `display' property, that have a string
3258 `display' property etc. */
3259 if (!it->string_from_display_prop_p)
3260 it->area = TEXT_AREA;
3261
3262 prop = Fget_char_property (make_number (position->charpos),
3263 Qdisplay, object);
3264 if (NILP (prop))
3265 return HANDLED_NORMALLY;
3266
3267 if (CONSP (prop)
3268 /* Simple properties. */
3269 && !EQ (XCAR (prop), Qimage)
3270 && !EQ (XCAR (prop), Qspace)
3271 && !EQ (XCAR (prop), Qwhen)
3272 && !EQ (XCAR (prop), Qspace_width)
3273 && !EQ (XCAR (prop), Qheight)
3274 && !EQ (XCAR (prop), Qraise)
3275 /* Marginal area specifications. */
3276 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3277 && !EQ (XCAR (prop), Qleft_fringe)
3278 && !EQ (XCAR (prop), Qright_fringe)
3279 && !NILP (XCAR (prop)))
3280 {
3281 for (; CONSP (prop); prop = XCDR (prop))
3282 {
3283 if (handle_single_display_prop (it, XCAR (prop), object,
3284 position, display_replaced_p))
3285 display_replaced_p = 1;
3286 }
3287 }
3288 else if (VECTORP (prop))
3289 {
3290 int i;
3291 for (i = 0; i < ASIZE (prop); ++i)
3292 if (handle_single_display_prop (it, AREF (prop, i), object,
3293 position, display_replaced_p))
3294 display_replaced_p = 1;
3295 }
3296 else
3297 {
3298 if (handle_single_display_prop (it, prop, object, position, 0))
3299 display_replaced_p = 1;
3300 }
3301
3302 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3303 }
3304
3305
3306 /* Value is the position of the end of the `display' property starting
3307 at START_POS in OBJECT. */
3308
3309 static struct text_pos
3310 display_prop_end (it, object, start_pos)
3311 struct it *it;
3312 Lisp_Object object;
3313 struct text_pos start_pos;
3314 {
3315 Lisp_Object end;
3316 struct text_pos end_pos;
3317
3318 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3319 Qdisplay, object, Qnil);
3320 CHARPOS (end_pos) = XFASTINT (end);
3321 if (STRINGP (object))
3322 compute_string_pos (&end_pos, start_pos, it->string);
3323 else
3324 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3325
3326 return end_pos;
3327 }
3328
3329
3330 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3331 is the object in which the `display' property was found. *POSITION
3332 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3333 means that we previously saw a display sub-property which already
3334 replaced text display with something else, for example an image;
3335 ignore such properties after the first one has been processed.
3336
3337 If PROP is a `space' or `image' sub-property, set *POSITION to the
3338 end position of the `display' property.
3339
3340 Value is non-zero if something was found which replaces the display
3341 of buffer or string text. */
3342
3343 static int
3344 handle_single_display_prop (it, prop, object, position,
3345 display_replaced_before_p)
3346 struct it *it;
3347 Lisp_Object prop;
3348 Lisp_Object object;
3349 struct text_pos *position;
3350 int display_replaced_before_p;
3351 {
3352 Lisp_Object value;
3353 int replaces_text_display_p = 0;
3354 Lisp_Object form;
3355
3356 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3357 evaluated. If the result is nil, VALUE is ignored. */
3358 form = Qt;
3359 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3360 {
3361 prop = XCDR (prop);
3362 if (!CONSP (prop))
3363 return 0;
3364 form = XCAR (prop);
3365 prop = XCDR (prop);
3366 }
3367
3368 if (!NILP (form) && !EQ (form, Qt))
3369 {
3370 int count = SPECPDL_INDEX ();
3371 struct gcpro gcpro1;
3372
3373 /* Bind `object' to the object having the `display' property, a
3374 buffer or string. Bind `position' to the position in the
3375 object where the property was found, and `buffer-position'
3376 to the current position in the buffer. */
3377 specbind (Qobject, object);
3378 specbind (Qposition, make_number (CHARPOS (*position)));
3379 specbind (Qbuffer_position,
3380 make_number (STRINGP (object)
3381 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3382 GCPRO1 (form);
3383 form = safe_eval (form);
3384 UNGCPRO;
3385 unbind_to (count, Qnil);
3386 }
3387
3388 if (NILP (form))
3389 return 0;
3390
3391 if (CONSP (prop)
3392 && EQ (XCAR (prop), Qheight)
3393 && CONSP (XCDR (prop)))
3394 {
3395 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3396 return 0;
3397
3398 /* `(height HEIGHT)'. */
3399 it->font_height = XCAR (XCDR (prop));
3400 if (!NILP (it->font_height))
3401 {
3402 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3403 int new_height = -1;
3404
3405 if (CONSP (it->font_height)
3406 && (EQ (XCAR (it->font_height), Qplus)
3407 || EQ (XCAR (it->font_height), Qminus))
3408 && CONSP (XCDR (it->font_height))
3409 && INTEGERP (XCAR (XCDR (it->font_height))))
3410 {
3411 /* `(+ N)' or `(- N)' where N is an integer. */
3412 int steps = XINT (XCAR (XCDR (it->font_height)));
3413 if (EQ (XCAR (it->font_height), Qplus))
3414 steps = - steps;
3415 it->face_id = smaller_face (it->f, it->face_id, steps);
3416 }
3417 else if (FUNCTIONP (it->font_height))
3418 {
3419 /* Call function with current height as argument.
3420 Value is the new height. */
3421 Lisp_Object height;
3422 height = safe_call1 (it->font_height,
3423 face->lface[LFACE_HEIGHT_INDEX]);
3424 if (NUMBERP (height))
3425 new_height = XFLOATINT (height);
3426 }
3427 else if (NUMBERP (it->font_height))
3428 {
3429 /* Value is a multiple of the canonical char height. */
3430 struct face *face;
3431
3432 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3433 new_height = (XFLOATINT (it->font_height)
3434 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3435 }
3436 else
3437 {
3438 /* Evaluate IT->font_height with `height' bound to the
3439 current specified height to get the new height. */
3440 Lisp_Object value;
3441 int count = SPECPDL_INDEX ();
3442
3443 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3444 value = safe_eval (it->font_height);
3445 unbind_to (count, Qnil);
3446
3447 if (NUMBERP (value))
3448 new_height = XFLOATINT (value);
3449 }
3450
3451 if (new_height > 0)
3452 it->face_id = face_with_height (it->f, it->face_id, new_height);
3453 }
3454 }
3455 else if (CONSP (prop)
3456 && EQ (XCAR (prop), Qspace_width)
3457 && CONSP (XCDR (prop)))
3458 {
3459 /* `(space_width WIDTH)'. */
3460 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3461 return 0;
3462
3463 value = XCAR (XCDR (prop));
3464 if (NUMBERP (value) && XFLOATINT (value) > 0)
3465 it->space_width = value;
3466 }
3467 else if (CONSP (prop)
3468 && EQ (XCAR (prop), Qraise)
3469 && CONSP (XCDR (prop)))
3470 {
3471 /* `(raise FACTOR)'. */
3472 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3473 return 0;
3474
3475 #ifdef HAVE_WINDOW_SYSTEM
3476 value = XCAR (XCDR (prop));
3477 if (NUMBERP (value))
3478 {
3479 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3480 it->voffset = - (XFLOATINT (value)
3481 * (FONT_HEIGHT (face->font)));
3482 }
3483 #endif /* HAVE_WINDOW_SYSTEM */
3484 }
3485 else if (CONSP (prop)
3486 && (EQ (XCAR (prop), Qleft_fringe)
3487 || EQ (XCAR (prop), Qright_fringe))
3488 && CONSP (XCDR (prop)))
3489 {
3490 unsigned face_id = DEFAULT_FACE_ID;
3491
3492 /* `(left-fringe BITMAP FACE)'. */
3493 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3494 return 0;
3495
3496 #ifdef HAVE_WINDOW_SYSTEM
3497 value = XCAR (XCDR (prop));
3498 if (!NUMBERP (value)
3499 || !valid_fringe_bitmap_id_p (XINT (value)))
3500 return 0;
3501
3502 if (CONSP (XCDR (XCDR (prop))))
3503 {
3504 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3505 face_id = lookup_named_face (it->f, face_name, 'A');
3506 if (face_id < 0)
3507 return 0;
3508 }
3509
3510 if (EQ (XCAR (prop), Qleft_fringe))
3511 {
3512 it->left_user_fringe_bitmap = XINT (value);
3513 it->left_user_fringe_face_id = face_id;
3514 }
3515 else
3516 {
3517 it->right_user_fringe_bitmap = XINT (value);
3518 it->right_user_fringe_face_id = face_id;
3519 }
3520 #endif /* HAVE_WINDOW_SYSTEM */
3521 }
3522 else if (!it->string_from_display_prop_p)
3523 {
3524 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3525 VALUE) or `((margin nil) VALUE)' or VALUE. */
3526 Lisp_Object location, value;
3527 struct text_pos start_pos;
3528 int valid_p;
3529
3530 /* Characters having this form of property are not displayed, so
3531 we have to find the end of the property. */
3532 start_pos = *position;
3533 *position = display_prop_end (it, object, start_pos);
3534 value = Qnil;
3535
3536 /* Let's stop at the new position and assume that all
3537 text properties change there. */
3538 it->stop_charpos = position->charpos;
3539
3540 location = Qunbound;
3541 if (CONSP (prop) && CONSP (XCAR (prop)))
3542 {
3543 Lisp_Object tem;
3544
3545 value = XCDR (prop);
3546 if (CONSP (value))
3547 value = XCAR (value);
3548
3549 tem = XCAR (prop);
3550 if (EQ (XCAR (tem), Qmargin)
3551 && (tem = XCDR (tem),
3552 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3553 (NILP (tem)
3554 || EQ (tem, Qleft_margin)
3555 || EQ (tem, Qright_margin))))
3556 location = tem;
3557 }
3558
3559 if (EQ (location, Qunbound))
3560 {
3561 location = Qnil;
3562 value = prop;
3563 }
3564
3565 #ifdef HAVE_WINDOW_SYSTEM
3566 if (FRAME_TERMCAP_P (it->f))
3567 valid_p = STRINGP (value);
3568 else
3569 valid_p = (STRINGP (value)
3570 || (CONSP (value) && EQ (XCAR (value), Qspace))
3571 || valid_image_p (value));
3572 #else /* not HAVE_WINDOW_SYSTEM */
3573 valid_p = STRINGP (value);
3574 #endif /* not HAVE_WINDOW_SYSTEM */
3575
3576 if ((EQ (location, Qleft_margin)
3577 || EQ (location, Qright_margin)
3578 || NILP (location))
3579 && valid_p
3580 && !display_replaced_before_p)
3581 {
3582 replaces_text_display_p = 1;
3583
3584 /* Save current settings of IT so that we can restore them
3585 when we are finished with the glyph property value. */
3586 push_it (it);
3587
3588 if (NILP (location))
3589 it->area = TEXT_AREA;
3590 else if (EQ (location, Qleft_margin))
3591 it->area = LEFT_MARGIN_AREA;
3592 else
3593 it->area = RIGHT_MARGIN_AREA;
3594
3595 if (STRINGP (value))
3596 {
3597 it->string = value;
3598 it->multibyte_p = STRING_MULTIBYTE (it->string);
3599 it->current.overlay_string_index = -1;
3600 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3601 it->end_charpos = it->string_nchars = SCHARS (it->string);
3602 it->method = next_element_from_string;
3603 it->stop_charpos = 0;
3604 it->string_from_display_prop_p = 1;
3605 /* Say that we haven't consumed the characters with
3606 `display' property yet. The call to pop_it in
3607 set_iterator_to_next will clean this up. */
3608 *position = start_pos;
3609 }
3610 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3611 {
3612 it->method = next_element_from_stretch;
3613 it->object = value;
3614 it->current.pos = it->position = start_pos;
3615 }
3616 #ifdef HAVE_WINDOW_SYSTEM
3617 else
3618 {
3619 it->what = IT_IMAGE;
3620 it->image_id = lookup_image (it->f, value);
3621 it->position = start_pos;
3622 it->object = NILP (object) ? it->w->buffer : object;
3623 it->method = next_element_from_image;
3624
3625 /* Say that we haven't consumed the characters with
3626 `display' property yet. The call to pop_it in
3627 set_iterator_to_next will clean this up. */
3628 *position = start_pos;
3629 }
3630 #endif /* HAVE_WINDOW_SYSTEM */
3631 }
3632 else
3633 /* Invalid property or property not supported. Restore
3634 the position to what it was before. */
3635 *position = start_pos;
3636 }
3637
3638 return replaces_text_display_p;
3639 }
3640
3641
3642 /* Check if PROP is a display sub-property value whose text should be
3643 treated as intangible. */
3644
3645 static int
3646 single_display_prop_intangible_p (prop)
3647 Lisp_Object prop;
3648 {
3649 /* Skip over `when FORM'. */
3650 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3651 {
3652 prop = XCDR (prop);
3653 if (!CONSP (prop))
3654 return 0;
3655 prop = XCDR (prop);
3656 }
3657
3658 if (STRINGP (prop))
3659 return 1;
3660
3661 if (!CONSP (prop))
3662 return 0;
3663
3664 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3665 we don't need to treat text as intangible. */
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 || EQ (XCAR (prop), Qleft_margin)
3675 || EQ (XCAR (prop), Qright_margin))
3676 return 0;
3677 }
3678
3679 return (CONSP (prop)
3680 && (EQ (XCAR (prop), Qimage)
3681 || EQ (XCAR (prop), Qspace)));
3682 }
3683
3684
3685 /* Check if PROP is a display property value whose text should be
3686 treated as intangible. */
3687
3688 int
3689 display_prop_intangible_p (prop)
3690 Lisp_Object prop;
3691 {
3692 if (CONSP (prop)
3693 && CONSP (XCAR (prop))
3694 && !EQ (Qmargin, XCAR (XCAR (prop))))
3695 {
3696 /* A list of sub-properties. */
3697 while (CONSP (prop))
3698 {
3699 if (single_display_prop_intangible_p (XCAR (prop)))
3700 return 1;
3701 prop = XCDR (prop);
3702 }
3703 }
3704 else if (VECTORP (prop))
3705 {
3706 /* A vector of sub-properties. */
3707 int i;
3708 for (i = 0; i < ASIZE (prop); ++i)
3709 if (single_display_prop_intangible_p (AREF (prop, i)))
3710 return 1;
3711 }
3712 else
3713 return single_display_prop_intangible_p (prop);
3714
3715 return 0;
3716 }
3717
3718
3719 /* Return 1 if PROP is a display sub-property value containing STRING. */
3720
3721 static int
3722 single_display_prop_string_p (prop, string)
3723 Lisp_Object prop, string;
3724 {
3725 if (EQ (string, prop))
3726 return 1;
3727
3728 /* Skip over `when FORM'. */
3729 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3730 {
3731 prop = XCDR (prop);
3732 if (!CONSP (prop))
3733 return 0;
3734 prop = XCDR (prop);
3735 }
3736
3737 if (CONSP (prop))
3738 /* Skip over `margin LOCATION'. */
3739 if (EQ (XCAR (prop), Qmargin))
3740 {
3741 prop = XCDR (prop);
3742 if (!CONSP (prop))
3743 return 0;
3744
3745 prop = XCDR (prop);
3746 if (!CONSP (prop))
3747 return 0;
3748 }
3749
3750 return CONSP (prop) && EQ (XCAR (prop), string);
3751 }
3752
3753
3754 /* Return 1 if STRING appears in the `display' property PROP. */
3755
3756 static int
3757 display_prop_string_p (prop, string)
3758 Lisp_Object prop, string;
3759 {
3760 if (CONSP (prop)
3761 && CONSP (XCAR (prop))
3762 && !EQ (Qmargin, XCAR (XCAR (prop))))
3763 {
3764 /* A list of sub-properties. */
3765 while (CONSP (prop))
3766 {
3767 if (single_display_prop_string_p (XCAR (prop), string))
3768 return 1;
3769 prop = XCDR (prop);
3770 }
3771 }
3772 else if (VECTORP (prop))
3773 {
3774 /* A vector of sub-properties. */
3775 int i;
3776 for (i = 0; i < ASIZE (prop); ++i)
3777 if (single_display_prop_string_p (AREF (prop, i), string))
3778 return 1;
3779 }
3780 else
3781 return single_display_prop_string_p (prop, string);
3782
3783 return 0;
3784 }
3785
3786
3787 /* Determine from which buffer position in W's buffer STRING comes
3788 from. AROUND_CHARPOS is an approximate position where it could
3789 be from. Value is the buffer position or 0 if it couldn't be
3790 determined.
3791
3792 W's buffer must be current.
3793
3794 This function is necessary because we don't record buffer positions
3795 in glyphs generated from strings (to keep struct glyph small).
3796 This function may only use code that doesn't eval because it is
3797 called asynchronously from note_mouse_highlight. */
3798
3799 int
3800 string_buffer_position (w, string, around_charpos)
3801 struct window *w;
3802 Lisp_Object string;
3803 int around_charpos;
3804 {
3805 Lisp_Object limit, prop, pos;
3806 const int MAX_DISTANCE = 1000;
3807 int found = 0;
3808
3809 pos = make_number (around_charpos);
3810 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3811 while (!found && !EQ (pos, limit))
3812 {
3813 prop = Fget_char_property (pos, Qdisplay, Qnil);
3814 if (!NILP (prop) && display_prop_string_p (prop, string))
3815 found = 1;
3816 else
3817 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3818 }
3819
3820 if (!found)
3821 {
3822 pos = make_number (around_charpos);
3823 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3824 while (!found && !EQ (pos, limit))
3825 {
3826 prop = Fget_char_property (pos, Qdisplay, Qnil);
3827 if (!NILP (prop) && display_prop_string_p (prop, string))
3828 found = 1;
3829 else
3830 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3831 limit);
3832 }
3833 }
3834
3835 return found ? XINT (pos) : 0;
3836 }
3837
3838
3839 \f
3840 /***********************************************************************
3841 `composition' property
3842 ***********************************************************************/
3843
3844 /* Set up iterator IT from `composition' property at its current
3845 position. Called from handle_stop. */
3846
3847 static enum prop_handled
3848 handle_composition_prop (it)
3849 struct it *it;
3850 {
3851 Lisp_Object prop, string;
3852 int pos, pos_byte, end;
3853 enum prop_handled handled = HANDLED_NORMALLY;
3854
3855 if (STRINGP (it->string))
3856 {
3857 pos = IT_STRING_CHARPOS (*it);
3858 pos_byte = IT_STRING_BYTEPOS (*it);
3859 string = it->string;
3860 }
3861 else
3862 {
3863 pos = IT_CHARPOS (*it);
3864 pos_byte = IT_BYTEPOS (*it);
3865 string = Qnil;
3866 }
3867
3868 /* If there's a valid composition and point is not inside of the
3869 composition (in the case that the composition is from the current
3870 buffer), draw a glyph composed from the composition components. */
3871 if (find_composition (pos, -1, &pos, &end, &prop, string)
3872 && COMPOSITION_VALID_P (pos, end, prop)
3873 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3874 {
3875 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3876
3877 if (id >= 0)
3878 {
3879 it->method = next_element_from_composition;
3880 it->cmp_id = id;
3881 it->cmp_len = COMPOSITION_LENGTH (prop);
3882 /* For a terminal, draw only the first character of the
3883 components. */
3884 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3885 it->len = (STRINGP (it->string)
3886 ? string_char_to_byte (it->string, end)
3887 : CHAR_TO_BYTE (end)) - pos_byte;
3888 it->stop_charpos = end;
3889 handled = HANDLED_RETURN;
3890 }
3891 }
3892
3893 return handled;
3894 }
3895
3896
3897 \f
3898 /***********************************************************************
3899 Overlay strings
3900 ***********************************************************************/
3901
3902 /* The following structure is used to record overlay strings for
3903 later sorting in load_overlay_strings. */
3904
3905 struct overlay_entry
3906 {
3907 Lisp_Object overlay;
3908 Lisp_Object string;
3909 int priority;
3910 int after_string_p;
3911 };
3912
3913
3914 /* Set up iterator IT from overlay strings at its current position.
3915 Called from handle_stop. */
3916
3917 static enum prop_handled
3918 handle_overlay_change (it)
3919 struct it *it;
3920 {
3921 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3922 return HANDLED_RECOMPUTE_PROPS;
3923 else
3924 return HANDLED_NORMALLY;
3925 }
3926
3927
3928 /* Set up the next overlay string for delivery by IT, if there is an
3929 overlay string to deliver. Called by set_iterator_to_next when the
3930 end of the current overlay string is reached. If there are more
3931 overlay strings to display, IT->string and
3932 IT->current.overlay_string_index are set appropriately here.
3933 Otherwise IT->string is set to nil. */
3934
3935 static void
3936 next_overlay_string (it)
3937 struct it *it;
3938 {
3939 ++it->current.overlay_string_index;
3940 if (it->current.overlay_string_index == it->n_overlay_strings)
3941 {
3942 /* No more overlay strings. Restore IT's settings to what
3943 they were before overlay strings were processed, and
3944 continue to deliver from current_buffer. */
3945 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3946
3947 pop_it (it);
3948 xassert (it->stop_charpos >= BEGV
3949 && it->stop_charpos <= it->end_charpos);
3950 it->string = Qnil;
3951 it->current.overlay_string_index = -1;
3952 SET_TEXT_POS (it->current.string_pos, -1, -1);
3953 it->n_overlay_strings = 0;
3954 it->method = next_element_from_buffer;
3955
3956 /* If we're at the end of the buffer, record that we have
3957 processed the overlay strings there already, so that
3958 next_element_from_buffer doesn't try it again. */
3959 if (IT_CHARPOS (*it) >= it->end_charpos)
3960 it->overlay_strings_at_end_processed_p = 1;
3961
3962 /* If we have to display `...' for invisible text, set
3963 the iterator up for that. */
3964 if (display_ellipsis_p)
3965 setup_for_ellipsis (it);
3966 }
3967 else
3968 {
3969 /* There are more overlay strings to process. If
3970 IT->current.overlay_string_index has advanced to a position
3971 where we must load IT->overlay_strings with more strings, do
3972 it. */
3973 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3974
3975 if (it->current.overlay_string_index && i == 0)
3976 load_overlay_strings (it, 0);
3977
3978 /* Initialize IT to deliver display elements from the overlay
3979 string. */
3980 it->string = it->overlay_strings[i];
3981 it->multibyte_p = STRING_MULTIBYTE (it->string);
3982 SET_TEXT_POS (it->current.string_pos, 0, 0);
3983 it->method = next_element_from_string;
3984 it->stop_charpos = 0;
3985 }
3986
3987 CHECK_IT (it);
3988 }
3989
3990
3991 /* Compare two overlay_entry structures E1 and E2. Used as a
3992 comparison function for qsort in load_overlay_strings. Overlay
3993 strings for the same position are sorted so that
3994
3995 1. All after-strings come in front of before-strings, except
3996 when they come from the same overlay.
3997
3998 2. Within after-strings, strings are sorted so that overlay strings
3999 from overlays with higher priorities come first.
4000
4001 2. Within before-strings, strings are sorted so that overlay
4002 strings from overlays with higher priorities come last.
4003
4004 Value is analogous to strcmp. */
4005
4006
4007 static int
4008 compare_overlay_entries (e1, e2)
4009 void *e1, *e2;
4010 {
4011 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4012 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4013 int result;
4014
4015 if (entry1->after_string_p != entry2->after_string_p)
4016 {
4017 /* Let after-strings appear in front of before-strings if
4018 they come from different overlays. */
4019 if (EQ (entry1->overlay, entry2->overlay))
4020 result = entry1->after_string_p ? 1 : -1;
4021 else
4022 result = entry1->after_string_p ? -1 : 1;
4023 }
4024 else if (entry1->after_string_p)
4025 /* After-strings sorted in order of decreasing priority. */
4026 result = entry2->priority - entry1->priority;
4027 else
4028 /* Before-strings sorted in order of increasing priority. */
4029 result = entry1->priority - entry2->priority;
4030
4031 return result;
4032 }
4033
4034
4035 /* Load the vector IT->overlay_strings with overlay strings from IT's
4036 current buffer position, or from CHARPOS if that is > 0. Set
4037 IT->n_overlays to the total number of overlay strings found.
4038
4039 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4040 a time. On entry into load_overlay_strings,
4041 IT->current.overlay_string_index gives the number of overlay
4042 strings that have already been loaded by previous calls to this
4043 function.
4044
4045 IT->add_overlay_start contains an additional overlay start
4046 position to consider for taking overlay strings from, if non-zero.
4047 This position comes into play when the overlay has an `invisible'
4048 property, and both before and after-strings. When we've skipped to
4049 the end of the overlay, because of its `invisible' property, we
4050 nevertheless want its before-string to appear.
4051 IT->add_overlay_start will contain the overlay start position
4052 in this case.
4053
4054 Overlay strings are sorted so that after-string strings come in
4055 front of before-string strings. Within before and after-strings,
4056 strings are sorted by overlay priority. See also function
4057 compare_overlay_entries. */
4058
4059 static void
4060 load_overlay_strings (it, charpos)
4061 struct it *it;
4062 int charpos;
4063 {
4064 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4065 Lisp_Object overlay, window, str, invisible;
4066 struct Lisp_Overlay *ov;
4067 int start, end;
4068 int size = 20;
4069 int n = 0, i, j, invis_p;
4070 struct overlay_entry *entries
4071 = (struct overlay_entry *) alloca (size * sizeof *entries);
4072
4073 if (charpos <= 0)
4074 charpos = IT_CHARPOS (*it);
4075
4076 /* Append the overlay string STRING of overlay OVERLAY to vector
4077 `entries' which has size `size' and currently contains `n'
4078 elements. AFTER_P non-zero means STRING is an after-string of
4079 OVERLAY. */
4080 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4081 do \
4082 { \
4083 Lisp_Object priority; \
4084 \
4085 if (n == size) \
4086 { \
4087 int new_size = 2 * size; \
4088 struct overlay_entry *old = entries; \
4089 entries = \
4090 (struct overlay_entry *) alloca (new_size \
4091 * sizeof *entries); \
4092 bcopy (old, entries, size * sizeof *entries); \
4093 size = new_size; \
4094 } \
4095 \
4096 entries[n].string = (STRING); \
4097 entries[n].overlay = (OVERLAY); \
4098 priority = Foverlay_get ((OVERLAY), Qpriority); \
4099 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4100 entries[n].after_string_p = (AFTER_P); \
4101 ++n; \
4102 } \
4103 while (0)
4104
4105 /* Process overlay before the overlay center. */
4106 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4107 {
4108 XSETMISC (overlay, ov);
4109 xassert (OVERLAYP (overlay));
4110 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4111 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4112
4113 if (end < charpos)
4114 break;
4115
4116 /* Skip this overlay if it doesn't start or end at IT's current
4117 position. */
4118 if (end != charpos && start != charpos)
4119 continue;
4120
4121 /* Skip this overlay if it doesn't apply to IT->w. */
4122 window = Foverlay_get (overlay, Qwindow);
4123 if (WINDOWP (window) && XWINDOW (window) != it->w)
4124 continue;
4125
4126 /* If the text ``under'' the overlay is invisible, both before-
4127 and after-strings from this overlay are visible; start and
4128 end position are indistinguishable. */
4129 invisible = Foverlay_get (overlay, Qinvisible);
4130 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4131
4132 /* If overlay has a non-empty before-string, record it. */
4133 if ((start == charpos || (end == charpos && invis_p))
4134 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4135 && SCHARS (str))
4136 RECORD_OVERLAY_STRING (overlay, str, 0);
4137
4138 /* If overlay has a non-empty after-string, record it. */
4139 if ((end == charpos || (start == charpos && invis_p))
4140 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4141 && SCHARS (str))
4142 RECORD_OVERLAY_STRING (overlay, str, 1);
4143 }
4144
4145 /* Process overlays after the overlay center. */
4146 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4147 {
4148 XSETMISC (overlay, ov);
4149 xassert (OVERLAYP (overlay));
4150 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4151 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4152
4153 if (start > charpos)
4154 break;
4155
4156 /* Skip this overlay if it doesn't start or end at IT's current
4157 position. */
4158 if (end != charpos && start != charpos)
4159 continue;
4160
4161 /* Skip this overlay if it doesn't apply to IT->w. */
4162 window = Foverlay_get (overlay, Qwindow);
4163 if (WINDOWP (window) && XWINDOW (window) != it->w)
4164 continue;
4165
4166 /* If the text ``under'' the overlay is invisible, it has a zero
4167 dimension, and both before- and after-strings apply. */
4168 invisible = Foverlay_get (overlay, Qinvisible);
4169 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4170
4171 /* If overlay has a non-empty before-string, record it. */
4172 if ((start == charpos || (end == charpos && invis_p))
4173 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4174 && SCHARS (str))
4175 RECORD_OVERLAY_STRING (overlay, str, 0);
4176
4177 /* If overlay has a non-empty after-string, record it. */
4178 if ((end == charpos || (start == charpos && invis_p))
4179 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4180 && SCHARS (str))
4181 RECORD_OVERLAY_STRING (overlay, str, 1);
4182 }
4183
4184 #undef RECORD_OVERLAY_STRING
4185
4186 /* Sort entries. */
4187 if (n > 1)
4188 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4189
4190 /* Record the total number of strings to process. */
4191 it->n_overlay_strings = n;
4192
4193 /* IT->current.overlay_string_index is the number of overlay strings
4194 that have already been consumed by IT. Copy some of the
4195 remaining overlay strings to IT->overlay_strings. */
4196 i = 0;
4197 j = it->current.overlay_string_index;
4198 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4199 it->overlay_strings[i++] = entries[j++].string;
4200
4201 CHECK_IT (it);
4202 }
4203
4204
4205 /* Get the first chunk of overlay strings at IT's current buffer
4206 position, or at CHARPOS if that is > 0. Value is non-zero if at
4207 least one overlay string was found. */
4208
4209 static int
4210 get_overlay_strings (it, charpos)
4211 struct it *it;
4212 int charpos;
4213 {
4214 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4215 process. This fills IT->overlay_strings with strings, and sets
4216 IT->n_overlay_strings to the total number of strings to process.
4217 IT->pos.overlay_string_index has to be set temporarily to zero
4218 because load_overlay_strings needs this; it must be set to -1
4219 when no overlay strings are found because a zero value would
4220 indicate a position in the first overlay string. */
4221 it->current.overlay_string_index = 0;
4222 load_overlay_strings (it, charpos);
4223
4224 /* If we found overlay strings, set up IT to deliver display
4225 elements from the first one. Otherwise set up IT to deliver
4226 from current_buffer. */
4227 if (it->n_overlay_strings)
4228 {
4229 /* Make sure we know settings in current_buffer, so that we can
4230 restore meaningful values when we're done with the overlay
4231 strings. */
4232 compute_stop_pos (it);
4233 xassert (it->face_id >= 0);
4234
4235 /* Save IT's settings. They are restored after all overlay
4236 strings have been processed. */
4237 xassert (it->sp == 0);
4238 push_it (it);
4239
4240 /* Set up IT to deliver display elements from the first overlay
4241 string. */
4242 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4243 it->string = it->overlay_strings[0];
4244 it->stop_charpos = 0;
4245 xassert (STRINGP (it->string));
4246 it->end_charpos = SCHARS (it->string);
4247 it->multibyte_p = STRING_MULTIBYTE (it->string);
4248 it->method = next_element_from_string;
4249 }
4250 else
4251 {
4252 it->string = Qnil;
4253 it->current.overlay_string_index = -1;
4254 it->method = next_element_from_buffer;
4255 }
4256
4257 CHECK_IT (it);
4258
4259 /* Value is non-zero if we found at least one overlay string. */
4260 return STRINGP (it->string);
4261 }
4262
4263
4264 \f
4265 /***********************************************************************
4266 Saving and restoring state
4267 ***********************************************************************/
4268
4269 /* Save current settings of IT on IT->stack. Called, for example,
4270 before setting up IT for an overlay string, to be able to restore
4271 IT's settings to what they were after the overlay string has been
4272 processed. */
4273
4274 static void
4275 push_it (it)
4276 struct it *it;
4277 {
4278 struct iterator_stack_entry *p;
4279
4280 xassert (it->sp < 2);
4281 p = it->stack + it->sp;
4282
4283 p->stop_charpos = it->stop_charpos;
4284 xassert (it->face_id >= 0);
4285 p->face_id = it->face_id;
4286 p->string = it->string;
4287 p->pos = it->current;
4288 p->end_charpos = it->end_charpos;
4289 p->string_nchars = it->string_nchars;
4290 p->area = it->area;
4291 p->multibyte_p = it->multibyte_p;
4292 p->space_width = it->space_width;
4293 p->font_height = it->font_height;
4294 p->voffset = it->voffset;
4295 p->string_from_display_prop_p = it->string_from_display_prop_p;
4296 p->display_ellipsis_p = 0;
4297 ++it->sp;
4298 }
4299
4300
4301 /* Restore IT's settings from IT->stack. Called, for example, when no
4302 more overlay strings must be processed, and we return to delivering
4303 display elements from a buffer, or when the end of a string from a
4304 `display' property is reached and we return to delivering display
4305 elements from an overlay string, or from a buffer. */
4306
4307 static void
4308 pop_it (it)
4309 struct it *it;
4310 {
4311 struct iterator_stack_entry *p;
4312
4313 xassert (it->sp > 0);
4314 --it->sp;
4315 p = it->stack + it->sp;
4316 it->stop_charpos = p->stop_charpos;
4317 it->face_id = p->face_id;
4318 it->string = p->string;
4319 it->current = p->pos;
4320 it->end_charpos = p->end_charpos;
4321 it->string_nchars = p->string_nchars;
4322 it->area = p->area;
4323 it->multibyte_p = p->multibyte_p;
4324 it->space_width = p->space_width;
4325 it->font_height = p->font_height;
4326 it->voffset = p->voffset;
4327 it->string_from_display_prop_p = p->string_from_display_prop_p;
4328 }
4329
4330
4331 \f
4332 /***********************************************************************
4333 Moving over lines
4334 ***********************************************************************/
4335
4336 /* Set IT's current position to the previous line start. */
4337
4338 static void
4339 back_to_previous_line_start (it)
4340 struct it *it;
4341 {
4342 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4343 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4344 }
4345
4346
4347 /* Move IT to the next line start.
4348
4349 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4350 we skipped over part of the text (as opposed to moving the iterator
4351 continuously over the text). Otherwise, don't change the value
4352 of *SKIPPED_P.
4353
4354 Newlines may come from buffer text, overlay strings, or strings
4355 displayed via the `display' property. That's the reason we can't
4356 simply use find_next_newline_no_quit.
4357
4358 Note that this function may not skip over invisible text that is so
4359 because of text properties and immediately follows a newline. If
4360 it would, function reseat_at_next_visible_line_start, when called
4361 from set_iterator_to_next, would effectively make invisible
4362 characters following a newline part of the wrong glyph row, which
4363 leads to wrong cursor motion. */
4364
4365 static int
4366 forward_to_next_line_start (it, skipped_p)
4367 struct it *it;
4368 int *skipped_p;
4369 {
4370 int old_selective, newline_found_p, n;
4371 const int MAX_NEWLINE_DISTANCE = 500;
4372
4373 /* If already on a newline, just consume it to avoid unintended
4374 skipping over invisible text below. */
4375 if (it->what == IT_CHARACTER
4376 && it->c == '\n'
4377 && CHARPOS (it->position) == IT_CHARPOS (*it))
4378 {
4379 set_iterator_to_next (it, 0);
4380 it->c = 0;
4381 return 1;
4382 }
4383
4384 /* Don't handle selective display in the following. It's (a)
4385 unnecessary because it's done by the caller, and (b) leads to an
4386 infinite recursion because next_element_from_ellipsis indirectly
4387 calls this function. */
4388 old_selective = it->selective;
4389 it->selective = 0;
4390
4391 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4392 from buffer text. */
4393 for (n = newline_found_p = 0;
4394 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4395 n += STRINGP (it->string) ? 0 : 1)
4396 {
4397 if (!get_next_display_element (it))
4398 return 0;
4399 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4400 set_iterator_to_next (it, 0);
4401 }
4402
4403 /* If we didn't find a newline near enough, see if we can use a
4404 short-cut. */
4405 if (!newline_found_p)
4406 {
4407 int start = IT_CHARPOS (*it);
4408 int limit = find_next_newline_no_quit (start, 1);
4409 Lisp_Object pos;
4410
4411 xassert (!STRINGP (it->string));
4412
4413 /* If there isn't any `display' property in sight, and no
4414 overlays, we can just use the position of the newline in
4415 buffer text. */
4416 if (it->stop_charpos >= limit
4417 || ((pos = Fnext_single_property_change (make_number (start),
4418 Qdisplay,
4419 Qnil, make_number (limit)),
4420 NILP (pos))
4421 && next_overlay_change (start) == ZV))
4422 {
4423 IT_CHARPOS (*it) = limit;
4424 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4425 *skipped_p = newline_found_p = 1;
4426 }
4427 else
4428 {
4429 while (get_next_display_element (it)
4430 && !newline_found_p)
4431 {
4432 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4433 set_iterator_to_next (it, 0);
4434 }
4435 }
4436 }
4437
4438 it->selective = old_selective;
4439 return newline_found_p;
4440 }
4441
4442
4443 /* Set IT's current position to the previous visible line start. Skip
4444 invisible text that is so either due to text properties or due to
4445 selective display. Caution: this does not change IT->current_x and
4446 IT->hpos. */
4447
4448 static void
4449 back_to_previous_visible_line_start (it)
4450 struct it *it;
4451 {
4452 int visible_p = 0;
4453
4454 /* Go back one newline if not on BEGV already. */
4455 if (IT_CHARPOS (*it) > BEGV)
4456 back_to_previous_line_start (it);
4457
4458 /* Move over lines that are invisible because of selective display
4459 or text properties. */
4460 while (IT_CHARPOS (*it) > BEGV
4461 && !visible_p)
4462 {
4463 visible_p = 1;
4464
4465 /* If selective > 0, then lines indented more than that values
4466 are invisible. */
4467 if (it->selective > 0
4468 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4469 (double) it->selective)) /* iftc */
4470 visible_p = 0;
4471 else
4472 {
4473 Lisp_Object prop;
4474
4475 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4476 Qinvisible, it->window);
4477 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4478 visible_p = 0;
4479 }
4480
4481 /* Back one more newline if the current one is invisible. */
4482 if (!visible_p)
4483 back_to_previous_line_start (it);
4484 }
4485
4486 xassert (IT_CHARPOS (*it) >= BEGV);
4487 xassert (IT_CHARPOS (*it) == BEGV
4488 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4489 CHECK_IT (it);
4490 }
4491
4492
4493 /* Reseat iterator IT at the previous visible line start. Skip
4494 invisible text that is so either due to text properties or due to
4495 selective display. At the end, update IT's overlay information,
4496 face information etc. */
4497
4498 static void
4499 reseat_at_previous_visible_line_start (it)
4500 struct it *it;
4501 {
4502 back_to_previous_visible_line_start (it);
4503 reseat (it, it->current.pos, 1);
4504 CHECK_IT (it);
4505 }
4506
4507
4508 /* Reseat iterator IT on the next visible line start in the current
4509 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4510 preceding the line start. Skip over invisible text that is so
4511 because of selective display. Compute faces, overlays etc at the
4512 new position. Note that this function does not skip over text that
4513 is invisible because of text properties. */
4514
4515 static void
4516 reseat_at_next_visible_line_start (it, on_newline_p)
4517 struct it *it;
4518 int on_newline_p;
4519 {
4520 int newline_found_p, skipped_p = 0;
4521
4522 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4523
4524 /* Skip over lines that are invisible because they are indented
4525 more than the value of IT->selective. */
4526 if (it->selective > 0)
4527 while (IT_CHARPOS (*it) < ZV
4528 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4529 (double) it->selective)) /* iftc */
4530 {
4531 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4532 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4533 }
4534
4535 /* Position on the newline if that's what's requested. */
4536 if (on_newline_p && newline_found_p)
4537 {
4538 if (STRINGP (it->string))
4539 {
4540 if (IT_STRING_CHARPOS (*it) > 0)
4541 {
4542 --IT_STRING_CHARPOS (*it);
4543 --IT_STRING_BYTEPOS (*it);
4544 }
4545 }
4546 else if (IT_CHARPOS (*it) > BEGV)
4547 {
4548 --IT_CHARPOS (*it);
4549 --IT_BYTEPOS (*it);
4550 reseat (it, it->current.pos, 0);
4551 }
4552 }
4553 else if (skipped_p)
4554 reseat (it, it->current.pos, 0);
4555
4556 CHECK_IT (it);
4557 }
4558
4559
4560 \f
4561 /***********************************************************************
4562 Changing an iterator's position
4563 ***********************************************************************/
4564
4565 /* Change IT's current position to POS in current_buffer. If FORCE_P
4566 is non-zero, always check for text properties at the new position.
4567 Otherwise, text properties are only looked up if POS >=
4568 IT->check_charpos of a property. */
4569
4570 static void
4571 reseat (it, pos, force_p)
4572 struct it *it;
4573 struct text_pos pos;
4574 int force_p;
4575 {
4576 int original_pos = IT_CHARPOS (*it);
4577
4578 reseat_1 (it, pos, 0);
4579
4580 /* Determine where to check text properties. Avoid doing it
4581 where possible because text property lookup is very expensive. */
4582 if (force_p
4583 || CHARPOS (pos) > it->stop_charpos
4584 || CHARPOS (pos) < original_pos)
4585 handle_stop (it);
4586
4587 CHECK_IT (it);
4588 }
4589
4590
4591 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4592 IT->stop_pos to POS, also. */
4593
4594 static void
4595 reseat_1 (it, pos, set_stop_p)
4596 struct it *it;
4597 struct text_pos pos;
4598 int set_stop_p;
4599 {
4600 /* Don't call this function when scanning a C string. */
4601 xassert (it->s == NULL);
4602
4603 /* POS must be a reasonable value. */
4604 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4605
4606 it->current.pos = it->position = pos;
4607 XSETBUFFER (it->object, current_buffer);
4608 it->end_charpos = ZV;
4609 it->dpvec = NULL;
4610 it->current.dpvec_index = -1;
4611 it->current.overlay_string_index = -1;
4612 IT_STRING_CHARPOS (*it) = -1;
4613 IT_STRING_BYTEPOS (*it) = -1;
4614 it->string = Qnil;
4615 it->method = next_element_from_buffer;
4616 /* RMS: I added this to fix a bug in move_it_vertically_backward
4617 where it->area continued to relate to the starting point
4618 for the backward motion. Bug report from
4619 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4620 However, I am not sure whether reseat still does the right thing
4621 in general after this change. */
4622 it->area = TEXT_AREA;
4623 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4624 it->sp = 0;
4625 it->face_before_selective_p = 0;
4626
4627 if (set_stop_p)
4628 it->stop_charpos = CHARPOS (pos);
4629 }
4630
4631
4632 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4633 If S is non-null, it is a C string to iterate over. Otherwise,
4634 STRING gives a Lisp string to iterate over.
4635
4636 If PRECISION > 0, don't return more then PRECISION number of
4637 characters from the string.
4638
4639 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4640 characters have been returned. FIELD_WIDTH < 0 means an infinite
4641 field width.
4642
4643 MULTIBYTE = 0 means disable processing of multibyte characters,
4644 MULTIBYTE > 0 means enable it,
4645 MULTIBYTE < 0 means use IT->multibyte_p.
4646
4647 IT must be initialized via a prior call to init_iterator before
4648 calling this function. */
4649
4650 static void
4651 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4652 struct it *it;
4653 unsigned char *s;
4654 Lisp_Object string;
4655 int charpos;
4656 int precision, field_width, multibyte;
4657 {
4658 /* No region in strings. */
4659 it->region_beg_charpos = it->region_end_charpos = -1;
4660
4661 /* No text property checks performed by default, but see below. */
4662 it->stop_charpos = -1;
4663
4664 /* Set iterator position and end position. */
4665 bzero (&it->current, sizeof it->current);
4666 it->current.overlay_string_index = -1;
4667 it->current.dpvec_index = -1;
4668 xassert (charpos >= 0);
4669
4670 /* If STRING is specified, use its multibyteness, otherwise use the
4671 setting of MULTIBYTE, if specified. */
4672 if (multibyte >= 0)
4673 it->multibyte_p = multibyte > 0;
4674
4675 if (s == NULL)
4676 {
4677 xassert (STRINGP (string));
4678 it->string = string;
4679 it->s = NULL;
4680 it->end_charpos = it->string_nchars = SCHARS (string);
4681 it->method = next_element_from_string;
4682 it->current.string_pos = string_pos (charpos, string);
4683 }
4684 else
4685 {
4686 it->s = s;
4687 it->string = Qnil;
4688
4689 /* Note that we use IT->current.pos, not it->current.string_pos,
4690 for displaying C strings. */
4691 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4692 if (it->multibyte_p)
4693 {
4694 it->current.pos = c_string_pos (charpos, s, 1);
4695 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4696 }
4697 else
4698 {
4699 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4700 it->end_charpos = it->string_nchars = strlen (s);
4701 }
4702
4703 it->method = next_element_from_c_string;
4704 }
4705
4706 /* PRECISION > 0 means don't return more than PRECISION characters
4707 from the string. */
4708 if (precision > 0 && it->end_charpos - charpos > precision)
4709 it->end_charpos = it->string_nchars = charpos + precision;
4710
4711 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4712 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4713 FIELD_WIDTH < 0 means infinite field width. This is useful for
4714 padding with `-' at the end of a mode line. */
4715 if (field_width < 0)
4716 field_width = INFINITY;
4717 if (field_width > it->end_charpos - charpos)
4718 it->end_charpos = charpos + field_width;
4719
4720 /* Use the standard display table for displaying strings. */
4721 if (DISP_TABLE_P (Vstandard_display_table))
4722 it->dp = XCHAR_TABLE (Vstandard_display_table);
4723
4724 it->stop_charpos = charpos;
4725 CHECK_IT (it);
4726 }
4727
4728
4729 \f
4730 /***********************************************************************
4731 Iteration
4732 ***********************************************************************/
4733
4734 /* Load IT's display element fields with information about the next
4735 display element from the current position of IT. Value is zero if
4736 end of buffer (or C string) is reached. */
4737
4738 int
4739 get_next_display_element (it)
4740 struct it *it;
4741 {
4742 /* Non-zero means that we found a display element. Zero means that
4743 we hit the end of what we iterate over. Performance note: the
4744 function pointer `method' used here turns out to be faster than
4745 using a sequence of if-statements. */
4746 int success_p = (*it->method) (it);
4747
4748 if (it->what == IT_CHARACTER)
4749 {
4750 /* Map via display table or translate control characters.
4751 IT->c, IT->len etc. have been set to the next character by
4752 the function call above. If we have a display table, and it
4753 contains an entry for IT->c, translate it. Don't do this if
4754 IT->c itself comes from a display table, otherwise we could
4755 end up in an infinite recursion. (An alternative could be to
4756 count the recursion depth of this function and signal an
4757 error when a certain maximum depth is reached.) Is it worth
4758 it? */
4759 if (success_p && it->dpvec == NULL)
4760 {
4761 Lisp_Object dv;
4762
4763 if (it->dp
4764 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4765 VECTORP (dv)))
4766 {
4767 struct Lisp_Vector *v = XVECTOR (dv);
4768
4769 /* Return the first character from the display table
4770 entry, if not empty. If empty, don't display the
4771 current character. */
4772 if (v->size)
4773 {
4774 it->dpvec_char_len = it->len;
4775 it->dpvec = v->contents;
4776 it->dpend = v->contents + v->size;
4777 it->current.dpvec_index = 0;
4778 it->method = next_element_from_display_vector;
4779 success_p = get_next_display_element (it);
4780 }
4781 else
4782 {
4783 set_iterator_to_next (it, 0);
4784 success_p = get_next_display_element (it);
4785 }
4786 }
4787
4788 /* Translate control characters into `\003' or `^C' form.
4789 Control characters coming from a display table entry are
4790 currently not translated because we use IT->dpvec to hold
4791 the translation. This could easily be changed but I
4792 don't believe that it is worth doing.
4793
4794 If it->multibyte_p is nonzero, eight-bit characters and
4795 non-printable multibyte characters are also translated to
4796 octal form.
4797
4798 If it->multibyte_p is zero, eight-bit characters that
4799 don't have corresponding multibyte char code are also
4800 translated to octal form. */
4801 else if ((it->c < ' '
4802 && (it->area != TEXT_AREA
4803 || (it->c != '\n' && it->c != '\t')))
4804 || (it->multibyte_p
4805 ? ((it->c >= 127
4806 && it->len == 1)
4807 || !CHAR_PRINTABLE_P (it->c))
4808 : (it->c >= 127
4809 && it->c == unibyte_char_to_multibyte (it->c))))
4810 {
4811 /* IT->c is a control character which must be displayed
4812 either as '\003' or as `^C' where the '\\' and '^'
4813 can be defined in the display table. Fill
4814 IT->ctl_chars with glyphs for what we have to
4815 display. Then, set IT->dpvec to these glyphs. */
4816 GLYPH g;
4817
4818 if (it->c < 128 && it->ctl_arrow_p)
4819 {
4820 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4821 if (it->dp
4822 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4823 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4824 g = XINT (DISP_CTRL_GLYPH (it->dp));
4825 else
4826 g = FAST_MAKE_GLYPH ('^', 0);
4827 XSETINT (it->ctl_chars[0], g);
4828
4829 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4830 XSETINT (it->ctl_chars[1], g);
4831
4832 /* Set up IT->dpvec and return first character from it. */
4833 it->dpvec_char_len = it->len;
4834 it->dpvec = it->ctl_chars;
4835 it->dpend = it->dpvec + 2;
4836 it->current.dpvec_index = 0;
4837 it->method = next_element_from_display_vector;
4838 get_next_display_element (it);
4839 }
4840 else
4841 {
4842 unsigned char str[MAX_MULTIBYTE_LENGTH];
4843 int len;
4844 int i;
4845 GLYPH escape_glyph;
4846
4847 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4848 if (it->dp
4849 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4850 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4851 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4852 else
4853 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4854
4855 if (SINGLE_BYTE_CHAR_P (it->c))
4856 str[0] = it->c, len = 1;
4857 else
4858 {
4859 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4860 if (len < 0)
4861 {
4862 /* It's an invalid character, which
4863 shouldn't happen actually, but due to
4864 bugs it may happen. Let's print the char
4865 as is, there's not much meaningful we can
4866 do with it. */
4867 str[0] = it->c;
4868 str[1] = it->c >> 8;
4869 str[2] = it->c >> 16;
4870 str[3] = it->c >> 24;
4871 len = 4;
4872 }
4873 }
4874
4875 for (i = 0; i < len; i++)
4876 {
4877 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4878 /* Insert three more glyphs into IT->ctl_chars for
4879 the octal display of the character. */
4880 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4881 XSETINT (it->ctl_chars[i * 4 + 1], g);
4882 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4883 XSETINT (it->ctl_chars[i * 4 + 2], g);
4884 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4885 XSETINT (it->ctl_chars[i * 4 + 3], g);
4886 }
4887
4888 /* Set up IT->dpvec and return the first character
4889 from it. */
4890 it->dpvec_char_len = it->len;
4891 it->dpvec = it->ctl_chars;
4892 it->dpend = it->dpvec + len * 4;
4893 it->current.dpvec_index = 0;
4894 it->method = next_element_from_display_vector;
4895 get_next_display_element (it);
4896 }
4897 }
4898 }
4899
4900 /* Adjust face id for a multibyte character. There are no
4901 multibyte character in unibyte text. */
4902 if (it->multibyte_p
4903 && success_p
4904 && FRAME_WINDOW_P (it->f))
4905 {
4906 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4907 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4908 }
4909 }
4910
4911 /* Is this character the last one of a run of characters with
4912 box? If yes, set IT->end_of_box_run_p to 1. */
4913 if (it->face_box_p
4914 && it->s == NULL)
4915 {
4916 int face_id;
4917 struct face *face;
4918
4919 it->end_of_box_run_p
4920 = ((face_id = face_after_it_pos (it),
4921 face_id != it->face_id)
4922 && (face = FACE_FROM_ID (it->f, face_id),
4923 face->box == FACE_NO_BOX));
4924 }
4925
4926 /* Value is 0 if end of buffer or string reached. */
4927 return success_p;
4928 }
4929
4930
4931 /* Move IT to the next display element.
4932
4933 RESEAT_P non-zero means if called on a newline in buffer text,
4934 skip to the next visible line start.
4935
4936 Functions get_next_display_element and set_iterator_to_next are
4937 separate because I find this arrangement easier to handle than a
4938 get_next_display_element function that also increments IT's
4939 position. The way it is we can first look at an iterator's current
4940 display element, decide whether it fits on a line, and if it does,
4941 increment the iterator position. The other way around we probably
4942 would either need a flag indicating whether the iterator has to be
4943 incremented the next time, or we would have to implement a
4944 decrement position function which would not be easy to write. */
4945
4946 void
4947 set_iterator_to_next (it, reseat_p)
4948 struct it *it;
4949 int reseat_p;
4950 {
4951 /* Reset flags indicating start and end of a sequence of characters
4952 with box. Reset them at the start of this function because
4953 moving the iterator to a new position might set them. */
4954 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4955
4956 if (it->method == next_element_from_buffer)
4957 {
4958 /* The current display element of IT is a character from
4959 current_buffer. Advance in the buffer, and maybe skip over
4960 invisible lines that are so because of selective display. */
4961 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4962 reseat_at_next_visible_line_start (it, 0);
4963 else
4964 {
4965 xassert (it->len != 0);
4966 IT_BYTEPOS (*it) += it->len;
4967 IT_CHARPOS (*it) += 1;
4968 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4969 }
4970 }
4971 else if (it->method == next_element_from_composition)
4972 {
4973 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4974 if (STRINGP (it->string))
4975 {
4976 IT_STRING_BYTEPOS (*it) += it->len;
4977 IT_STRING_CHARPOS (*it) += it->cmp_len;
4978 it->method = next_element_from_string;
4979 goto consider_string_end;
4980 }
4981 else
4982 {
4983 IT_BYTEPOS (*it) += it->len;
4984 IT_CHARPOS (*it) += it->cmp_len;
4985 it->method = next_element_from_buffer;
4986 }
4987 }
4988 else if (it->method == next_element_from_c_string)
4989 {
4990 /* Current display element of IT is from a C string. */
4991 IT_BYTEPOS (*it) += it->len;
4992 IT_CHARPOS (*it) += 1;
4993 }
4994 else if (it->method == next_element_from_display_vector)
4995 {
4996 /* Current display element of IT is from a display table entry.
4997 Advance in the display table definition. Reset it to null if
4998 end reached, and continue with characters from buffers/
4999 strings. */
5000 ++it->current.dpvec_index;
5001
5002 /* Restore face of the iterator to what they were before the
5003 display vector entry (these entries may contain faces). */
5004 it->face_id = it->saved_face_id;
5005
5006 if (it->dpvec + it->current.dpvec_index == it->dpend)
5007 {
5008 if (it->s)
5009 it->method = next_element_from_c_string;
5010 else if (STRINGP (it->string))
5011 it->method = next_element_from_string;
5012 else
5013 it->method = next_element_from_buffer;
5014
5015 it->dpvec = NULL;
5016 it->current.dpvec_index = -1;
5017
5018 /* Skip over characters which were displayed via IT->dpvec. */
5019 if (it->dpvec_char_len < 0)
5020 reseat_at_next_visible_line_start (it, 1);
5021 else if (it->dpvec_char_len > 0)
5022 {
5023 it->len = it->dpvec_char_len;
5024 set_iterator_to_next (it, reseat_p);
5025 }
5026 }
5027 }
5028 else if (it->method == next_element_from_string)
5029 {
5030 /* Current display element is a character from a Lisp string. */
5031 xassert (it->s == NULL && STRINGP (it->string));
5032 IT_STRING_BYTEPOS (*it) += it->len;
5033 IT_STRING_CHARPOS (*it) += 1;
5034
5035 consider_string_end:
5036
5037 if (it->current.overlay_string_index >= 0)
5038 {
5039 /* IT->string is an overlay string. Advance to the
5040 next, if there is one. */
5041 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5042 next_overlay_string (it);
5043 }
5044 else
5045 {
5046 /* IT->string is not an overlay string. If we reached
5047 its end, and there is something on IT->stack, proceed
5048 with what is on the stack. This can be either another
5049 string, this time an overlay string, or a buffer. */
5050 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5051 && it->sp > 0)
5052 {
5053 pop_it (it);
5054 if (!STRINGP (it->string))
5055 it->method = next_element_from_buffer;
5056 else
5057 goto consider_string_end;
5058 }
5059 }
5060 }
5061 else if (it->method == next_element_from_image
5062 || it->method == next_element_from_stretch)
5063 {
5064 /* The position etc with which we have to proceed are on
5065 the stack. The position may be at the end of a string,
5066 if the `display' property takes up the whole string. */
5067 pop_it (it);
5068 it->image_id = 0;
5069 if (STRINGP (it->string))
5070 {
5071 it->method = next_element_from_string;
5072 goto consider_string_end;
5073 }
5074 else
5075 it->method = next_element_from_buffer;
5076 }
5077 else
5078 /* There are no other methods defined, so this should be a bug. */
5079 abort ();
5080
5081 xassert (it->method != next_element_from_string
5082 || (STRINGP (it->string)
5083 && IT_STRING_CHARPOS (*it) >= 0));
5084 }
5085
5086
5087 /* Load IT's display element fields with information about the next
5088 display element which comes from a display table entry or from the
5089 result of translating a control character to one of the forms `^C'
5090 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5091
5092 static int
5093 next_element_from_display_vector (it)
5094 struct it *it;
5095 {
5096 /* Precondition. */
5097 xassert (it->dpvec && it->current.dpvec_index >= 0);
5098
5099 /* Remember the current face id in case glyphs specify faces.
5100 IT's face is restored in set_iterator_to_next. */
5101 it->saved_face_id = it->face_id;
5102
5103 if (INTEGERP (*it->dpvec)
5104 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5105 {
5106 int lface_id;
5107 GLYPH g;
5108
5109 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5110 it->c = FAST_GLYPH_CHAR (g);
5111 it->len = CHAR_BYTES (it->c);
5112
5113 /* The entry may contain a face id to use. Such a face id is
5114 the id of a Lisp face, not a realized face. A face id of
5115 zero means no face is specified. */
5116 lface_id = FAST_GLYPH_FACE (g);
5117 if (lface_id)
5118 {
5119 /* The function returns -1 if lface_id is invalid. */
5120 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5121 if (face_id >= 0)
5122 it->face_id = face_id;
5123 }
5124 }
5125 else
5126 /* Display table entry is invalid. Return a space. */
5127 it->c = ' ', it->len = 1;
5128
5129 /* Don't change position and object of the iterator here. They are
5130 still the values of the character that had this display table
5131 entry or was translated, and that's what we want. */
5132 it->what = IT_CHARACTER;
5133 return 1;
5134 }
5135
5136
5137 /* Load IT with the next display element from Lisp string IT->string.
5138 IT->current.string_pos is the current position within the string.
5139 If IT->current.overlay_string_index >= 0, the Lisp string is an
5140 overlay string. */
5141
5142 static int
5143 next_element_from_string (it)
5144 struct it *it;
5145 {
5146 struct text_pos position;
5147
5148 xassert (STRINGP (it->string));
5149 xassert (IT_STRING_CHARPOS (*it) >= 0);
5150 position = it->current.string_pos;
5151
5152 /* Time to check for invisible text? */
5153 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5154 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5155 {
5156 handle_stop (it);
5157
5158 /* Since a handler may have changed IT->method, we must
5159 recurse here. */
5160 return get_next_display_element (it);
5161 }
5162
5163 if (it->current.overlay_string_index >= 0)
5164 {
5165 /* Get the next character from an overlay string. In overlay
5166 strings, There is no field width or padding with spaces to
5167 do. */
5168 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5169 {
5170 it->what = IT_EOB;
5171 return 0;
5172 }
5173 else if (STRING_MULTIBYTE (it->string))
5174 {
5175 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5176 const unsigned char *s = (SDATA (it->string)
5177 + IT_STRING_BYTEPOS (*it));
5178 it->c = string_char_and_length (s, remaining, &it->len);
5179 }
5180 else
5181 {
5182 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5183 it->len = 1;
5184 }
5185 }
5186 else
5187 {
5188 /* Get the next character from a Lisp string that is not an
5189 overlay string. Such strings come from the mode line, for
5190 example. We may have to pad with spaces, or truncate the
5191 string. See also next_element_from_c_string. */
5192 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5193 {
5194 it->what = IT_EOB;
5195 return 0;
5196 }
5197 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5198 {
5199 /* Pad with spaces. */
5200 it->c = ' ', it->len = 1;
5201 CHARPOS (position) = BYTEPOS (position) = -1;
5202 }
5203 else if (STRING_MULTIBYTE (it->string))
5204 {
5205 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5206 const unsigned char *s = (SDATA (it->string)
5207 + IT_STRING_BYTEPOS (*it));
5208 it->c = string_char_and_length (s, maxlen, &it->len);
5209 }
5210 else
5211 {
5212 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5213 it->len = 1;
5214 }
5215 }
5216
5217 /* Record what we have and where it came from. Note that we store a
5218 buffer position in IT->position although it could arguably be a
5219 string position. */
5220 it->what = IT_CHARACTER;
5221 it->object = it->string;
5222 it->position = position;
5223 return 1;
5224 }
5225
5226
5227 /* Load IT with next display element from C string IT->s.
5228 IT->string_nchars is the maximum number of characters to return
5229 from the string. IT->end_charpos may be greater than
5230 IT->string_nchars when this function is called, in which case we
5231 may have to return padding spaces. Value is zero if end of string
5232 reached, including padding spaces. */
5233
5234 static int
5235 next_element_from_c_string (it)
5236 struct it *it;
5237 {
5238 int success_p = 1;
5239
5240 xassert (it->s);
5241 it->what = IT_CHARACTER;
5242 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5243 it->object = Qnil;
5244
5245 /* IT's position can be greater IT->string_nchars in case a field
5246 width or precision has been specified when the iterator was
5247 initialized. */
5248 if (IT_CHARPOS (*it) >= it->end_charpos)
5249 {
5250 /* End of the game. */
5251 it->what = IT_EOB;
5252 success_p = 0;
5253 }
5254 else if (IT_CHARPOS (*it) >= it->string_nchars)
5255 {
5256 /* Pad with spaces. */
5257 it->c = ' ', it->len = 1;
5258 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5259 }
5260 else if (it->multibyte_p)
5261 {
5262 /* Implementation note: The calls to strlen apparently aren't a
5263 performance problem because there is no noticeable performance
5264 difference between Emacs running in unibyte or multibyte mode. */
5265 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5266 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5267 maxlen, &it->len);
5268 }
5269 else
5270 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5271
5272 return success_p;
5273 }
5274
5275
5276 /* Set up IT to return characters from an ellipsis, if appropriate.
5277 The definition of the ellipsis glyphs may come from a display table
5278 entry. This function Fills IT with the first glyph from the
5279 ellipsis if an ellipsis is to be displayed. */
5280
5281 static int
5282 next_element_from_ellipsis (it)
5283 struct it *it;
5284 {
5285 if (it->selective_display_ellipsis_p)
5286 {
5287 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5288 {
5289 /* Use the display table definition for `...'. Invalid glyphs
5290 will be handled by the method returning elements from dpvec. */
5291 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5292 it->dpvec_char_len = it->len;
5293 it->dpvec = v->contents;
5294 it->dpend = v->contents + v->size;
5295 it->current.dpvec_index = 0;
5296 it->method = next_element_from_display_vector;
5297 }
5298 else
5299 {
5300 /* Use default `...' which is stored in default_invis_vector. */
5301 it->dpvec_char_len = it->len;
5302 it->dpvec = default_invis_vector;
5303 it->dpend = default_invis_vector + 3;
5304 it->current.dpvec_index = 0;
5305 it->method = next_element_from_display_vector;
5306 }
5307 }
5308 else
5309 {
5310 /* The face at the current position may be different from the
5311 face we find after the invisible text. Remember what it
5312 was in IT->saved_face_id, and signal that it's there by
5313 setting face_before_selective_p. */
5314 it->saved_face_id = it->face_id;
5315 it->method = next_element_from_buffer;
5316 reseat_at_next_visible_line_start (it, 1);
5317 it->face_before_selective_p = 1;
5318 }
5319
5320 return get_next_display_element (it);
5321 }
5322
5323
5324 /* Deliver an image display element. The iterator IT is already
5325 filled with image information (done in handle_display_prop). Value
5326 is always 1. */
5327
5328
5329 static int
5330 next_element_from_image (it)
5331 struct it *it;
5332 {
5333 it->what = IT_IMAGE;
5334 return 1;
5335 }
5336
5337
5338 /* Fill iterator IT with next display element from a stretch glyph
5339 property. IT->object is the value of the text property. Value is
5340 always 1. */
5341
5342 static int
5343 next_element_from_stretch (it)
5344 struct it *it;
5345 {
5346 it->what = IT_STRETCH;
5347 return 1;
5348 }
5349
5350
5351 /* Load IT with the next display element from current_buffer. Value
5352 is zero if end of buffer reached. IT->stop_charpos is the next
5353 position at which to stop and check for text properties or buffer
5354 end. */
5355
5356 static int
5357 next_element_from_buffer (it)
5358 struct it *it;
5359 {
5360 int success_p = 1;
5361
5362 /* Check this assumption, otherwise, we would never enter the
5363 if-statement, below. */
5364 xassert (IT_CHARPOS (*it) >= BEGV
5365 && IT_CHARPOS (*it) <= it->stop_charpos);
5366
5367 if (IT_CHARPOS (*it) >= it->stop_charpos)
5368 {
5369 if (IT_CHARPOS (*it) >= it->end_charpos)
5370 {
5371 int overlay_strings_follow_p;
5372
5373 /* End of the game, except when overlay strings follow that
5374 haven't been returned yet. */
5375 if (it->overlay_strings_at_end_processed_p)
5376 overlay_strings_follow_p = 0;
5377 else
5378 {
5379 it->overlay_strings_at_end_processed_p = 1;
5380 overlay_strings_follow_p = get_overlay_strings (it, 0);
5381 }
5382
5383 if (overlay_strings_follow_p)
5384 success_p = get_next_display_element (it);
5385 else
5386 {
5387 it->what = IT_EOB;
5388 it->position = it->current.pos;
5389 success_p = 0;
5390 }
5391 }
5392 else
5393 {
5394 handle_stop (it);
5395 return get_next_display_element (it);
5396 }
5397 }
5398 else
5399 {
5400 /* No face changes, overlays etc. in sight, so just return a
5401 character from current_buffer. */
5402 unsigned char *p;
5403
5404 /* Maybe run the redisplay end trigger hook. Performance note:
5405 This doesn't seem to cost measurable time. */
5406 if (it->redisplay_end_trigger_charpos
5407 && it->glyph_row
5408 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5409 run_redisplay_end_trigger_hook (it);
5410
5411 /* Get the next character, maybe multibyte. */
5412 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5413 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5414 {
5415 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5416 - IT_BYTEPOS (*it));
5417 it->c = string_char_and_length (p, maxlen, &it->len);
5418 }
5419 else
5420 it->c = *p, it->len = 1;
5421
5422 /* Record what we have and where it came from. */
5423 it->what = IT_CHARACTER;;
5424 it->object = it->w->buffer;
5425 it->position = it->current.pos;
5426
5427 /* Normally we return the character found above, except when we
5428 really want to return an ellipsis for selective display. */
5429 if (it->selective)
5430 {
5431 if (it->c == '\n')
5432 {
5433 /* A value of selective > 0 means hide lines indented more
5434 than that number of columns. */
5435 if (it->selective > 0
5436 && IT_CHARPOS (*it) + 1 < ZV
5437 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5438 IT_BYTEPOS (*it) + 1,
5439 (double) it->selective)) /* iftc */
5440 {
5441 success_p = next_element_from_ellipsis (it);
5442 it->dpvec_char_len = -1;
5443 }
5444 }
5445 else if (it->c == '\r' && it->selective == -1)
5446 {
5447 /* A value of selective == -1 means that everything from the
5448 CR to the end of the line is invisible, with maybe an
5449 ellipsis displayed for it. */
5450 success_p = next_element_from_ellipsis (it);
5451 it->dpvec_char_len = -1;
5452 }
5453 }
5454 }
5455
5456 /* Value is zero if end of buffer reached. */
5457 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5458 return success_p;
5459 }
5460
5461
5462 /* Run the redisplay end trigger hook for IT. */
5463
5464 static void
5465 run_redisplay_end_trigger_hook (it)
5466 struct it *it;
5467 {
5468 Lisp_Object args[3];
5469
5470 /* IT->glyph_row should be non-null, i.e. we should be actually
5471 displaying something, or otherwise we should not run the hook. */
5472 xassert (it->glyph_row);
5473
5474 /* Set up hook arguments. */
5475 args[0] = Qredisplay_end_trigger_functions;
5476 args[1] = it->window;
5477 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5478 it->redisplay_end_trigger_charpos = 0;
5479
5480 /* Since we are *trying* to run these functions, don't try to run
5481 them again, even if they get an error. */
5482 it->w->redisplay_end_trigger = Qnil;
5483 Frun_hook_with_args (3, args);
5484
5485 /* Notice if it changed the face of the character we are on. */
5486 handle_face_prop (it);
5487 }
5488
5489
5490 /* Deliver a composition display element. The iterator IT is already
5491 filled with composition information (done in
5492 handle_composition_prop). Value is always 1. */
5493
5494 static int
5495 next_element_from_composition (it)
5496 struct it *it;
5497 {
5498 it->what = IT_COMPOSITION;
5499 it->position = (STRINGP (it->string)
5500 ? it->current.string_pos
5501 : it->current.pos);
5502 return 1;
5503 }
5504
5505
5506 \f
5507 /***********************************************************************
5508 Moving an iterator without producing glyphs
5509 ***********************************************************************/
5510
5511 /* Move iterator IT to a specified buffer or X position within one
5512 line on the display without producing glyphs.
5513
5514 OP should be a bit mask including some or all of these bits:
5515 MOVE_TO_X: Stop on reaching x-position TO_X.
5516 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5517 Regardless of OP's value, stop in reaching the end of the display line.
5518
5519 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5520 This means, in particular, that TO_X includes window's horizontal
5521 scroll amount.
5522
5523 The return value has several possible values that
5524 say what condition caused the scan to stop:
5525
5526 MOVE_POS_MATCH_OR_ZV
5527 - when TO_POS or ZV was reached.
5528
5529 MOVE_X_REACHED
5530 -when TO_X was reached before TO_POS or ZV were reached.
5531
5532 MOVE_LINE_CONTINUED
5533 - when we reached the end of the display area and the line must
5534 be continued.
5535
5536 MOVE_LINE_TRUNCATED
5537 - when we reached the end of the display area and the line is
5538 truncated.
5539
5540 MOVE_NEWLINE_OR_CR
5541 - when we stopped at a line end, i.e. a newline or a CR and selective
5542 display is on. */
5543
5544 static enum move_it_result
5545 move_it_in_display_line_to (it, to_charpos, to_x, op)
5546 struct it *it;
5547 int to_charpos, to_x, op;
5548 {
5549 enum move_it_result result = MOVE_UNDEFINED;
5550 struct glyph_row *saved_glyph_row;
5551
5552 /* Don't produce glyphs in produce_glyphs. */
5553 saved_glyph_row = it->glyph_row;
5554 it->glyph_row = NULL;
5555
5556 while (1)
5557 {
5558 int x, i, ascent = 0, descent = 0;
5559
5560 /* Stop when ZV or TO_CHARPOS reached. */
5561 if (!get_next_display_element (it)
5562 || ((op & MOVE_TO_POS) != 0
5563 && BUFFERP (it->object)
5564 && IT_CHARPOS (*it) >= to_charpos))
5565 {
5566 result = MOVE_POS_MATCH_OR_ZV;
5567 break;
5568 }
5569
5570 /* The call to produce_glyphs will get the metrics of the
5571 display element IT is loaded with. We record in x the
5572 x-position before this display element in case it does not
5573 fit on the line. */
5574 x = it->current_x;
5575
5576 /* Remember the line height so far in case the next element doesn't
5577 fit on the line. */
5578 if (!it->truncate_lines_p)
5579 {
5580 ascent = it->max_ascent;
5581 descent = it->max_descent;
5582 }
5583
5584 PRODUCE_GLYPHS (it);
5585
5586 if (it->area != TEXT_AREA)
5587 {
5588 set_iterator_to_next (it, 1);
5589 continue;
5590 }
5591
5592 /* The number of glyphs we get back in IT->nglyphs will normally
5593 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5594 character on a terminal frame, or (iii) a line end. For the
5595 second case, IT->nglyphs - 1 padding glyphs will be present
5596 (on X frames, there is only one glyph produced for a
5597 composite character.
5598
5599 The behavior implemented below means, for continuation lines,
5600 that as many spaces of a TAB as fit on the current line are
5601 displayed there. For terminal frames, as many glyphs of a
5602 multi-glyph character are displayed in the current line, too.
5603 This is what the old redisplay code did, and we keep it that
5604 way. Under X, the whole shape of a complex character must
5605 fit on the line or it will be completely displayed in the
5606 next line.
5607
5608 Note that both for tabs and padding glyphs, all glyphs have
5609 the same width. */
5610 if (it->nglyphs)
5611 {
5612 /* More than one glyph or glyph doesn't fit on line. All
5613 glyphs have the same width. */
5614 int single_glyph_width = it->pixel_width / it->nglyphs;
5615 int new_x;
5616
5617 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5618 {
5619 new_x = x + single_glyph_width;
5620
5621 /* We want to leave anything reaching TO_X to the caller. */
5622 if ((op & MOVE_TO_X) && new_x > to_x)
5623 {
5624 it->current_x = x;
5625 result = MOVE_X_REACHED;
5626 break;
5627 }
5628 else if (/* Lines are continued. */
5629 !it->truncate_lines_p
5630 && (/* And glyph doesn't fit on the line. */
5631 new_x > it->last_visible_x
5632 /* Or it fits exactly and we're on a window
5633 system frame. */
5634 || (new_x == it->last_visible_x
5635 && FRAME_WINDOW_P (it->f))))
5636 {
5637 if (/* IT->hpos == 0 means the very first glyph
5638 doesn't fit on the line, e.g. a wide image. */
5639 it->hpos == 0
5640 || (new_x == it->last_visible_x
5641 && FRAME_WINDOW_P (it->f)))
5642 {
5643 ++it->hpos;
5644 it->current_x = new_x;
5645 if (i == it->nglyphs - 1)
5646 {
5647 set_iterator_to_next (it, 1);
5648 #ifdef HAVE_WINDOW_SYSTEM
5649 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5650 {
5651 if (!get_next_display_element (it))
5652 {
5653 result = MOVE_POS_MATCH_OR_ZV;
5654 break;
5655 }
5656 if (ITERATOR_AT_END_OF_LINE_P (it))
5657 {
5658 result = MOVE_NEWLINE_OR_CR;
5659 break;
5660 }
5661 }
5662 #endif /* HAVE_WINDOW_SYSTEM */
5663 }
5664 }
5665 else
5666 {
5667 it->current_x = x;
5668 it->max_ascent = ascent;
5669 it->max_descent = descent;
5670 }
5671
5672 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5673 IT_CHARPOS (*it)));
5674 result = MOVE_LINE_CONTINUED;
5675 break;
5676 }
5677 else if (new_x > it->first_visible_x)
5678 {
5679 /* Glyph is visible. Increment number of glyphs that
5680 would be displayed. */
5681 ++it->hpos;
5682 }
5683 else
5684 {
5685 /* Glyph is completely off the left margin of the display
5686 area. Nothing to do. */
5687 }
5688 }
5689
5690 if (result != MOVE_UNDEFINED)
5691 break;
5692 }
5693 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5694 {
5695 /* Stop when TO_X specified and reached. This check is
5696 necessary here because of lines consisting of a line end,
5697 only. The line end will not produce any glyphs and we
5698 would never get MOVE_X_REACHED. */
5699 xassert (it->nglyphs == 0);
5700 result = MOVE_X_REACHED;
5701 break;
5702 }
5703
5704 /* Is this a line end? If yes, we're done. */
5705 if (ITERATOR_AT_END_OF_LINE_P (it))
5706 {
5707 result = MOVE_NEWLINE_OR_CR;
5708 break;
5709 }
5710
5711 /* The current display element has been consumed. Advance
5712 to the next. */
5713 set_iterator_to_next (it, 1);
5714
5715 /* Stop if lines are truncated and IT's current x-position is
5716 past the right edge of the window now. */
5717 if (it->truncate_lines_p
5718 && it->current_x >= it->last_visible_x)
5719 {
5720 #ifdef HAVE_WINDOW_SYSTEM
5721 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5722 {
5723 if (!get_next_display_element (it))
5724 {
5725 result = MOVE_POS_MATCH_OR_ZV;
5726 break;
5727 }
5728 if (ITERATOR_AT_END_OF_LINE_P (it))
5729 {
5730 result = MOVE_NEWLINE_OR_CR;
5731 break;
5732 }
5733 }
5734 #endif /* HAVE_WINDOW_SYSTEM */
5735 result = MOVE_LINE_TRUNCATED;
5736 break;
5737 }
5738 }
5739
5740 /* Restore the iterator settings altered at the beginning of this
5741 function. */
5742 it->glyph_row = saved_glyph_row;
5743 return result;
5744 }
5745
5746
5747 /* Move IT forward until it satisfies one or more of the criteria in
5748 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5749
5750 OP is a bit-mask that specifies where to stop, and in particular,
5751 which of those four position arguments makes a difference. See the
5752 description of enum move_operation_enum.
5753
5754 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5755 screen line, this function will set IT to the next position >
5756 TO_CHARPOS. */
5757
5758 void
5759 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5760 struct it *it;
5761 int to_charpos, to_x, to_y, to_vpos;
5762 int op;
5763 {
5764 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5765 int line_height;
5766 int reached = 0;
5767
5768 for (;;)
5769 {
5770 if (op & MOVE_TO_VPOS)
5771 {
5772 /* If no TO_CHARPOS and no TO_X specified, stop at the
5773 start of the line TO_VPOS. */
5774 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5775 {
5776 if (it->vpos == to_vpos)
5777 {
5778 reached = 1;
5779 break;
5780 }
5781 else
5782 skip = move_it_in_display_line_to (it, -1, -1, 0);
5783 }
5784 else
5785 {
5786 /* TO_VPOS >= 0 means stop at TO_X in the line at
5787 TO_VPOS, or at TO_POS, whichever comes first. */
5788 if (it->vpos == to_vpos)
5789 {
5790 reached = 2;
5791 break;
5792 }
5793
5794 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5795
5796 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5797 {
5798 reached = 3;
5799 break;
5800 }
5801 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5802 {
5803 /* We have reached TO_X but not in the line we want. */
5804 skip = move_it_in_display_line_to (it, to_charpos,
5805 -1, MOVE_TO_POS);
5806 if (skip == MOVE_POS_MATCH_OR_ZV)
5807 {
5808 reached = 4;
5809 break;
5810 }
5811 }
5812 }
5813 }
5814 else if (op & MOVE_TO_Y)
5815 {
5816 struct it it_backup;
5817
5818 /* TO_Y specified means stop at TO_X in the line containing
5819 TO_Y---or at TO_CHARPOS if this is reached first. The
5820 problem is that we can't really tell whether the line
5821 contains TO_Y before we have completely scanned it, and
5822 this may skip past TO_X. What we do is to first scan to
5823 TO_X.
5824
5825 If TO_X is not specified, use a TO_X of zero. The reason
5826 is to make the outcome of this function more predictable.
5827 If we didn't use TO_X == 0, we would stop at the end of
5828 the line which is probably not what a caller would expect
5829 to happen. */
5830 skip = move_it_in_display_line_to (it, to_charpos,
5831 ((op & MOVE_TO_X)
5832 ? to_x : 0),
5833 (MOVE_TO_X
5834 | (op & MOVE_TO_POS)));
5835
5836 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5837 if (skip == MOVE_POS_MATCH_OR_ZV)
5838 {
5839 reached = 5;
5840 break;
5841 }
5842
5843 /* If TO_X was reached, we would like to know whether TO_Y
5844 is in the line. This can only be said if we know the
5845 total line height which requires us to scan the rest of
5846 the line. */
5847 if (skip == MOVE_X_REACHED)
5848 {
5849 it_backup = *it;
5850 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5851 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5852 op & MOVE_TO_POS);
5853 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5854 }
5855
5856 /* Now, decide whether TO_Y is in this line. */
5857 line_height = it->max_ascent + it->max_descent;
5858 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5859
5860 if (to_y >= it->current_y
5861 && to_y < it->current_y + line_height)
5862 {
5863 if (skip == MOVE_X_REACHED)
5864 /* If TO_Y is in this line and TO_X was reached above,
5865 we scanned too far. We have to restore IT's settings
5866 to the ones before skipping. */
5867 *it = it_backup;
5868 reached = 6;
5869 }
5870 else if (skip == MOVE_X_REACHED)
5871 {
5872 skip = skip2;
5873 if (skip == MOVE_POS_MATCH_OR_ZV)
5874 reached = 7;
5875 }
5876
5877 if (reached)
5878 break;
5879 }
5880 else
5881 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5882
5883 switch (skip)
5884 {
5885 case MOVE_POS_MATCH_OR_ZV:
5886 reached = 8;
5887 goto out;
5888
5889 case MOVE_NEWLINE_OR_CR:
5890 set_iterator_to_next (it, 1);
5891 it->continuation_lines_width = 0;
5892 break;
5893
5894 case MOVE_LINE_TRUNCATED:
5895 it->continuation_lines_width = 0;
5896 reseat_at_next_visible_line_start (it, 0);
5897 if ((op & MOVE_TO_POS) != 0
5898 && IT_CHARPOS (*it) > to_charpos)
5899 {
5900 reached = 9;
5901 goto out;
5902 }
5903 break;
5904
5905 case MOVE_LINE_CONTINUED:
5906 it->continuation_lines_width += it->current_x;
5907 break;
5908
5909 default:
5910 abort ();
5911 }
5912
5913 /* Reset/increment for the next run. */
5914 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5915 it->current_x = it->hpos = 0;
5916 it->current_y += it->max_ascent + it->max_descent;
5917 ++it->vpos;
5918 last_height = it->max_ascent + it->max_descent;
5919 last_max_ascent = it->max_ascent;
5920 it->max_ascent = it->max_descent = 0;
5921 }
5922
5923 out:
5924
5925 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5926 }
5927
5928
5929 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5930
5931 If DY > 0, move IT backward at least that many pixels. DY = 0
5932 means move IT backward to the preceding line start or BEGV. This
5933 function may move over more than DY pixels if IT->current_y - DY
5934 ends up in the middle of a line; in this case IT->current_y will be
5935 set to the top of the line moved to. */
5936
5937 void
5938 move_it_vertically_backward (it, dy)
5939 struct it *it;
5940 int dy;
5941 {
5942 int nlines, h;
5943 struct it it2, it3;
5944 int start_pos = IT_CHARPOS (*it);
5945
5946 xassert (dy >= 0);
5947
5948 /* Estimate how many newlines we must move back. */
5949 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5950
5951 /* Set the iterator's position that many lines back. */
5952 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5953 back_to_previous_visible_line_start (it);
5954
5955 /* Reseat the iterator here. When moving backward, we don't want
5956 reseat to skip forward over invisible text, set up the iterator
5957 to deliver from overlay strings at the new position etc. So,
5958 use reseat_1 here. */
5959 reseat_1 (it, it->current.pos, 1);
5960
5961 /* We are now surely at a line start. */
5962 it->current_x = it->hpos = 0;
5963 it->continuation_lines_width = 0;
5964
5965 /* Move forward and see what y-distance we moved. First move to the
5966 start of the next line so that we get its height. We need this
5967 height to be able to tell whether we reached the specified
5968 y-distance. */
5969 it2 = *it;
5970 it2.max_ascent = it2.max_descent = 0;
5971 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5972 MOVE_TO_POS | MOVE_TO_VPOS);
5973 xassert (IT_CHARPOS (*it) >= BEGV);
5974 it3 = it2;
5975
5976 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5977 xassert (IT_CHARPOS (*it) >= BEGV);
5978 /* H is the actual vertical distance from the position in *IT
5979 and the starting position. */
5980 h = it2.current_y - it->current_y;
5981 /* NLINES is the distance in number of lines. */
5982 nlines = it2.vpos - it->vpos;
5983
5984 /* Correct IT's y and vpos position
5985 so that they are relative to the starting point. */
5986 it->vpos -= nlines;
5987 it->current_y -= h;
5988
5989 if (dy == 0)
5990 {
5991 /* DY == 0 means move to the start of the screen line. The
5992 value of nlines is > 0 if continuation lines were involved. */
5993 if (nlines > 0)
5994 move_it_by_lines (it, nlines, 1);
5995 xassert (IT_CHARPOS (*it) <= start_pos);
5996 }
5997 else
5998 {
5999 /* The y-position we try to reach, relative to *IT.
6000 Note that H has been subtracted in front of the if-statement. */
6001 int target_y = it->current_y + h - dy;
6002 int y0 = it3.current_y;
6003 int y1 = line_bottom_y (&it3);
6004 int line_height = y1 - y0;
6005
6006 /* If we did not reach target_y, try to move further backward if
6007 we can. If we moved too far backward, try to move forward. */
6008 if (target_y < it->current_y
6009 /* This is heuristic. In a window that's 3 lines high, with
6010 a line height of 13 pixels each, recentering with point
6011 on the bottom line will try to move -39/2 = 19 pixels
6012 backward. Try to avoid moving into the first line. */
6013 && it->current_y - target_y > line_height / 3 * 2
6014 && IT_CHARPOS (*it) > BEGV)
6015 {
6016 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6017 target_y - it->current_y));
6018 move_it_vertically (it, target_y - it->current_y);
6019 xassert (IT_CHARPOS (*it) >= BEGV);
6020 }
6021 else if (target_y >= it->current_y + line_height
6022 && IT_CHARPOS (*it) < ZV)
6023 {
6024 /* Should move forward by at least one line, maybe more.
6025
6026 Note: Calling move_it_by_lines can be expensive on
6027 terminal frames, where compute_motion is used (via
6028 vmotion) to do the job, when there are very long lines
6029 and truncate-lines is nil. That's the reason for
6030 treating terminal frames specially here. */
6031
6032 if (!FRAME_WINDOW_P (it->f))
6033 move_it_vertically (it, target_y - (it->current_y + line_height));
6034 else
6035 {
6036 do
6037 {
6038 move_it_by_lines (it, 1, 1);
6039 }
6040 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6041 }
6042
6043 xassert (IT_CHARPOS (*it) >= BEGV);
6044 }
6045 }
6046 }
6047
6048
6049 /* Move IT by a specified amount of pixel lines DY. DY negative means
6050 move backwards. DY = 0 means move to start of screen line. At the
6051 end, IT will be on the start of a screen line. */
6052
6053 void
6054 move_it_vertically (it, dy)
6055 struct it *it;
6056 int dy;
6057 {
6058 if (dy <= 0)
6059 move_it_vertically_backward (it, -dy);
6060 else if (dy > 0)
6061 {
6062 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6063 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6064 MOVE_TO_POS | MOVE_TO_Y);
6065 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6066
6067 /* If buffer ends in ZV without a newline, move to the start of
6068 the line to satisfy the post-condition. */
6069 if (IT_CHARPOS (*it) == ZV
6070 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6071 move_it_by_lines (it, 0, 0);
6072 }
6073 }
6074
6075
6076 /* Move iterator IT past the end of the text line it is in. */
6077
6078 void
6079 move_it_past_eol (it)
6080 struct it *it;
6081 {
6082 enum move_it_result rc;
6083
6084 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6085 if (rc == MOVE_NEWLINE_OR_CR)
6086 set_iterator_to_next (it, 0);
6087 }
6088
6089
6090 #if 0 /* Currently not used. */
6091
6092 /* Return non-zero if some text between buffer positions START_CHARPOS
6093 and END_CHARPOS is invisible. IT->window is the window for text
6094 property lookup. */
6095
6096 static int
6097 invisible_text_between_p (it, start_charpos, end_charpos)
6098 struct it *it;
6099 int start_charpos, end_charpos;
6100 {
6101 Lisp_Object prop, limit;
6102 int invisible_found_p;
6103
6104 xassert (it != NULL && start_charpos <= end_charpos);
6105
6106 /* Is text at START invisible? */
6107 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6108 it->window);
6109 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6110 invisible_found_p = 1;
6111 else
6112 {
6113 limit = Fnext_single_char_property_change (make_number (start_charpos),
6114 Qinvisible, Qnil,
6115 make_number (end_charpos));
6116 invisible_found_p = XFASTINT (limit) < end_charpos;
6117 }
6118
6119 return invisible_found_p;
6120 }
6121
6122 #endif /* 0 */
6123
6124
6125 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6126 negative means move up. DVPOS == 0 means move to the start of the
6127 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6128 NEED_Y_P is zero, IT->current_y will be left unchanged.
6129
6130 Further optimization ideas: If we would know that IT->f doesn't use
6131 a face with proportional font, we could be faster for
6132 truncate-lines nil. */
6133
6134 void
6135 move_it_by_lines (it, dvpos, need_y_p)
6136 struct it *it;
6137 int dvpos, need_y_p;
6138 {
6139 struct position pos;
6140
6141 if (!FRAME_WINDOW_P (it->f))
6142 {
6143 struct text_pos textpos;
6144
6145 /* We can use vmotion on frames without proportional fonts. */
6146 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6147 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6148 reseat (it, textpos, 1);
6149 it->vpos += pos.vpos;
6150 it->current_y += pos.vpos;
6151 }
6152 else if (dvpos == 0)
6153 {
6154 /* DVPOS == 0 means move to the start of the screen line. */
6155 move_it_vertically_backward (it, 0);
6156 xassert (it->current_x == 0 && it->hpos == 0);
6157 }
6158 else if (dvpos > 0)
6159 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6160 else
6161 {
6162 struct it it2;
6163 int start_charpos, i;
6164
6165 /* Start at the beginning of the screen line containing IT's
6166 position. */
6167 move_it_vertically_backward (it, 0);
6168
6169 /* Go back -DVPOS visible lines and reseat the iterator there. */
6170 start_charpos = IT_CHARPOS (*it);
6171 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6172 back_to_previous_visible_line_start (it);
6173 reseat (it, it->current.pos, 1);
6174 it->current_x = it->hpos = 0;
6175
6176 /* Above call may have moved too far if continuation lines
6177 are involved. Scan forward and see if it did. */
6178 it2 = *it;
6179 it2.vpos = it2.current_y = 0;
6180 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6181 it->vpos -= it2.vpos;
6182 it->current_y -= it2.current_y;
6183 it->current_x = it->hpos = 0;
6184
6185 /* If we moved too far, move IT some lines forward. */
6186 if (it2.vpos > -dvpos)
6187 {
6188 int delta = it2.vpos + dvpos;
6189 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6190 }
6191 }
6192 }
6193
6194 /* Return 1 if IT points into the middle of a display vector. */
6195
6196 int
6197 in_display_vector_p (it)
6198 struct it *it;
6199 {
6200 return (it->method == next_element_from_display_vector
6201 && it->current.dpvec_index > 0
6202 && it->dpvec + it->current.dpvec_index != it->dpend);
6203 }
6204
6205 \f
6206 /***********************************************************************
6207 Messages
6208 ***********************************************************************/
6209
6210
6211 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6212 to *Messages*. */
6213
6214 void
6215 add_to_log (format, arg1, arg2)
6216 char *format;
6217 Lisp_Object arg1, arg2;
6218 {
6219 Lisp_Object args[3];
6220 Lisp_Object msg, fmt;
6221 char *buffer;
6222 int len;
6223 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6224
6225 /* Do nothing if called asynchronously. Inserting text into
6226 a buffer may call after-change-functions and alike and
6227 that would means running Lisp asynchronously. */
6228 if (handling_signal)
6229 return;
6230
6231 fmt = msg = Qnil;
6232 GCPRO4 (fmt, msg, arg1, arg2);
6233
6234 args[0] = fmt = build_string (format);
6235 args[1] = arg1;
6236 args[2] = arg2;
6237 msg = Fformat (3, args);
6238
6239 len = SBYTES (msg) + 1;
6240 buffer = (char *) alloca (len);
6241 bcopy (SDATA (msg), buffer, len);
6242
6243 message_dolog (buffer, len - 1, 1, 0);
6244 UNGCPRO;
6245 }
6246
6247
6248 /* Output a newline in the *Messages* buffer if "needs" one. */
6249
6250 void
6251 message_log_maybe_newline ()
6252 {
6253 if (message_log_need_newline)
6254 message_dolog ("", 0, 1, 0);
6255 }
6256
6257
6258 /* Add a string M of length NBYTES to the message log, optionally
6259 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6260 nonzero, means interpret the contents of M as multibyte. This
6261 function calls low-level routines in order to bypass text property
6262 hooks, etc. which might not be safe to run. */
6263
6264 void
6265 message_dolog (m, nbytes, nlflag, multibyte)
6266 const char *m;
6267 int nbytes, nlflag, multibyte;
6268 {
6269 if (!NILP (Vmemory_full))
6270 return;
6271
6272 if (!NILP (Vmessage_log_max))
6273 {
6274 struct buffer *oldbuf;
6275 Lisp_Object oldpoint, oldbegv, oldzv;
6276 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6277 int point_at_end = 0;
6278 int zv_at_end = 0;
6279 Lisp_Object old_deactivate_mark, tem;
6280 struct gcpro gcpro1;
6281
6282 old_deactivate_mark = Vdeactivate_mark;
6283 oldbuf = current_buffer;
6284 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6285 current_buffer->undo_list = Qt;
6286
6287 oldpoint = message_dolog_marker1;
6288 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6289 oldbegv = message_dolog_marker2;
6290 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6291 oldzv = message_dolog_marker3;
6292 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6293 GCPRO1 (old_deactivate_mark);
6294
6295 if (PT == Z)
6296 point_at_end = 1;
6297 if (ZV == Z)
6298 zv_at_end = 1;
6299
6300 BEGV = BEG;
6301 BEGV_BYTE = BEG_BYTE;
6302 ZV = Z;
6303 ZV_BYTE = Z_BYTE;
6304 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6305
6306 /* Insert the string--maybe converting multibyte to single byte
6307 or vice versa, so that all the text fits the buffer. */
6308 if (multibyte
6309 && NILP (current_buffer->enable_multibyte_characters))
6310 {
6311 int i, c, char_bytes;
6312 unsigned char work[1];
6313
6314 /* Convert a multibyte string to single-byte
6315 for the *Message* buffer. */
6316 for (i = 0; i < nbytes; i += char_bytes)
6317 {
6318 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6319 work[0] = (SINGLE_BYTE_CHAR_P (c)
6320 ? c
6321 : multibyte_char_to_unibyte (c, Qnil));
6322 insert_1_both (work, 1, 1, 1, 0, 0);
6323 }
6324 }
6325 else if (! multibyte
6326 && ! NILP (current_buffer->enable_multibyte_characters))
6327 {
6328 int i, c, char_bytes;
6329 unsigned char *msg = (unsigned char *) m;
6330 unsigned char str[MAX_MULTIBYTE_LENGTH];
6331 /* Convert a single-byte string to multibyte
6332 for the *Message* buffer. */
6333 for (i = 0; i < nbytes; i++)
6334 {
6335 c = unibyte_char_to_multibyte (msg[i]);
6336 char_bytes = CHAR_STRING (c, str);
6337 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6338 }
6339 }
6340 else if (nbytes)
6341 insert_1 (m, nbytes, 1, 0, 0);
6342
6343 if (nlflag)
6344 {
6345 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6346 insert_1 ("\n", 1, 1, 0, 0);
6347
6348 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6349 this_bol = PT;
6350 this_bol_byte = PT_BYTE;
6351
6352 /* See if this line duplicates the previous one.
6353 If so, combine duplicates. */
6354 if (this_bol > BEG)
6355 {
6356 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6357 prev_bol = PT;
6358 prev_bol_byte = PT_BYTE;
6359
6360 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6361 this_bol, this_bol_byte);
6362 if (dup)
6363 {
6364 del_range_both (prev_bol, prev_bol_byte,
6365 this_bol, this_bol_byte, 0);
6366 if (dup > 1)
6367 {
6368 char dupstr[40];
6369 int duplen;
6370
6371 /* If you change this format, don't forget to also
6372 change message_log_check_duplicate. */
6373 sprintf (dupstr, " [%d times]", dup);
6374 duplen = strlen (dupstr);
6375 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6376 insert_1 (dupstr, duplen, 1, 0, 1);
6377 }
6378 }
6379 }
6380
6381 /* If we have more than the desired maximum number of lines
6382 in the *Messages* buffer now, delete the oldest ones.
6383 This is safe because we don't have undo in this buffer. */
6384
6385 if (NATNUMP (Vmessage_log_max))
6386 {
6387 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6388 -XFASTINT (Vmessage_log_max) - 1, 0);
6389 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6390 }
6391 }
6392 BEGV = XMARKER (oldbegv)->charpos;
6393 BEGV_BYTE = marker_byte_position (oldbegv);
6394
6395 if (zv_at_end)
6396 {
6397 ZV = Z;
6398 ZV_BYTE = Z_BYTE;
6399 }
6400 else
6401 {
6402 ZV = XMARKER (oldzv)->charpos;
6403 ZV_BYTE = marker_byte_position (oldzv);
6404 }
6405
6406 if (point_at_end)
6407 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6408 else
6409 /* We can't do Fgoto_char (oldpoint) because it will run some
6410 Lisp code. */
6411 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6412 XMARKER (oldpoint)->bytepos);
6413
6414 UNGCPRO;
6415 unchain_marker (XMARKER (oldpoint));
6416 unchain_marker (XMARKER (oldbegv));
6417 unchain_marker (XMARKER (oldzv));
6418
6419 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6420 set_buffer_internal (oldbuf);
6421 if (NILP (tem))
6422 windows_or_buffers_changed = old_windows_or_buffers_changed;
6423 message_log_need_newline = !nlflag;
6424 Vdeactivate_mark = old_deactivate_mark;
6425 }
6426 }
6427
6428
6429 /* We are at the end of the buffer after just having inserted a newline.
6430 (Note: We depend on the fact we won't be crossing the gap.)
6431 Check to see if the most recent message looks a lot like the previous one.
6432 Return 0 if different, 1 if the new one should just replace it, or a
6433 value N > 1 if we should also append " [N times]". */
6434
6435 static int
6436 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6437 int prev_bol, this_bol;
6438 int prev_bol_byte, this_bol_byte;
6439 {
6440 int i;
6441 int len = Z_BYTE - 1 - this_bol_byte;
6442 int seen_dots = 0;
6443 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6444 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6445
6446 for (i = 0; i < len; i++)
6447 {
6448 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6449 seen_dots = 1;
6450 if (p1[i] != p2[i])
6451 return seen_dots;
6452 }
6453 p1 += len;
6454 if (*p1 == '\n')
6455 return 2;
6456 if (*p1++ == ' ' && *p1++ == '[')
6457 {
6458 int n = 0;
6459 while (*p1 >= '0' && *p1 <= '9')
6460 n = n * 10 + *p1++ - '0';
6461 if (strncmp (p1, " times]\n", 8) == 0)
6462 return n+1;
6463 }
6464 return 0;
6465 }
6466
6467
6468 /* Display an echo area message M with a specified length of NBYTES
6469 bytes. The string may include null characters. If M is 0, clear
6470 out any existing message, and let the mini-buffer text show
6471 through.
6472
6473 The buffer M must continue to exist until after the echo area gets
6474 cleared or some other message gets displayed there. This means do
6475 not pass text that is stored in a Lisp string; do not pass text in
6476 a buffer that was alloca'd. */
6477
6478 void
6479 message2 (m, nbytes, multibyte)
6480 const char *m;
6481 int nbytes;
6482 int multibyte;
6483 {
6484 /* First flush out any partial line written with print. */
6485 message_log_maybe_newline ();
6486 if (m)
6487 message_dolog (m, nbytes, 1, multibyte);
6488 message2_nolog (m, nbytes, multibyte);
6489 }
6490
6491
6492 /* The non-logging counterpart of message2. */
6493
6494 void
6495 message2_nolog (m, nbytes, multibyte)
6496 const char *m;
6497 int nbytes, multibyte;
6498 {
6499 struct frame *sf = SELECTED_FRAME ();
6500 message_enable_multibyte = multibyte;
6501
6502 if (noninteractive)
6503 {
6504 if (noninteractive_need_newline)
6505 putc ('\n', stderr);
6506 noninteractive_need_newline = 0;
6507 if (m)
6508 fwrite (m, nbytes, 1, stderr);
6509 if (cursor_in_echo_area == 0)
6510 fprintf (stderr, "\n");
6511 fflush (stderr);
6512 }
6513 /* A null message buffer means that the frame hasn't really been
6514 initialized yet. Error messages get reported properly by
6515 cmd_error, so this must be just an informative message; toss it. */
6516 else if (INTERACTIVE
6517 && sf->glyphs_initialized_p
6518 && FRAME_MESSAGE_BUF (sf))
6519 {
6520 Lisp_Object mini_window;
6521 struct frame *f;
6522
6523 /* Get the frame containing the mini-buffer
6524 that the selected frame is using. */
6525 mini_window = FRAME_MINIBUF_WINDOW (sf);
6526 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6527
6528 FRAME_SAMPLE_VISIBILITY (f);
6529 if (FRAME_VISIBLE_P (sf)
6530 && ! FRAME_VISIBLE_P (f))
6531 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6532
6533 if (m)
6534 {
6535 set_message (m, Qnil, nbytes, multibyte);
6536 if (minibuffer_auto_raise)
6537 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6538 }
6539 else
6540 clear_message (1, 1);
6541
6542 do_pending_window_change (0);
6543 echo_area_display (1);
6544 do_pending_window_change (0);
6545 if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
6546 (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f);
6547 }
6548 }
6549
6550
6551 /* Display an echo area message M with a specified length of NBYTES
6552 bytes. The string may include null characters. If M is not a
6553 string, clear out any existing message, and let the mini-buffer
6554 text show through. */
6555
6556 void
6557 message3 (m, nbytes, multibyte)
6558 Lisp_Object m;
6559 int nbytes;
6560 int multibyte;
6561 {
6562 struct gcpro gcpro1;
6563
6564 GCPRO1 (m);
6565
6566 /* First flush out any partial line written with print. */
6567 message_log_maybe_newline ();
6568 if (STRINGP (m))
6569 message_dolog (SDATA (m), nbytes, 1, multibyte);
6570 message3_nolog (m, nbytes, multibyte);
6571
6572 UNGCPRO;
6573 }
6574
6575
6576 /* The non-logging version of message3. */
6577
6578 void
6579 message3_nolog (m, nbytes, multibyte)
6580 Lisp_Object m;
6581 int nbytes, multibyte;
6582 {
6583 struct frame *sf = SELECTED_FRAME ();
6584 message_enable_multibyte = multibyte;
6585
6586 if (noninteractive)
6587 {
6588 if (noninteractive_need_newline)
6589 putc ('\n', stderr);
6590 noninteractive_need_newline = 0;
6591 if (STRINGP (m))
6592 fwrite (SDATA (m), nbytes, 1, stderr);
6593 if (cursor_in_echo_area == 0)
6594 fprintf (stderr, "\n");
6595 fflush (stderr);
6596 }
6597 /* A null message buffer means that the frame hasn't really been
6598 initialized yet. Error messages get reported properly by
6599 cmd_error, so this must be just an informative message; toss it. */
6600 else if (INTERACTIVE
6601 && sf->glyphs_initialized_p
6602 && FRAME_MESSAGE_BUF (sf))
6603 {
6604 Lisp_Object mini_window;
6605 Lisp_Object frame;
6606 struct frame *f;
6607
6608 /* Get the frame containing the mini-buffer
6609 that the selected frame is using. */
6610 mini_window = FRAME_MINIBUF_WINDOW (sf);
6611 frame = XWINDOW (mini_window)->frame;
6612 f = XFRAME (frame);
6613
6614 FRAME_SAMPLE_VISIBILITY (f);
6615 if (FRAME_VISIBLE_P (sf)
6616 && !FRAME_VISIBLE_P (f))
6617 Fmake_frame_visible (frame);
6618
6619 if (STRINGP (m) && SCHARS (m) > 0)
6620 {
6621 set_message (NULL, m, nbytes, multibyte);
6622 if (minibuffer_auto_raise)
6623 Fraise_frame (frame);
6624 }
6625 else
6626 clear_message (1, 1);
6627
6628 do_pending_window_change (0);
6629 echo_area_display (1);
6630 do_pending_window_change (0);
6631 if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
6632 (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f);
6633 }
6634 }
6635
6636
6637 /* Display a null-terminated echo area message M. If M is 0, clear
6638 out any existing message, and let the mini-buffer text show through.
6639
6640 The buffer M must continue to exist until after the echo area gets
6641 cleared or some other message gets displayed there. Do not pass
6642 text that is stored in a Lisp string. Do not pass text in a buffer
6643 that was alloca'd. */
6644
6645 void
6646 message1 (m)
6647 char *m;
6648 {
6649 message2 (m, (m ? strlen (m) : 0), 0);
6650 }
6651
6652
6653 /* The non-logging counterpart of message1. */
6654
6655 void
6656 message1_nolog (m)
6657 char *m;
6658 {
6659 message2_nolog (m, (m ? strlen (m) : 0), 0);
6660 }
6661
6662 /* Display a message M which contains a single %s
6663 which gets replaced with STRING. */
6664
6665 void
6666 message_with_string (m, string, log)
6667 char *m;
6668 Lisp_Object string;
6669 int log;
6670 {
6671 CHECK_STRING (string);
6672
6673 if (noninteractive)
6674 {
6675 if (m)
6676 {
6677 if (noninteractive_need_newline)
6678 putc ('\n', stderr);
6679 noninteractive_need_newline = 0;
6680 fprintf (stderr, m, SDATA (string));
6681 if (cursor_in_echo_area == 0)
6682 fprintf (stderr, "\n");
6683 fflush (stderr);
6684 }
6685 }
6686 else if (INTERACTIVE)
6687 {
6688 /* The frame whose minibuffer we're going to display the message on.
6689 It may be larger than the selected frame, so we need
6690 to use its buffer, not the selected frame's buffer. */
6691 Lisp_Object mini_window;
6692 struct frame *f, *sf = SELECTED_FRAME ();
6693
6694 /* Get the frame containing the minibuffer
6695 that the selected frame is using. */
6696 mini_window = FRAME_MINIBUF_WINDOW (sf);
6697 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6698
6699 /* A null message buffer means that the frame hasn't really been
6700 initialized yet. Error messages get reported properly by
6701 cmd_error, so this must be just an informative message; toss it. */
6702 if (FRAME_MESSAGE_BUF (f))
6703 {
6704 Lisp_Object args[2], message;
6705 struct gcpro gcpro1, gcpro2;
6706
6707 args[0] = build_string (m);
6708 args[1] = message = string;
6709 GCPRO2 (args[0], message);
6710 gcpro1.nvars = 2;
6711
6712 message = Fformat (2, args);
6713
6714 if (log)
6715 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6716 else
6717 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6718
6719 UNGCPRO;
6720
6721 /* Print should start at the beginning of the message
6722 buffer next time. */
6723 message_buf_print = 0;
6724 }
6725 }
6726 }
6727
6728
6729 /* Dump an informative message to the minibuf. If M is 0, clear out
6730 any existing message, and let the mini-buffer text show through. */
6731
6732 /* VARARGS 1 */
6733 void
6734 message (m, a1, a2, a3)
6735 char *m;
6736 EMACS_INT a1, a2, a3;
6737 {
6738 if (noninteractive)
6739 {
6740 if (m)
6741 {
6742 if (noninteractive_need_newline)
6743 putc ('\n', stderr);
6744 noninteractive_need_newline = 0;
6745 fprintf (stderr, m, a1, a2, a3);
6746 if (cursor_in_echo_area == 0)
6747 fprintf (stderr, "\n");
6748 fflush (stderr);
6749 }
6750 }
6751 else if (INTERACTIVE)
6752 {
6753 /* The frame whose mini-buffer we're going to display the message
6754 on. It may be larger than the selected frame, so we need to
6755 use its buffer, not the selected frame's buffer. */
6756 Lisp_Object mini_window;
6757 struct frame *f, *sf = SELECTED_FRAME ();
6758
6759 /* Get the frame containing the mini-buffer
6760 that the selected frame is using. */
6761 mini_window = FRAME_MINIBUF_WINDOW (sf);
6762 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6763
6764 /* A null message buffer means that the frame hasn't really been
6765 initialized yet. Error messages get reported properly by
6766 cmd_error, so this must be just an informative message; toss
6767 it. */
6768 if (FRAME_MESSAGE_BUF (f))
6769 {
6770 if (m)
6771 {
6772 int len;
6773 #ifdef NO_ARG_ARRAY
6774 char *a[3];
6775 a[0] = (char *) a1;
6776 a[1] = (char *) a2;
6777 a[2] = (char *) a3;
6778
6779 len = doprnt (FRAME_MESSAGE_BUF (f),
6780 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6781 #else
6782 len = doprnt (FRAME_MESSAGE_BUF (f),
6783 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6784 (char **) &a1);
6785 #endif /* NO_ARG_ARRAY */
6786
6787 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6788 }
6789 else
6790 message1 (0);
6791
6792 /* Print should start at the beginning of the message
6793 buffer next time. */
6794 message_buf_print = 0;
6795 }
6796 }
6797 }
6798
6799
6800 /* The non-logging version of message. */
6801
6802 void
6803 message_nolog (m, a1, a2, a3)
6804 char *m;
6805 EMACS_INT a1, a2, a3;
6806 {
6807 Lisp_Object old_log_max;
6808 old_log_max = Vmessage_log_max;
6809 Vmessage_log_max = Qnil;
6810 message (m, a1, a2, a3);
6811 Vmessage_log_max = old_log_max;
6812 }
6813
6814
6815 /* Display the current message in the current mini-buffer. This is
6816 only called from error handlers in process.c, and is not time
6817 critical. */
6818
6819 void
6820 update_echo_area ()
6821 {
6822 if (!NILP (echo_area_buffer[0]))
6823 {
6824 Lisp_Object string;
6825 string = Fcurrent_message ();
6826 message3 (string, SBYTES (string),
6827 !NILP (current_buffer->enable_multibyte_characters));
6828 }
6829 }
6830
6831
6832 /* Make sure echo area buffers in `echo_buffers' are live.
6833 If they aren't, make new ones. */
6834
6835 static void
6836 ensure_echo_area_buffers ()
6837 {
6838 int i;
6839
6840 for (i = 0; i < 2; ++i)
6841 if (!BUFFERP (echo_buffer[i])
6842 || NILP (XBUFFER (echo_buffer[i])->name))
6843 {
6844 char name[30];
6845 Lisp_Object old_buffer;
6846 int j;
6847
6848 old_buffer = echo_buffer[i];
6849 sprintf (name, " *Echo Area %d*", i);
6850 echo_buffer[i] = Fget_buffer_create (build_string (name));
6851 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6852
6853 for (j = 0; j < 2; ++j)
6854 if (EQ (old_buffer, echo_area_buffer[j]))
6855 echo_area_buffer[j] = echo_buffer[i];
6856 }
6857 }
6858
6859
6860 /* Call FN with args A1..A4 with either the current or last displayed
6861 echo_area_buffer as current buffer.
6862
6863 WHICH zero means use the current message buffer
6864 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6865 from echo_buffer[] and clear it.
6866
6867 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6868 suitable buffer from echo_buffer[] and clear it.
6869
6870 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6871 that the current message becomes the last displayed one, make
6872 choose a suitable buffer for echo_area_buffer[0], and clear it.
6873
6874 Value is what FN returns. */
6875
6876 static int
6877 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6878 struct window *w;
6879 int which;
6880 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6881 EMACS_INT a1;
6882 Lisp_Object a2;
6883 EMACS_INT a3, a4;
6884 {
6885 Lisp_Object buffer;
6886 int this_one, the_other, clear_buffer_p, rc;
6887 int count = SPECPDL_INDEX ();
6888
6889 /* If buffers aren't live, make new ones. */
6890 ensure_echo_area_buffers ();
6891
6892 clear_buffer_p = 0;
6893
6894 if (which == 0)
6895 this_one = 0, the_other = 1;
6896 else if (which > 0)
6897 this_one = 1, the_other = 0;
6898 else
6899 {
6900 this_one = 0, the_other = 1;
6901 clear_buffer_p = 1;
6902
6903 /* We need a fresh one in case the current echo buffer equals
6904 the one containing the last displayed echo area message. */
6905 if (!NILP (echo_area_buffer[this_one])
6906 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6907 echo_area_buffer[this_one] = Qnil;
6908 }
6909
6910 /* Choose a suitable buffer from echo_buffer[] is we don't
6911 have one. */
6912 if (NILP (echo_area_buffer[this_one]))
6913 {
6914 echo_area_buffer[this_one]
6915 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6916 ? echo_buffer[the_other]
6917 : echo_buffer[this_one]);
6918 clear_buffer_p = 1;
6919 }
6920
6921 buffer = echo_area_buffer[this_one];
6922
6923 /* Don't get confused by reusing the buffer used for echoing
6924 for a different purpose. */
6925 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6926 cancel_echoing ();
6927
6928 record_unwind_protect (unwind_with_echo_area_buffer,
6929 with_echo_area_buffer_unwind_data (w));
6930
6931 /* Make the echo area buffer current. Note that for display
6932 purposes, it is not necessary that the displayed window's buffer
6933 == current_buffer, except for text property lookup. So, let's
6934 only set that buffer temporarily here without doing a full
6935 Fset_window_buffer. We must also change w->pointm, though,
6936 because otherwise an assertions in unshow_buffer fails, and Emacs
6937 aborts. */
6938 set_buffer_internal_1 (XBUFFER (buffer));
6939 if (w)
6940 {
6941 w->buffer = buffer;
6942 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6943 }
6944
6945 current_buffer->undo_list = Qt;
6946 current_buffer->read_only = Qnil;
6947 specbind (Qinhibit_read_only, Qt);
6948 specbind (Qinhibit_modification_hooks, Qt);
6949
6950 if (clear_buffer_p && Z > BEG)
6951 del_range (BEG, Z);
6952
6953 xassert (BEGV >= BEG);
6954 xassert (ZV <= Z && ZV >= BEGV);
6955
6956 rc = fn (a1, a2, a3, a4);
6957
6958 xassert (BEGV >= BEG);
6959 xassert (ZV <= Z && ZV >= BEGV);
6960
6961 unbind_to (count, Qnil);
6962 return rc;
6963 }
6964
6965
6966 /* Save state that should be preserved around the call to the function
6967 FN called in with_echo_area_buffer. */
6968
6969 static Lisp_Object
6970 with_echo_area_buffer_unwind_data (w)
6971 struct window *w;
6972 {
6973 int i = 0;
6974 Lisp_Object vector;
6975
6976 /* Reduce consing by keeping one vector in
6977 Vwith_echo_area_save_vector. */
6978 vector = Vwith_echo_area_save_vector;
6979 Vwith_echo_area_save_vector = Qnil;
6980
6981 if (NILP (vector))
6982 vector = Fmake_vector (make_number (7), Qnil);
6983
6984 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6985 AREF (vector, i) = Vdeactivate_mark, ++i;
6986 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6987
6988 if (w)
6989 {
6990 XSETWINDOW (AREF (vector, i), w); ++i;
6991 AREF (vector, i) = w->buffer; ++i;
6992 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6993 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6994 }
6995 else
6996 {
6997 int end = i + 4;
6998 for (; i < end; ++i)
6999 AREF (vector, i) = Qnil;
7000 }
7001
7002 xassert (i == ASIZE (vector));
7003 return vector;
7004 }
7005
7006
7007 /* Restore global state from VECTOR which was created by
7008 with_echo_area_buffer_unwind_data. */
7009
7010 static Lisp_Object
7011 unwind_with_echo_area_buffer (vector)
7012 Lisp_Object vector;
7013 {
7014 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7015 Vdeactivate_mark = AREF (vector, 1);
7016 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7017
7018 if (WINDOWP (AREF (vector, 3)))
7019 {
7020 struct window *w;
7021 Lisp_Object buffer, charpos, bytepos;
7022
7023 w = XWINDOW (AREF (vector, 3));
7024 buffer = AREF (vector, 4);
7025 charpos = AREF (vector, 5);
7026 bytepos = AREF (vector, 6);
7027
7028 w->buffer = buffer;
7029 set_marker_both (w->pointm, buffer,
7030 XFASTINT (charpos), XFASTINT (bytepos));
7031 }
7032
7033 Vwith_echo_area_save_vector = vector;
7034 return Qnil;
7035 }
7036
7037
7038 /* Set up the echo area for use by print functions. MULTIBYTE_P
7039 non-zero means we will print multibyte. */
7040
7041 void
7042 setup_echo_area_for_printing (multibyte_p)
7043 int multibyte_p;
7044 {
7045 /* If we can't find an echo area any more, exit. */
7046 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7047 Fkill_emacs (Qnil);
7048
7049 ensure_echo_area_buffers ();
7050
7051 if (!message_buf_print)
7052 {
7053 /* A message has been output since the last time we printed.
7054 Choose a fresh echo area buffer. */
7055 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7056 echo_area_buffer[0] = echo_buffer[1];
7057 else
7058 echo_area_buffer[0] = echo_buffer[0];
7059
7060 /* Switch to that buffer and clear it. */
7061 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7062 current_buffer->truncate_lines = Qnil;
7063
7064 if (Z > BEG)
7065 {
7066 int count = SPECPDL_INDEX ();
7067 specbind (Qinhibit_read_only, Qt);
7068 /* Note that undo recording is always disabled. */
7069 del_range (BEG, Z);
7070 unbind_to (count, Qnil);
7071 }
7072 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7073
7074 /* Set up the buffer for the multibyteness we need. */
7075 if (multibyte_p
7076 != !NILP (current_buffer->enable_multibyte_characters))
7077 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7078
7079 /* Raise the frame containing the echo area. */
7080 if (minibuffer_auto_raise)
7081 {
7082 struct frame *sf = SELECTED_FRAME ();
7083 Lisp_Object mini_window;
7084 mini_window = FRAME_MINIBUF_WINDOW (sf);
7085 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7086 }
7087
7088 message_log_maybe_newline ();
7089 message_buf_print = 1;
7090 }
7091 else
7092 {
7093 if (NILP (echo_area_buffer[0]))
7094 {
7095 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7096 echo_area_buffer[0] = echo_buffer[1];
7097 else
7098 echo_area_buffer[0] = echo_buffer[0];
7099 }
7100
7101 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7102 {
7103 /* Someone switched buffers between print requests. */
7104 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7105 current_buffer->truncate_lines = Qnil;
7106 }
7107 }
7108 }
7109
7110
7111 /* Display an echo area message in window W. Value is non-zero if W's
7112 height is changed. If display_last_displayed_message_p is
7113 non-zero, display the message that was last displayed, otherwise
7114 display the current message. */
7115
7116 static int
7117 display_echo_area (w)
7118 struct window *w;
7119 {
7120 int i, no_message_p, window_height_changed_p, count;
7121
7122 /* Temporarily disable garbage collections while displaying the echo
7123 area. This is done because a GC can print a message itself.
7124 That message would modify the echo area buffer's contents while a
7125 redisplay of the buffer is going on, and seriously confuse
7126 redisplay. */
7127 count = inhibit_garbage_collection ();
7128
7129 /* If there is no message, we must call display_echo_area_1
7130 nevertheless because it resizes the window. But we will have to
7131 reset the echo_area_buffer in question to nil at the end because
7132 with_echo_area_buffer will sets it to an empty buffer. */
7133 i = display_last_displayed_message_p ? 1 : 0;
7134 no_message_p = NILP (echo_area_buffer[i]);
7135
7136 window_height_changed_p
7137 = with_echo_area_buffer (w, display_last_displayed_message_p,
7138 display_echo_area_1,
7139 (EMACS_INT) w, Qnil, 0, 0);
7140
7141 if (no_message_p)
7142 echo_area_buffer[i] = Qnil;
7143
7144 unbind_to (count, Qnil);
7145 return window_height_changed_p;
7146 }
7147
7148
7149 /* Helper for display_echo_area. Display the current buffer which
7150 contains the current echo area message in window W, a mini-window,
7151 a pointer to which is passed in A1. A2..A4 are currently not used.
7152 Change the height of W so that all of the message is displayed.
7153 Value is non-zero if height of W was changed. */
7154
7155 static int
7156 display_echo_area_1 (a1, a2, a3, a4)
7157 EMACS_INT a1;
7158 Lisp_Object a2;
7159 EMACS_INT a3, a4;
7160 {
7161 struct window *w = (struct window *) a1;
7162 Lisp_Object window;
7163 struct text_pos start;
7164 int window_height_changed_p = 0;
7165
7166 /* Do this before displaying, so that we have a large enough glyph
7167 matrix for the display. */
7168 window_height_changed_p = resize_mini_window (w, 0);
7169
7170 /* Display. */
7171 clear_glyph_matrix (w->desired_matrix);
7172 XSETWINDOW (window, w);
7173 SET_TEXT_POS (start, BEG, BEG_BYTE);
7174 try_window (window, start);
7175
7176 return window_height_changed_p;
7177 }
7178
7179
7180 /* Resize the echo area window to exactly the size needed for the
7181 currently displayed message, if there is one. If a mini-buffer
7182 is active, don't shrink it. */
7183
7184 void
7185 resize_echo_area_exactly ()
7186 {
7187 if (BUFFERP (echo_area_buffer[0])
7188 && WINDOWP (echo_area_window))
7189 {
7190 struct window *w = XWINDOW (echo_area_window);
7191 int resized_p;
7192 Lisp_Object resize_exactly;
7193
7194 if (minibuf_level == 0)
7195 resize_exactly = Qt;
7196 else
7197 resize_exactly = Qnil;
7198
7199 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7200 (EMACS_INT) w, resize_exactly, 0, 0);
7201 if (resized_p)
7202 {
7203 ++windows_or_buffers_changed;
7204 ++update_mode_lines;
7205 redisplay_internal (0);
7206 }
7207 }
7208 }
7209
7210
7211 /* Callback function for with_echo_area_buffer, when used from
7212 resize_echo_area_exactly. A1 contains a pointer to the window to
7213 resize, EXACTLY non-nil means resize the mini-window exactly to the
7214 size of the text displayed. A3 and A4 are not used. Value is what
7215 resize_mini_window returns. */
7216
7217 static int
7218 resize_mini_window_1 (a1, exactly, a3, a4)
7219 EMACS_INT a1;
7220 Lisp_Object exactly;
7221 EMACS_INT a3, a4;
7222 {
7223 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7224 }
7225
7226
7227 /* Resize mini-window W to fit the size of its contents. EXACT:P
7228 means size the window exactly to the size needed. Otherwise, it's
7229 only enlarged until W's buffer is empty. Value is non-zero if
7230 the window height has been changed. */
7231
7232 int
7233 resize_mini_window (w, exact_p)
7234 struct window *w;
7235 int exact_p;
7236 {
7237 struct frame *f = XFRAME (w->frame);
7238 int window_height_changed_p = 0;
7239
7240 xassert (MINI_WINDOW_P (w));
7241
7242 /* Don't resize windows while redisplaying a window; it would
7243 confuse redisplay functions when the size of the window they are
7244 displaying changes from under them. Such a resizing can happen,
7245 for instance, when which-func prints a long message while
7246 we are running fontification-functions. We're running these
7247 functions with safe_call which binds inhibit-redisplay to t. */
7248 if (!NILP (Vinhibit_redisplay))
7249 return 0;
7250
7251 /* Nil means don't try to resize. */
7252 if (NILP (Vresize_mini_windows)
7253 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7254 return 0;
7255
7256 if (!FRAME_MINIBUF_ONLY_P (f))
7257 {
7258 struct it it;
7259 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7260 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7261 int height, max_height;
7262 int unit = FRAME_LINE_HEIGHT (f);
7263 struct text_pos start;
7264 struct buffer *old_current_buffer = NULL;
7265
7266 if (current_buffer != XBUFFER (w->buffer))
7267 {
7268 old_current_buffer = current_buffer;
7269 set_buffer_internal (XBUFFER (w->buffer));
7270 }
7271
7272 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7273
7274 /* Compute the max. number of lines specified by the user. */
7275 if (FLOATP (Vmax_mini_window_height))
7276 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7277 else if (INTEGERP (Vmax_mini_window_height))
7278 max_height = XINT (Vmax_mini_window_height);
7279 else
7280 max_height = total_height / 4;
7281
7282 /* Correct that max. height if it's bogus. */
7283 max_height = max (1, max_height);
7284 max_height = min (total_height, max_height);
7285
7286 /* Find out the height of the text in the window. */
7287 if (it.truncate_lines_p)
7288 height = 1;
7289 else
7290 {
7291 last_height = 0;
7292 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7293 if (it.max_ascent == 0 && it.max_descent == 0)
7294 height = it.current_y + last_height;
7295 else
7296 height = it.current_y + it.max_ascent + it.max_descent;
7297 height -= it.extra_line_spacing;
7298 height = (height + unit - 1) / unit;
7299 }
7300
7301 /* Compute a suitable window start. */
7302 if (height > max_height)
7303 {
7304 height = max_height;
7305 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7306 move_it_vertically_backward (&it, (height - 1) * unit);
7307 start = it.current.pos;
7308 }
7309 else
7310 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7311 SET_MARKER_FROM_TEXT_POS (w->start, start);
7312
7313 if (EQ (Vresize_mini_windows, Qgrow_only))
7314 {
7315 /* Let it grow only, until we display an empty message, in which
7316 case the window shrinks again. */
7317 if (height > WINDOW_TOTAL_LINES (w))
7318 {
7319 int old_height = WINDOW_TOTAL_LINES (w);
7320 freeze_window_starts (f, 1);
7321 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7322 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7323 }
7324 else if (height < WINDOW_TOTAL_LINES (w)
7325 && (exact_p || BEGV == ZV))
7326 {
7327 int old_height = WINDOW_TOTAL_LINES (w);
7328 freeze_window_starts (f, 0);
7329 shrink_mini_window (w);
7330 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7331 }
7332 }
7333 else
7334 {
7335 /* Always resize to exact size needed. */
7336 if (height > WINDOW_TOTAL_LINES (w))
7337 {
7338 int old_height = WINDOW_TOTAL_LINES (w);
7339 freeze_window_starts (f, 1);
7340 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7341 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7342 }
7343 else if (height < WINDOW_TOTAL_LINES (w))
7344 {
7345 int old_height = WINDOW_TOTAL_LINES (w);
7346 freeze_window_starts (f, 0);
7347 shrink_mini_window (w);
7348
7349 if (height)
7350 {
7351 freeze_window_starts (f, 1);
7352 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7353 }
7354
7355 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7356 }
7357 }
7358
7359 if (old_current_buffer)
7360 set_buffer_internal (old_current_buffer);
7361 }
7362
7363 return window_height_changed_p;
7364 }
7365
7366
7367 /* Value is the current message, a string, or nil if there is no
7368 current message. */
7369
7370 Lisp_Object
7371 current_message ()
7372 {
7373 Lisp_Object msg;
7374
7375 if (NILP (echo_area_buffer[0]))
7376 msg = Qnil;
7377 else
7378 {
7379 with_echo_area_buffer (0, 0, current_message_1,
7380 (EMACS_INT) &msg, Qnil, 0, 0);
7381 if (NILP (msg))
7382 echo_area_buffer[0] = Qnil;
7383 }
7384
7385 return msg;
7386 }
7387
7388
7389 static int
7390 current_message_1 (a1, a2, a3, a4)
7391 EMACS_INT a1;
7392 Lisp_Object a2;
7393 EMACS_INT a3, a4;
7394 {
7395 Lisp_Object *msg = (Lisp_Object *) a1;
7396
7397 if (Z > BEG)
7398 *msg = make_buffer_string (BEG, Z, 1);
7399 else
7400 *msg = Qnil;
7401 return 0;
7402 }
7403
7404
7405 /* Push the current message on Vmessage_stack for later restauration
7406 by restore_message. Value is non-zero if the current message isn't
7407 empty. This is a relatively infrequent operation, so it's not
7408 worth optimizing. */
7409
7410 int
7411 push_message ()
7412 {
7413 Lisp_Object msg;
7414 msg = current_message ();
7415 Vmessage_stack = Fcons (msg, Vmessage_stack);
7416 return STRINGP (msg);
7417 }
7418
7419
7420 /* Restore message display from the top of Vmessage_stack. */
7421
7422 void
7423 restore_message ()
7424 {
7425 Lisp_Object msg;
7426
7427 xassert (CONSP (Vmessage_stack));
7428 msg = XCAR (Vmessage_stack);
7429 if (STRINGP (msg))
7430 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7431 else
7432 message3_nolog (msg, 0, 0);
7433 }
7434
7435
7436 /* Handler for record_unwind_protect calling pop_message. */
7437
7438 Lisp_Object
7439 pop_message_unwind (dummy)
7440 Lisp_Object dummy;
7441 {
7442 pop_message ();
7443 return Qnil;
7444 }
7445
7446 /* Pop the top-most entry off Vmessage_stack. */
7447
7448 void
7449 pop_message ()
7450 {
7451 xassert (CONSP (Vmessage_stack));
7452 Vmessage_stack = XCDR (Vmessage_stack);
7453 }
7454
7455
7456 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7457 exits. If the stack is not empty, we have a missing pop_message
7458 somewhere. */
7459
7460 void
7461 check_message_stack ()
7462 {
7463 if (!NILP (Vmessage_stack))
7464 abort ();
7465 }
7466
7467
7468 /* Truncate to NCHARS what will be displayed in the echo area the next
7469 time we display it---but don't redisplay it now. */
7470
7471 void
7472 truncate_echo_area (nchars)
7473 int nchars;
7474 {
7475 if (nchars == 0)
7476 echo_area_buffer[0] = Qnil;
7477 /* A null message buffer means that the frame hasn't really been
7478 initialized yet. Error messages get reported properly by
7479 cmd_error, so this must be just an informative message; toss it. */
7480 else if (!noninteractive
7481 && INTERACTIVE
7482 && !NILP (echo_area_buffer[0]))
7483 {
7484 struct frame *sf = SELECTED_FRAME ();
7485 if (FRAME_MESSAGE_BUF (sf))
7486 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7487 }
7488 }
7489
7490
7491 /* Helper function for truncate_echo_area. Truncate the current
7492 message to at most NCHARS characters. */
7493
7494 static int
7495 truncate_message_1 (nchars, a2, a3, a4)
7496 EMACS_INT nchars;
7497 Lisp_Object a2;
7498 EMACS_INT a3, a4;
7499 {
7500 if (BEG + nchars < Z)
7501 del_range (BEG + nchars, Z);
7502 if (Z == BEG)
7503 echo_area_buffer[0] = Qnil;
7504 return 0;
7505 }
7506
7507
7508 /* Set the current message to a substring of S or STRING.
7509
7510 If STRING is a Lisp string, set the message to the first NBYTES
7511 bytes from STRING. NBYTES zero means use the whole string. If
7512 STRING is multibyte, the message will be displayed multibyte.
7513
7514 If S is not null, set the message to the first LEN bytes of S. LEN
7515 zero means use the whole string. MULTIBYTE_P non-zero means S is
7516 multibyte. Display the message multibyte in that case. */
7517
7518 void
7519 set_message (s, string, nbytes, multibyte_p)
7520 const char *s;
7521 Lisp_Object string;
7522 int nbytes, multibyte_p;
7523 {
7524 message_enable_multibyte
7525 = ((s && multibyte_p)
7526 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7527
7528 with_echo_area_buffer (0, -1, set_message_1,
7529 (EMACS_INT) s, string, nbytes, multibyte_p);
7530 message_buf_print = 0;
7531 help_echo_showing_p = 0;
7532 }
7533
7534
7535 /* Helper function for set_message. Arguments have the same meaning
7536 as there, with A1 corresponding to S and A2 corresponding to STRING
7537 This function is called with the echo area buffer being
7538 current. */
7539
7540 static int
7541 set_message_1 (a1, a2, nbytes, multibyte_p)
7542 EMACS_INT a1;
7543 Lisp_Object a2;
7544 EMACS_INT nbytes, multibyte_p;
7545 {
7546 const char *s = (const char *) a1;
7547 Lisp_Object string = a2;
7548
7549 xassert (BEG == Z);
7550
7551 /* Change multibyteness of the echo buffer appropriately. */
7552 if (message_enable_multibyte
7553 != !NILP (current_buffer->enable_multibyte_characters))
7554 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7555
7556 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7557
7558 /* Insert new message at BEG. */
7559 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7560
7561 if (STRINGP (string))
7562 {
7563 int nchars;
7564
7565 if (nbytes == 0)
7566 nbytes = SBYTES (string);
7567 nchars = string_byte_to_char (string, nbytes);
7568
7569 /* This function takes care of single/multibyte conversion. We
7570 just have to ensure that the echo area buffer has the right
7571 setting of enable_multibyte_characters. */
7572 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7573 }
7574 else if (s)
7575 {
7576 if (nbytes == 0)
7577 nbytes = strlen (s);
7578
7579 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7580 {
7581 /* Convert from multi-byte to single-byte. */
7582 int i, c, n;
7583 unsigned char work[1];
7584
7585 /* Convert a multibyte string to single-byte. */
7586 for (i = 0; i < nbytes; i += n)
7587 {
7588 c = string_char_and_length (s + i, nbytes - i, &n);
7589 work[0] = (SINGLE_BYTE_CHAR_P (c)
7590 ? c
7591 : multibyte_char_to_unibyte (c, Qnil));
7592 insert_1_both (work, 1, 1, 1, 0, 0);
7593 }
7594 }
7595 else if (!multibyte_p
7596 && !NILP (current_buffer->enable_multibyte_characters))
7597 {
7598 /* Convert from single-byte to multi-byte. */
7599 int i, c, n;
7600 const unsigned char *msg = (const unsigned char *) s;
7601 unsigned char str[MAX_MULTIBYTE_LENGTH];
7602
7603 /* Convert a single-byte string to multibyte. */
7604 for (i = 0; i < nbytes; i++)
7605 {
7606 c = unibyte_char_to_multibyte (msg[i]);
7607 n = CHAR_STRING (c, str);
7608 insert_1_both (str, 1, n, 1, 0, 0);
7609 }
7610 }
7611 else
7612 insert_1 (s, nbytes, 1, 0, 0);
7613 }
7614
7615 return 0;
7616 }
7617
7618
7619 /* Clear messages. CURRENT_P non-zero means clear the current
7620 message. LAST_DISPLAYED_P non-zero means clear the message
7621 last displayed. */
7622
7623 void
7624 clear_message (current_p, last_displayed_p)
7625 int current_p, last_displayed_p;
7626 {
7627 if (current_p)
7628 {
7629 echo_area_buffer[0] = Qnil;
7630 message_cleared_p = 1;
7631 }
7632
7633 if (last_displayed_p)
7634 echo_area_buffer[1] = Qnil;
7635
7636 message_buf_print = 0;
7637 }
7638
7639 /* Clear garbaged frames.
7640
7641 This function is used where the old redisplay called
7642 redraw_garbaged_frames which in turn called redraw_frame which in
7643 turn called clear_frame. The call to clear_frame was a source of
7644 flickering. I believe a clear_frame is not necessary. It should
7645 suffice in the new redisplay to invalidate all current matrices,
7646 and ensure a complete redisplay of all windows. */
7647
7648 static void
7649 clear_garbaged_frames ()
7650 {
7651 if (frame_garbaged)
7652 {
7653 Lisp_Object tail, frame;
7654 int changed_count = 0;
7655
7656 FOR_EACH_FRAME (tail, frame)
7657 {
7658 struct frame *f = XFRAME (frame);
7659
7660 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7661 {
7662 if (f->resized_p)
7663 {
7664 Fredraw_frame (frame);
7665 f->force_flush_display_p = 1;
7666 }
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 the initial terminal
7707 frame. If we let this through, a message would be displayed on
7708 the terminal. */
7709 if (FRAME_TERMCAP_P (XFRAME (selected_frame))
7710 && FRAME_TTY (XFRAME (selected_frame))->type == NULL)
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 FRAME_RIF (f)->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 (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
8223 FRAME_RIF (SELECTED_FRAME ())->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;
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, 0, 0, &area);
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 Horizontal scrolling
8982 ************************************************************************/
8983
8984 static int hscroll_window_tree P_ ((Lisp_Object));
8985 static int hscroll_windows P_ ((Lisp_Object));
8986
8987 /* For all leaf windows in the window tree rooted at WINDOW, set their
8988 hscroll value so that PT is (i) visible in the window, and (ii) so
8989 that it is not within a certain margin at the window's left and
8990 right border. Value is non-zero if any window's hscroll has been
8991 changed. */
8992
8993 static int
8994 hscroll_window_tree (window)
8995 Lisp_Object window;
8996 {
8997 int hscrolled_p = 0;
8998 int hscroll_relative_p = FLOATP (Vhscroll_step);
8999 int hscroll_step_abs = 0;
9000 double hscroll_step_rel = 0;
9001
9002 if (hscroll_relative_p)
9003 {
9004 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9005 if (hscroll_step_rel < 0)
9006 {
9007 hscroll_relative_p = 0;
9008 hscroll_step_abs = 0;
9009 }
9010 }
9011 else if (INTEGERP (Vhscroll_step))
9012 {
9013 hscroll_step_abs = XINT (Vhscroll_step);
9014 if (hscroll_step_abs < 0)
9015 hscroll_step_abs = 0;
9016 }
9017 else
9018 hscroll_step_abs = 0;
9019
9020 while (WINDOWP (window))
9021 {
9022 struct window *w = XWINDOW (window);
9023
9024 if (WINDOWP (w->hchild))
9025 hscrolled_p |= hscroll_window_tree (w->hchild);
9026 else if (WINDOWP (w->vchild))
9027 hscrolled_p |= hscroll_window_tree (w->vchild);
9028 else if (w->cursor.vpos >= 0)
9029 {
9030 int h_margin;
9031 int text_area_width;
9032 struct glyph_row *current_cursor_row
9033 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9034 struct glyph_row *desired_cursor_row
9035 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9036 struct glyph_row *cursor_row
9037 = (desired_cursor_row->enabled_p
9038 ? desired_cursor_row
9039 : current_cursor_row);
9040
9041 text_area_width = window_box_width (w, TEXT_AREA);
9042
9043 /* Scroll when cursor is inside this scroll margin. */
9044 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9045
9046 if ((XFASTINT (w->hscroll)
9047 && w->cursor.x <= h_margin)
9048 || (cursor_row->enabled_p
9049 && cursor_row->truncated_on_right_p
9050 && (w->cursor.x >= text_area_width - h_margin)))
9051 {
9052 struct it it;
9053 int hscroll;
9054 struct buffer *saved_current_buffer;
9055 int pt;
9056 int wanted_x;
9057
9058 /* Find point in a display of infinite width. */
9059 saved_current_buffer = current_buffer;
9060 current_buffer = XBUFFER (w->buffer);
9061
9062 if (w == XWINDOW (selected_window))
9063 pt = BUF_PT (current_buffer);
9064 else
9065 {
9066 pt = marker_position (w->pointm);
9067 pt = max (BEGV, pt);
9068 pt = min (ZV, pt);
9069 }
9070
9071 /* Move iterator to pt starting at cursor_row->start in
9072 a line with infinite width. */
9073 init_to_row_start (&it, w, cursor_row);
9074 it.last_visible_x = INFINITY;
9075 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9076 current_buffer = saved_current_buffer;
9077
9078 /* Position cursor in window. */
9079 if (!hscroll_relative_p && hscroll_step_abs == 0)
9080 hscroll = max (0, (it.current_x
9081 - (ITERATOR_AT_END_OF_LINE_P (&it)
9082 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9083 : (text_area_width / 2))))
9084 / FRAME_COLUMN_WIDTH (it.f);
9085 else if (w->cursor.x >= text_area_width - h_margin)
9086 {
9087 if (hscroll_relative_p)
9088 wanted_x = text_area_width * (1 - hscroll_step_rel)
9089 - h_margin;
9090 else
9091 wanted_x = text_area_width
9092 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9093 - h_margin;
9094 hscroll
9095 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9096 }
9097 else
9098 {
9099 if (hscroll_relative_p)
9100 wanted_x = text_area_width * hscroll_step_rel
9101 + h_margin;
9102 else
9103 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9104 + h_margin;
9105 hscroll
9106 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9107 }
9108 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9109
9110 /* Don't call Fset_window_hscroll if value hasn't
9111 changed because it will prevent redisplay
9112 optimizations. */
9113 if (XFASTINT (w->hscroll) != hscroll)
9114 {
9115 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9116 w->hscroll = make_number (hscroll);
9117 hscrolled_p = 1;
9118 }
9119 }
9120 }
9121
9122 window = w->next;
9123 }
9124
9125 /* Value is non-zero if hscroll of any leaf window has been changed. */
9126 return hscrolled_p;
9127 }
9128
9129
9130 /* Set hscroll so that cursor is visible and not inside horizontal
9131 scroll margins for all windows in the tree rooted at WINDOW. See
9132 also hscroll_window_tree above. Value is non-zero if any window's
9133 hscroll has been changed. If it has, desired matrices on the frame
9134 of WINDOW are cleared. */
9135
9136 static int
9137 hscroll_windows (window)
9138 Lisp_Object window;
9139 {
9140 int hscrolled_p;
9141
9142 if (automatic_hscrolling_p)
9143 {
9144 hscrolled_p = hscroll_window_tree (window);
9145 if (hscrolled_p)
9146 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9147 }
9148 else
9149 hscrolled_p = 0;
9150 return hscrolled_p;
9151 }
9152
9153
9154 \f
9155 /************************************************************************
9156 Redisplay
9157 ************************************************************************/
9158
9159 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9160 to a non-zero value. This is sometimes handy to have in a debugger
9161 session. */
9162
9163 #if GLYPH_DEBUG
9164
9165 /* First and last unchanged row for try_window_id. */
9166
9167 int debug_first_unchanged_at_end_vpos;
9168 int debug_last_unchanged_at_beg_vpos;
9169
9170 /* Delta vpos and y. */
9171
9172 int debug_dvpos, debug_dy;
9173
9174 /* Delta in characters and bytes for try_window_id. */
9175
9176 int debug_delta, debug_delta_bytes;
9177
9178 /* Values of window_end_pos and window_end_vpos at the end of
9179 try_window_id. */
9180
9181 EMACS_INT debug_end_pos, debug_end_vpos;
9182
9183 /* Append a string to W->desired_matrix->method. FMT is a printf
9184 format string. A1...A9 are a supplement for a variable-length
9185 argument list. If trace_redisplay_p is non-zero also printf the
9186 resulting string to stderr. */
9187
9188 static void
9189 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9190 struct window *w;
9191 char *fmt;
9192 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9193 {
9194 char buffer[512];
9195 char *method = w->desired_matrix->method;
9196 int len = strlen (method);
9197 int size = sizeof w->desired_matrix->method;
9198 int remaining = size - len - 1;
9199
9200 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9201 if (len && remaining)
9202 {
9203 method[len] = '|';
9204 --remaining, ++len;
9205 }
9206
9207 strncpy (method + len, buffer, remaining);
9208
9209 if (trace_redisplay_p)
9210 fprintf (stderr, "%p (%s): %s\n",
9211 w,
9212 ((BUFFERP (w->buffer)
9213 && STRINGP (XBUFFER (w->buffer)->name))
9214 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9215 : "no buffer"),
9216 buffer);
9217 }
9218
9219 #endif /* GLYPH_DEBUG */
9220
9221
9222 /* Value is non-zero if all changes in window W, which displays
9223 current_buffer, are in the text between START and END. START is a
9224 buffer position, END is given as a distance from Z. Used in
9225 redisplay_internal for display optimization. */
9226
9227 static INLINE int
9228 text_outside_line_unchanged_p (w, start, end)
9229 struct window *w;
9230 int start, end;
9231 {
9232 int unchanged_p = 1;
9233
9234 /* If text or overlays have changed, see where. */
9235 if (XFASTINT (w->last_modified) < MODIFF
9236 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9237 {
9238 /* Gap in the line? */
9239 if (GPT < start || Z - GPT < end)
9240 unchanged_p = 0;
9241
9242 /* Changes start in front of the line, or end after it? */
9243 if (unchanged_p
9244 && (BEG_UNCHANGED < start - 1
9245 || END_UNCHANGED < end))
9246 unchanged_p = 0;
9247
9248 /* If selective display, can't optimize if changes start at the
9249 beginning of the line. */
9250 if (unchanged_p
9251 && INTEGERP (current_buffer->selective_display)
9252 && XINT (current_buffer->selective_display) > 0
9253 && (BEG_UNCHANGED < start || GPT <= start))
9254 unchanged_p = 0;
9255
9256 /* If there are overlays at the start or end of the line, these
9257 may have overlay strings with newlines in them. A change at
9258 START, for instance, may actually concern the display of such
9259 overlay strings as well, and they are displayed on different
9260 lines. So, quickly rule out this case. (For the future, it
9261 might be desirable to implement something more telling than
9262 just BEG/END_UNCHANGED.) */
9263 if (unchanged_p)
9264 {
9265 if (BEG + BEG_UNCHANGED == start
9266 && overlay_touches_p (start))
9267 unchanged_p = 0;
9268 if (END_UNCHANGED == end
9269 && overlay_touches_p (Z - end))
9270 unchanged_p = 0;
9271 }
9272 }
9273
9274 return unchanged_p;
9275 }
9276
9277
9278 /* Do a frame update, taking possible shortcuts into account. This is
9279 the main external entry point for redisplay.
9280
9281 If the last redisplay displayed an echo area message and that message
9282 is no longer requested, we clear the echo area or bring back the
9283 mini-buffer if that is in use. */
9284
9285 void
9286 redisplay ()
9287 {
9288 redisplay_internal (0);
9289 }
9290
9291
9292 /* Return 1 if point moved out of or into a composition. Otherwise
9293 return 0. PREV_BUF and PREV_PT are the last point buffer and
9294 position. BUF and PT are the current point buffer and position. */
9295
9296 int
9297 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9298 struct buffer *prev_buf, *buf;
9299 int prev_pt, pt;
9300 {
9301 int start, end;
9302 Lisp_Object prop;
9303 Lisp_Object buffer;
9304
9305 XSETBUFFER (buffer, buf);
9306 /* Check a composition at the last point if point moved within the
9307 same buffer. */
9308 if (prev_buf == buf)
9309 {
9310 if (prev_pt == pt)
9311 /* Point didn't move. */
9312 return 0;
9313
9314 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9315 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9316 && COMPOSITION_VALID_P (start, end, prop)
9317 && start < prev_pt && end > prev_pt)
9318 /* The last point was within the composition. Return 1 iff
9319 point moved out of the composition. */
9320 return (pt <= start || pt >= end);
9321 }
9322
9323 /* Check a composition at the current point. */
9324 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9325 && find_composition (pt, -1, &start, &end, &prop, buffer)
9326 && COMPOSITION_VALID_P (start, end, prop)
9327 && start < pt && end > pt);
9328 }
9329
9330
9331 /* Reconsider the setting of B->clip_changed which is displayed
9332 in window W. */
9333
9334 static INLINE void
9335 reconsider_clip_changes (w, b)
9336 struct window *w;
9337 struct buffer *b;
9338 {
9339 if (b->clip_changed
9340 && !NILP (w->window_end_valid)
9341 && w->current_matrix->buffer == b
9342 && w->current_matrix->zv == BUF_ZV (b)
9343 && w->current_matrix->begv == BUF_BEGV (b))
9344 b->clip_changed = 0;
9345
9346 /* If display wasn't paused, and W is not a tool bar window, see if
9347 point has been moved into or out of a composition. In that case,
9348 we set b->clip_changed to 1 to force updating the screen. If
9349 b->clip_changed has already been set to 1, we can skip this
9350 check. */
9351 if (!b->clip_changed
9352 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9353 {
9354 int pt;
9355
9356 if (w == XWINDOW (selected_window))
9357 pt = BUF_PT (current_buffer);
9358 else
9359 pt = marker_position (w->pointm);
9360
9361 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9362 || pt != XINT (w->last_point))
9363 && check_point_in_composition (w->current_matrix->buffer,
9364 XINT (w->last_point),
9365 XBUFFER (w->buffer), pt))
9366 b->clip_changed = 1;
9367 }
9368 }
9369 \f
9370
9371 /* Select FRAME to forward the values of frame-local variables into C
9372 variables so that the redisplay routines can access those values
9373 directly. */
9374
9375 static void
9376 select_frame_for_redisplay (frame)
9377 Lisp_Object frame;
9378 {
9379 Lisp_Object tail, sym, val;
9380 Lisp_Object old = selected_frame;
9381
9382 selected_frame = frame;
9383
9384 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9385 if (CONSP (XCAR (tail))
9386 && (sym = XCAR (XCAR (tail)),
9387 SYMBOLP (sym))
9388 && (sym = indirect_variable (sym),
9389 val = SYMBOL_VALUE (sym),
9390 (BUFFER_LOCAL_VALUEP (val)
9391 || SOME_BUFFER_LOCAL_VALUEP (val)))
9392 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9393 Fsymbol_value (sym);
9394
9395 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9396 if (CONSP (XCAR (tail))
9397 && (sym = XCAR (XCAR (tail)),
9398 SYMBOLP (sym))
9399 && (sym = indirect_variable (sym),
9400 val = SYMBOL_VALUE (sym),
9401 (BUFFER_LOCAL_VALUEP (val)
9402 || SOME_BUFFER_LOCAL_VALUEP (val)))
9403 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9404 Fsymbol_value (sym);
9405 }
9406
9407
9408 #define STOP_POLLING \
9409 do { if (! polling_stopped_here) stop_polling (); \
9410 polling_stopped_here = 1; } while (0)
9411
9412 #define RESUME_POLLING \
9413 do { if (polling_stopped_here) start_polling (); \
9414 polling_stopped_here = 0; } while (0)
9415
9416
9417 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9418 response to any user action; therefore, we should preserve the echo
9419 area. (Actually, our caller does that job.) Perhaps in the future
9420 avoid recentering windows if it is not necessary; currently that
9421 causes some problems. */
9422
9423 static void
9424 redisplay_internal (preserve_echo_area)
9425 int preserve_echo_area;
9426 {
9427 struct window *w = XWINDOW (selected_window);
9428 struct frame *f = XFRAME (w->frame);
9429 int pause;
9430 int must_finish = 0;
9431 struct text_pos tlbufpos, tlendpos;
9432 int number_of_visible_frames;
9433 int count;
9434 struct frame *sf = SELECTED_FRAME ();
9435 int polling_stopped_here = 0;
9436
9437 /* Non-zero means redisplay has to consider all windows on all
9438 frames. Zero means, only selected_window is considered. */
9439 int consider_all_windows_p;
9440
9441 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9442
9443 /* No redisplay if running in batch mode or frame is not yet fully
9444 initialized, or redisplay is explicitly turned off by setting
9445 Vinhibit_redisplay. */
9446 if (noninteractive
9447 || !NILP (Vinhibit_redisplay)
9448 || !f->glyphs_initialized_p)
9449 return;
9450
9451 /* The flag redisplay_performed_directly_p is set by
9452 direct_output_for_insert when it already did the whole screen
9453 update necessary. */
9454 if (redisplay_performed_directly_p)
9455 {
9456 redisplay_performed_directly_p = 0;
9457 if (!hscroll_windows (selected_window))
9458 return;
9459 }
9460
9461 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9462 if (popup_activated ())
9463 return;
9464 #endif
9465
9466 /* I don't think this happens but let's be paranoid. */
9467 if (redisplaying_p)
9468 return;
9469
9470 /* Record a function that resets redisplaying_p to its old value
9471 when we leave this function. */
9472 count = SPECPDL_INDEX ();
9473 record_unwind_protect (unwind_redisplay,
9474 Fcons (make_number (redisplaying_p), selected_frame));
9475 ++redisplaying_p;
9476 specbind (Qinhibit_free_realized_faces, Qnil);
9477
9478 retry:
9479 pause = 0;
9480 reconsider_clip_changes (w, current_buffer);
9481
9482 /* If new fonts have been loaded that make a glyph matrix adjustment
9483 necessary, do it. */
9484 if (fonts_changed_p)
9485 {
9486 adjust_glyphs (NULL);
9487 ++windows_or_buffers_changed;
9488 fonts_changed_p = 0;
9489 }
9490
9491 /* If face_change_count is non-zero, init_iterator will free all
9492 realized faces, which includes the faces referenced from current
9493 matrices. So, we can't reuse current matrices in this case. */
9494 if (face_change_count)
9495 ++windows_or_buffers_changed;
9496
9497 if (FRAME_TERMCAP_P (sf)
9498 && FRAME_TTY (sf)->previous_terminal_frame != sf)
9499 {
9500 /* Since frames on a single ASCII terminal share the same
9501 display area, displaying a different frame means redisplay
9502 the whole thing. */
9503 windows_or_buffers_changed++;
9504 SET_FRAME_GARBAGED (sf);
9505 FRAME_TTY (sf)->previous_terminal_frame = sf;
9506 }
9507
9508 /* Set the visible flags for all frames. Do this before checking
9509 for resized or garbaged frames; they want to know if their frames
9510 are visible. See the comment in frame.h for
9511 FRAME_SAMPLE_VISIBILITY. */
9512 {
9513 Lisp_Object tail, frame;
9514
9515 number_of_visible_frames = 0;
9516
9517 FOR_EACH_FRAME (tail, frame)
9518 {
9519 struct frame *f = XFRAME (frame);
9520
9521 FRAME_SAMPLE_VISIBILITY (f);
9522 if (FRAME_VISIBLE_P (f))
9523 ++number_of_visible_frames;
9524 clear_desired_matrices (f);
9525 }
9526 }
9527
9528
9529 /* Notice any pending interrupt request to change frame size. */
9530 do_pending_window_change (1);
9531
9532 /* Clear frames marked as garbaged. */
9533 if (frame_garbaged)
9534 clear_garbaged_frames ();
9535
9536 /* Build menubar and tool-bar items. */
9537 prepare_menu_bars ();
9538
9539 if (windows_or_buffers_changed)
9540 update_mode_lines++;
9541
9542 /* Detect case that we need to write or remove a star in the mode line. */
9543 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9544 {
9545 w->update_mode_line = Qt;
9546 if (buffer_shared > 1)
9547 update_mode_lines++;
9548 }
9549
9550 /* If %c is in the mode line, update it if needed. */
9551 if (!NILP (w->column_number_displayed)
9552 /* This alternative quickly identifies a common case
9553 where no change is needed. */
9554 && !(PT == XFASTINT (w->last_point)
9555 && XFASTINT (w->last_modified) >= MODIFF
9556 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9557 && (XFASTINT (w->column_number_displayed)
9558 != (int) current_column ())) /* iftc */
9559 w->update_mode_line = Qt;
9560
9561 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9562
9563 /* The variable buffer_shared is set in redisplay_window and
9564 indicates that we redisplay a buffer in different windows. See
9565 there. */
9566 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9567 || cursor_type_changed);
9568
9569 /* If specs for an arrow have changed, do thorough redisplay
9570 to ensure we remove any arrow that should no longer exist. */
9571 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
9572 || ! EQ (Voverlay_arrow_string, last_arrow_string))
9573 consider_all_windows_p = windows_or_buffers_changed = 1;
9574
9575 /* Normally the message* functions will have already displayed and
9576 updated the echo area, but the frame may have been trashed, or
9577 the update may have been preempted, so display the echo area
9578 again here. Checking message_cleared_p captures the case that
9579 the echo area should be cleared. */
9580 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9581 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9582 || (message_cleared_p
9583 && minibuf_level == 0
9584 /* If the mini-window is currently selected, this means the
9585 echo-area doesn't show through. */
9586 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9587 {
9588 int window_height_changed_p = echo_area_display (0);
9589 must_finish = 1;
9590
9591 /* If we don't display the current message, don't clear the
9592 message_cleared_p flag, because, if we did, we wouldn't clear
9593 the echo area in the next redisplay which doesn't preserve
9594 the echo area. */
9595 if (!display_last_displayed_message_p)
9596 message_cleared_p = 0;
9597
9598 if (fonts_changed_p)
9599 goto retry;
9600 else if (window_height_changed_p)
9601 {
9602 consider_all_windows_p = 1;
9603 ++update_mode_lines;
9604 ++windows_or_buffers_changed;
9605
9606 /* If window configuration was changed, frames may have been
9607 marked garbaged. Clear them or we will experience
9608 surprises wrt scrolling. */
9609 if (frame_garbaged)
9610 clear_garbaged_frames ();
9611 }
9612 }
9613 else if (EQ (selected_window, minibuf_window)
9614 && (current_buffer->clip_changed
9615 || XFASTINT (w->last_modified) < MODIFF
9616 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9617 && resize_mini_window (w, 0))
9618 {
9619 /* Resized active mini-window to fit the size of what it is
9620 showing if its contents might have changed. */
9621 must_finish = 1;
9622 consider_all_windows_p = 1;
9623 ++windows_or_buffers_changed;
9624 ++update_mode_lines;
9625
9626 /* If window configuration was changed, frames may have been
9627 marked garbaged. Clear them or we will experience
9628 surprises wrt scrolling. */
9629 if (frame_garbaged)
9630 clear_garbaged_frames ();
9631 }
9632
9633
9634 /* If showing the region, and mark has changed, we must redisplay
9635 the whole window. The assignment to this_line_start_pos prevents
9636 the optimization directly below this if-statement. */
9637 if (((!NILP (Vtransient_mark_mode)
9638 && !NILP (XBUFFER (w->buffer)->mark_active))
9639 != !NILP (w->region_showing))
9640 || (!NILP (w->region_showing)
9641 && !EQ (w->region_showing,
9642 Fmarker_position (XBUFFER (w->buffer)->mark))))
9643 CHARPOS (this_line_start_pos) = 0;
9644
9645 /* Optimize the case that only the line containing the cursor in the
9646 selected window has changed. Variables starting with this_ are
9647 set in display_line and record information about the line
9648 containing the cursor. */
9649 tlbufpos = this_line_start_pos;
9650 tlendpos = this_line_end_pos;
9651 if (!consider_all_windows_p
9652 && CHARPOS (tlbufpos) > 0
9653 && NILP (w->update_mode_line)
9654 && !current_buffer->clip_changed
9655 && !current_buffer->prevent_redisplay_optimizations_p
9656 && FRAME_VISIBLE_P (XFRAME (w->frame))
9657 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9658 /* Make sure recorded data applies to current buffer, etc. */
9659 && this_line_buffer == current_buffer
9660 && current_buffer == XBUFFER (w->buffer)
9661 && NILP (w->force_start)
9662 && NILP (w->optional_new_start)
9663 /* Point must be on the line that we have info recorded about. */
9664 && PT >= CHARPOS (tlbufpos)
9665 && PT <= Z - CHARPOS (tlendpos)
9666 /* All text outside that line, including its final newline,
9667 must be unchanged */
9668 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9669 CHARPOS (tlendpos)))
9670 {
9671 if (CHARPOS (tlbufpos) > BEGV
9672 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9673 && (CHARPOS (tlbufpos) == ZV
9674 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9675 /* Former continuation line has disappeared by becoming empty */
9676 goto cancel;
9677 else if (XFASTINT (w->last_modified) < MODIFF
9678 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9679 || MINI_WINDOW_P (w))
9680 {
9681 /* We have to handle the case of continuation around a
9682 wide-column character (See the comment in indent.c around
9683 line 885).
9684
9685 For instance, in the following case:
9686
9687 -------- Insert --------
9688 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9689 J_I_ ==> J_I_ `^^' are cursors.
9690 ^^ ^^
9691 -------- --------
9692
9693 As we have to redraw the line above, we should goto cancel. */
9694
9695 struct it it;
9696 int line_height_before = this_line_pixel_height;
9697
9698 /* Note that start_display will handle the case that the
9699 line starting at tlbufpos is a continuation lines. */
9700 start_display (&it, w, tlbufpos);
9701
9702 /* Implementation note: It this still necessary? */
9703 if (it.current_x != this_line_start_x)
9704 goto cancel;
9705
9706 TRACE ((stderr, "trying display optimization 1\n"));
9707 w->cursor.vpos = -1;
9708 overlay_arrow_seen = 0;
9709 it.vpos = this_line_vpos;
9710 it.current_y = this_line_y;
9711 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9712 display_line (&it);
9713
9714 /* If line contains point, is not continued,
9715 and ends at same distance from eob as before, we win */
9716 if (w->cursor.vpos >= 0
9717 /* Line is not continued, otherwise this_line_start_pos
9718 would have been set to 0 in display_line. */
9719 && CHARPOS (this_line_start_pos)
9720 /* Line ends as before. */
9721 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9722 /* Line has same height as before. Otherwise other lines
9723 would have to be shifted up or down. */
9724 && this_line_pixel_height == line_height_before)
9725 {
9726 /* If this is not the window's last line, we must adjust
9727 the charstarts of the lines below. */
9728 if (it.current_y < it.last_visible_y)
9729 {
9730 struct glyph_row *row
9731 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9732 int delta, delta_bytes;
9733
9734 if (Z - CHARPOS (tlendpos) == ZV)
9735 {
9736 /* This line ends at end of (accessible part of)
9737 buffer. There is no newline to count. */
9738 delta = (Z
9739 - CHARPOS (tlendpos)
9740 - MATRIX_ROW_START_CHARPOS (row));
9741 delta_bytes = (Z_BYTE
9742 - BYTEPOS (tlendpos)
9743 - MATRIX_ROW_START_BYTEPOS (row));
9744 }
9745 else
9746 {
9747 /* This line ends in a newline. Must take
9748 account of the newline and the rest of the
9749 text that follows. */
9750 delta = (Z
9751 - CHARPOS (tlendpos)
9752 - MATRIX_ROW_START_CHARPOS (row));
9753 delta_bytes = (Z_BYTE
9754 - BYTEPOS (tlendpos)
9755 - MATRIX_ROW_START_BYTEPOS (row));
9756 }
9757
9758 increment_matrix_positions (w->current_matrix,
9759 this_line_vpos + 1,
9760 w->current_matrix->nrows,
9761 delta, delta_bytes);
9762 }
9763
9764 /* If this row displays text now but previously didn't,
9765 or vice versa, w->window_end_vpos may have to be
9766 adjusted. */
9767 if ((it.glyph_row - 1)->displays_text_p)
9768 {
9769 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9770 XSETINT (w->window_end_vpos, this_line_vpos);
9771 }
9772 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9773 && this_line_vpos > 0)
9774 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9775 w->window_end_valid = Qnil;
9776
9777 /* Update hint: No need to try to scroll in update_window. */
9778 w->desired_matrix->no_scrolling_p = 1;
9779
9780 #if GLYPH_DEBUG
9781 *w->desired_matrix->method = 0;
9782 debug_method_add (w, "optimization 1");
9783 #endif
9784 #ifdef HAVE_WINDOW_SYSTEM
9785 update_window_fringes (w, 0);
9786 #endif
9787 goto update;
9788 }
9789 else
9790 goto cancel;
9791 }
9792 else if (/* Cursor position hasn't changed. */
9793 PT == XFASTINT (w->last_point)
9794 /* Make sure the cursor was last displayed
9795 in this window. Otherwise we have to reposition it. */
9796 && 0 <= w->cursor.vpos
9797 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
9798 {
9799 if (!must_finish)
9800 {
9801 do_pending_window_change (1);
9802
9803 /* We used to always goto end_of_redisplay here, but this
9804 isn't enough if we have a blinking cursor. */
9805 if (w->cursor_off_p == w->last_cursor_off_p)
9806 goto end_of_redisplay;
9807 }
9808 goto update;
9809 }
9810 /* If highlighting the region, or if the cursor is in the echo area,
9811 then we can't just move the cursor. */
9812 else if (! (!NILP (Vtransient_mark_mode)
9813 && !NILP (current_buffer->mark_active))
9814 && (EQ (selected_window, current_buffer->last_selected_window)
9815 || highlight_nonselected_windows)
9816 && NILP (w->region_showing)
9817 && NILP (Vshow_trailing_whitespace)
9818 && !cursor_in_echo_area)
9819 {
9820 struct it it;
9821 struct glyph_row *row;
9822
9823 /* Skip from tlbufpos to PT and see where it is. Note that
9824 PT may be in invisible text. If so, we will end at the
9825 next visible position. */
9826 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
9827 NULL, DEFAULT_FACE_ID);
9828 it.current_x = this_line_start_x;
9829 it.current_y = this_line_y;
9830 it.vpos = this_line_vpos;
9831
9832 /* The call to move_it_to stops in front of PT, but
9833 moves over before-strings. */
9834 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
9835
9836 if (it.vpos == this_line_vpos
9837 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
9838 row->enabled_p))
9839 {
9840 xassert (this_line_vpos == it.vpos);
9841 xassert (this_line_y == it.current_y);
9842 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9843 #if GLYPH_DEBUG
9844 *w->desired_matrix->method = 0;
9845 debug_method_add (w, "optimization 3");
9846 #endif
9847 goto update;
9848 }
9849 else
9850 goto cancel;
9851 }
9852
9853 cancel:
9854 /* Text changed drastically or point moved off of line. */
9855 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
9856 }
9857
9858 CHARPOS (this_line_start_pos) = 0;
9859 consider_all_windows_p |= buffer_shared > 1;
9860 ++clear_face_cache_count;
9861
9862
9863 /* Build desired matrices, and update the display. If
9864 consider_all_windows_p is non-zero, do it for all windows on all
9865 frames. Otherwise do it for selected_window, only. */
9866
9867 if (consider_all_windows_p)
9868 {
9869 Lisp_Object tail, frame;
9870 int i, n = 0, size = 50;
9871 struct frame **updated
9872 = (struct frame **) alloca (size * sizeof *updated);
9873
9874 /* Clear the face cache eventually. */
9875 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
9876 {
9877 clear_face_cache (0);
9878 clear_face_cache_count = 0;
9879 }
9880
9881 /* Recompute # windows showing selected buffer. This will be
9882 incremented each time such a window is displayed. */
9883 buffer_shared = 0;
9884
9885 FOR_EACH_FRAME (tail, frame)
9886 {
9887 struct frame *f = XFRAME (frame);
9888
9889 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
9890 {
9891 if (! EQ (frame, selected_frame))
9892 /* Select the frame, for the sake of frame-local
9893 variables. */
9894 select_frame_for_redisplay (frame);
9895
9896 #ifdef HAVE_WINDOW_SYSTEM
9897 if (clear_face_cache_count % 50 == 0
9898 && FRAME_WINDOW_P (f))
9899 clear_image_cache (f, 0);
9900 #endif /* HAVE_WINDOW_SYSTEM */
9901
9902 /* Mark all the scroll bars to be removed; we'll redeem
9903 the ones we want when we redisplay their windows. */
9904 if (FRAME_DISPLAY (f)->condemn_scroll_bars_hook)
9905 FRAME_DISPLAY (f)->condemn_scroll_bars_hook (f);
9906
9907 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9908 redisplay_windows (FRAME_ROOT_WINDOW (f));
9909
9910 /* Any scroll bars which redisplay_windows should have
9911 nuked should now go away. */
9912 if (FRAME_DISPLAY (f)->judge_scroll_bars_hook)
9913 FRAME_DISPLAY (f)->judge_scroll_bars_hook (f);
9914
9915 /* If fonts changed, display again. */
9916 /* ??? rms: I suspect it is a mistake to jump all the way
9917 back to retry here. It should just retry this frame. */
9918 if (fonts_changed_p)
9919 goto retry;
9920
9921 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9922 {
9923 /* See if we have to hscroll. */
9924 if (hscroll_windows (f->root_window))
9925 goto retry;
9926
9927 /* Prevent various kinds of signals during display
9928 update. stdio is not robust about handling
9929 signals, which can cause an apparent I/O
9930 error. */
9931 if (interrupt_input)
9932 unrequest_sigio ();
9933 STOP_POLLING;
9934
9935 /* Update the display. */
9936 set_window_update_flags (XWINDOW (f->root_window), 1);
9937 pause |= update_frame (f, 0, 0);
9938 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
9939 if (pause)
9940 break;
9941 #endif
9942
9943 if (n == size)
9944 {
9945 int nbytes = size * sizeof *updated;
9946 struct frame **p = (struct frame **) alloca (2 * nbytes);
9947 bcopy (updated, p, nbytes);
9948 size *= 2;
9949 }
9950
9951 updated[n++] = f;
9952 }
9953 }
9954 }
9955
9956 if (!pause)
9957 {
9958 /* Do the mark_window_display_accurate after all windows have
9959 been redisplayed because this call resets flags in buffers
9960 which are needed for proper redisplay. */
9961 for (i = 0; i < n; ++i)
9962 {
9963 struct frame *f = updated[i];
9964 mark_window_display_accurate (f->root_window, 1);
9965 if (FRAME_DISPLAY (f)->frame_up_to_date_hook)
9966 FRAME_DISPLAY (f)->frame_up_to_date_hook (f);
9967 }
9968 }
9969 }
9970 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
9971 {
9972 Lisp_Object mini_window;
9973 struct frame *mini_frame;
9974
9975 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
9976 /* Use list_of_error, not Qerror, so that
9977 we catch only errors and don't run the debugger. */
9978 internal_condition_case_1 (redisplay_window_1, selected_window,
9979 list_of_error,
9980 redisplay_window_error);
9981
9982 /* Compare desired and current matrices, perform output. */
9983
9984 update:
9985 /* If fonts changed, display again. */
9986 if (fonts_changed_p)
9987 goto retry;
9988
9989 /* Prevent various kinds of signals during display update.
9990 stdio is not robust about handling signals,
9991 which can cause an apparent I/O error. */
9992 if (interrupt_input)
9993 unrequest_sigio ();
9994 STOP_POLLING;
9995
9996 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
9997 {
9998 if (hscroll_windows (selected_window))
9999 goto retry;
10000
10001 XWINDOW (selected_window)->must_be_updated_p = 1;
10002 pause = update_frame (sf, 0, 0);
10003 }
10004
10005 /* We may have called echo_area_display at the top of this
10006 function. If the echo area is on another frame, that may
10007 have put text on a frame other than the selected one, so the
10008 above call to update_frame would not have caught it. Catch
10009 it here. */
10010 mini_window = FRAME_MINIBUF_WINDOW (sf);
10011 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10012
10013 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10014 {
10015 XWINDOW (mini_window)->must_be_updated_p = 1;
10016 pause |= update_frame (mini_frame, 0, 0);
10017 if (!pause && hscroll_windows (mini_window))
10018 goto retry;
10019 }
10020 }
10021
10022 /* If display was paused because of pending input, make sure we do a
10023 thorough update the next time. */
10024 if (pause)
10025 {
10026 /* Prevent the optimization at the beginning of
10027 redisplay_internal that tries a single-line update of the
10028 line containing the cursor in the selected window. */
10029 CHARPOS (this_line_start_pos) = 0;
10030
10031 /* Let the overlay arrow be updated the next time. */
10032 if (!NILP (last_arrow_position))
10033 {
10034 last_arrow_position = Qt;
10035 last_arrow_string = Qt;
10036 }
10037
10038 /* If we pause after scrolling, some rows in the current
10039 matrices of some windows are not valid. */
10040 if (!WINDOW_FULL_WIDTH_P (w)
10041 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10042 update_mode_lines = 1;
10043 }
10044 else
10045 {
10046 if (!consider_all_windows_p)
10047 {
10048 /* This has already been done above if
10049 consider_all_windows_p is set. */
10050 mark_window_display_accurate_1 (w, 1);
10051
10052 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10053 last_arrow_string = Voverlay_arrow_string;
10054
10055 if (FRAME_DISPLAY (sf)->frame_up_to_date_hook != 0)
10056 FRAME_DISPLAY (sf)->frame_up_to_date_hook (sf);
10057 }
10058
10059 update_mode_lines = 0;
10060 windows_or_buffers_changed = 0;
10061 cursor_type_changed = 0;
10062 }
10063
10064 /* Start SIGIO interrupts coming again. Having them off during the
10065 code above makes it less likely one will discard output, but not
10066 impossible, since there might be stuff in the system buffer here.
10067 But it is much hairier to try to do anything about that. */
10068 if (interrupt_input)
10069 request_sigio ();
10070 RESUME_POLLING;
10071
10072 /* If a frame has become visible which was not before, redisplay
10073 again, so that we display it. Expose events for such a frame
10074 (which it gets when becoming visible) don't call the parts of
10075 redisplay constructing glyphs, so simply exposing a frame won't
10076 display anything in this case. So, we have to display these
10077 frames here explicitly. */
10078 if (!pause)
10079 {
10080 Lisp_Object tail, frame;
10081 int new_count = 0;
10082
10083 FOR_EACH_FRAME (tail, frame)
10084 {
10085 int this_is_visible = 0;
10086
10087 if (XFRAME (frame)->visible)
10088 this_is_visible = 1;
10089 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10090 if (XFRAME (frame)->visible)
10091 this_is_visible = 1;
10092
10093 if (this_is_visible)
10094 new_count++;
10095 }
10096
10097 if (new_count != number_of_visible_frames)
10098 windows_or_buffers_changed++;
10099 }
10100
10101 /* Change frame size now if a change is pending. */
10102 do_pending_window_change (1);
10103
10104 /* If we just did a pending size change, or have additional
10105 visible frames, redisplay again. */
10106 if (windows_or_buffers_changed && !pause)
10107 goto retry;
10108
10109 end_of_redisplay:
10110 unbind_to (count, Qnil);
10111 RESUME_POLLING;
10112 }
10113
10114
10115 /* Redisplay, but leave alone any recent echo area message unless
10116 another message has been requested in its place.
10117
10118 This is useful in situations where you need to redisplay but no
10119 user action has occurred, making it inappropriate for the message
10120 area to be cleared. See tracking_off and
10121 wait_reading_process_input for examples of these situations.
10122
10123 FROM_WHERE is an integer saying from where this function was
10124 called. This is useful for debugging. */
10125
10126 void
10127 redisplay_preserve_echo_area (from_where)
10128 int from_where;
10129 {
10130 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10131
10132 if (!NILP (echo_area_buffer[1]))
10133 {
10134 /* We have a previously displayed message, but no current
10135 message. Redisplay the previous message. */
10136 display_last_displayed_message_p = 1;
10137 redisplay_internal (1);
10138 display_last_displayed_message_p = 0;
10139 }
10140 else
10141 redisplay_internal (1);
10142 }
10143
10144
10145 /* Function registered with record_unwind_protect in
10146 redisplay_internal. Reset redisplaying_p to the value it had
10147 before redisplay_internal was called, and clear
10148 prevent_freeing_realized_faces_p. It also selects the previously
10149 selected frame. */
10150
10151 static Lisp_Object
10152 unwind_redisplay (val)
10153 Lisp_Object val;
10154 {
10155 Lisp_Object old_redisplaying_p, old_frame;
10156
10157 old_redisplaying_p = XCAR (val);
10158 redisplaying_p = XFASTINT (old_redisplaying_p);
10159 old_frame = XCDR (val);
10160 if (! EQ (old_frame, selected_frame))
10161 select_frame_for_redisplay (old_frame);
10162 return Qnil;
10163 }
10164
10165
10166 /* Mark the display of window W as accurate or inaccurate. If
10167 ACCURATE_P is non-zero mark display of W as accurate. If
10168 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10169 redisplay_internal is called. */
10170
10171 static void
10172 mark_window_display_accurate_1 (w, accurate_p)
10173 struct window *w;
10174 int accurate_p;
10175 {
10176 if (BUFFERP (w->buffer))
10177 {
10178 struct buffer *b = XBUFFER (w->buffer);
10179
10180 w->last_modified
10181 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10182 w->last_overlay_modified
10183 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10184 w->last_had_star
10185 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10186
10187 if (accurate_p)
10188 {
10189 b->clip_changed = 0;
10190 b->prevent_redisplay_optimizations_p = 0;
10191
10192 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10193 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10194 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10195 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10196
10197 w->current_matrix->buffer = b;
10198 w->current_matrix->begv = BUF_BEGV (b);
10199 w->current_matrix->zv = BUF_ZV (b);
10200
10201 w->last_cursor = w->cursor;
10202 w->last_cursor_off_p = w->cursor_off_p;
10203
10204 if (w == XWINDOW (selected_window))
10205 w->last_point = make_number (BUF_PT (b));
10206 else
10207 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10208 }
10209 }
10210
10211 if (accurate_p)
10212 {
10213 w->window_end_valid = w->buffer;
10214 #if 0 /* This is incorrect with variable-height lines. */
10215 xassert (XINT (w->window_end_vpos)
10216 < (WINDOW_TOTAL_LINES (w)
10217 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10218 #endif
10219 w->update_mode_line = Qnil;
10220 }
10221 }
10222
10223
10224 /* Mark the display of windows in the window tree rooted at WINDOW as
10225 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10226 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10227 be redisplayed the next time redisplay_internal is called. */
10228
10229 void
10230 mark_window_display_accurate (window, accurate_p)
10231 Lisp_Object window;
10232 int accurate_p;
10233 {
10234 struct window *w;
10235
10236 for (; !NILP (window); window = w->next)
10237 {
10238 w = XWINDOW (window);
10239 mark_window_display_accurate_1 (w, accurate_p);
10240
10241 if (!NILP (w->vchild))
10242 mark_window_display_accurate (w->vchild, accurate_p);
10243 if (!NILP (w->hchild))
10244 mark_window_display_accurate (w->hchild, accurate_p);
10245 }
10246
10247 if (accurate_p)
10248 {
10249 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10250 last_arrow_string = Voverlay_arrow_string;
10251 }
10252 else
10253 {
10254 /* Force a thorough redisplay the next time by setting
10255 last_arrow_position and last_arrow_string to t, which is
10256 unequal to any useful value of Voverlay_arrow_... */
10257 last_arrow_position = Qt;
10258 last_arrow_string = Qt;
10259 }
10260 }
10261
10262
10263 /* Return value in display table DP (Lisp_Char_Table *) for character
10264 C. Since a display table doesn't have any parent, we don't have to
10265 follow parent. Do not call this function directly but use the
10266 macro DISP_CHAR_VECTOR. */
10267
10268 Lisp_Object
10269 disp_char_vector (dp, c)
10270 struct Lisp_Char_Table *dp;
10271 int c;
10272 {
10273 int code[4], i;
10274 Lisp_Object val;
10275
10276 if (SINGLE_BYTE_CHAR_P (c))
10277 return (dp->contents[c]);
10278
10279 SPLIT_CHAR (c, code[0], code[1], code[2]);
10280 if (code[1] < 32)
10281 code[1] = -1;
10282 else if (code[2] < 32)
10283 code[2] = -1;
10284
10285 /* Here, the possible range of code[0] (== charset ID) is
10286 128..max_charset. Since the top level char table contains data
10287 for multibyte characters after 256th element, we must increment
10288 code[0] by 128 to get a correct index. */
10289 code[0] += 128;
10290 code[3] = -1; /* anchor */
10291
10292 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10293 {
10294 val = dp->contents[code[i]];
10295 if (!SUB_CHAR_TABLE_P (val))
10296 return (NILP (val) ? dp->defalt : val);
10297 }
10298
10299 /* Here, val is a sub char table. We return the default value of
10300 it. */
10301 return (dp->defalt);
10302 }
10303
10304
10305 \f
10306 /***********************************************************************
10307 Window Redisplay
10308 ***********************************************************************/
10309
10310 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10311
10312 static void
10313 redisplay_windows (window)
10314 Lisp_Object window;
10315 {
10316 while (!NILP (window))
10317 {
10318 struct window *w = XWINDOW (window);
10319
10320 if (!NILP (w->hchild))
10321 redisplay_windows (w->hchild);
10322 else if (!NILP (w->vchild))
10323 redisplay_windows (w->vchild);
10324 else
10325 {
10326 displayed_buffer = XBUFFER (w->buffer);
10327 /* Use list_of_error, not Qerror, so that
10328 we catch only errors and don't run the debugger. */
10329 internal_condition_case_1 (redisplay_window_0, window,
10330 list_of_error,
10331 redisplay_window_error);
10332 }
10333
10334 window = w->next;
10335 }
10336 }
10337
10338 static Lisp_Object
10339 redisplay_window_error ()
10340 {
10341 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10342 return Qnil;
10343 }
10344
10345 static Lisp_Object
10346 redisplay_window_0 (window)
10347 Lisp_Object window;
10348 {
10349 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10350 redisplay_window (window, 0);
10351 return Qnil;
10352 }
10353
10354 static Lisp_Object
10355 redisplay_window_1 (window)
10356 Lisp_Object window;
10357 {
10358 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10359 redisplay_window (window, 1);
10360 return Qnil;
10361 }
10362 \f
10363
10364 /* Increment GLYPH until it reaches END or CONDITION fails while
10365 adding (GLYPH)->pixel_width to X. */
10366
10367 #define SKIP_GLYPHS(glyph, end, x, condition) \
10368 do \
10369 { \
10370 (x) += (glyph)->pixel_width; \
10371 ++(glyph); \
10372 } \
10373 while ((glyph) < (end) && (condition))
10374
10375
10376 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10377 DELTA is the number of bytes by which positions recorded in ROW
10378 differ from current buffer positions. */
10379
10380 void
10381 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10382 struct window *w;
10383 struct glyph_row *row;
10384 struct glyph_matrix *matrix;
10385 int delta, delta_bytes, dy, dvpos;
10386 {
10387 struct glyph *glyph = row->glyphs[TEXT_AREA];
10388 struct glyph *end = glyph + row->used[TEXT_AREA];
10389 /* The first glyph that starts a sequence of glyphs from string. */
10390 struct glyph *string_start;
10391 /* The X coordinate of string_start. */
10392 int string_start_x;
10393 /* The last known character position. */
10394 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10395 /* The last known character position before string_start. */
10396 int string_before_pos;
10397 int x = row->x;
10398 int pt_old = PT - delta;
10399
10400 /* Skip over glyphs not having an object at the start of the row.
10401 These are special glyphs like truncation marks on terminal
10402 frames. */
10403 if (row->displays_text_p)
10404 while (glyph < end
10405 && INTEGERP (glyph->object)
10406 && glyph->charpos < 0)
10407 {
10408 x += glyph->pixel_width;
10409 ++glyph;
10410 }
10411
10412 string_start = NULL;
10413 while (glyph < end
10414 && !INTEGERP (glyph->object)
10415 && (!BUFFERP (glyph->object)
10416 || (last_pos = glyph->charpos) < pt_old))
10417 {
10418 if (! STRINGP (glyph->object))
10419 {
10420 string_start = NULL;
10421 x += glyph->pixel_width;
10422 ++glyph;
10423 }
10424 else
10425 {
10426 string_before_pos = last_pos;
10427 string_start = glyph;
10428 string_start_x = x;
10429 /* Skip all glyphs from string. */
10430 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10431 }
10432 }
10433
10434 if (string_start
10435 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10436 {
10437 /* We may have skipped over point because the previous glyphs
10438 are from string. As there's no easy way to know the
10439 character position of the current glyph, find the correct
10440 glyph on point by scanning from string_start again. */
10441 Lisp_Object limit;
10442 Lisp_Object string;
10443 int pos;
10444
10445 limit = make_number (pt_old + 1);
10446 end = glyph;
10447 glyph = string_start;
10448 x = string_start_x;
10449 string = glyph->object;
10450 pos = string_buffer_position (w, string, string_before_pos);
10451 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10452 because we always put cursor after overlay strings. */
10453 while (pos == 0 && glyph < end)
10454 {
10455 string = glyph->object;
10456 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10457 if (glyph < end)
10458 pos = string_buffer_position (w, glyph->object, string_before_pos);
10459 }
10460
10461 while (glyph < end)
10462 {
10463 pos = XINT (Fnext_single_char_property_change
10464 (make_number (pos), Qdisplay, Qnil, limit));
10465 if (pos > pt_old)
10466 break;
10467 /* Skip glyphs from the same string. */
10468 string = glyph->object;
10469 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10470 /* Skip glyphs from an overlay. */
10471 while (glyph < end
10472 && ! string_buffer_position (w, glyph->object, pos))
10473 {
10474 string = glyph->object;
10475 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10476 }
10477 }
10478 }
10479
10480 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10481 w->cursor.x = x;
10482 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10483 w->cursor.y = row->y + dy;
10484
10485 if (w == XWINDOW (selected_window))
10486 {
10487 if (!row->continued_p
10488 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10489 && row->x == 0)
10490 {
10491 this_line_buffer = XBUFFER (w->buffer);
10492
10493 CHARPOS (this_line_start_pos)
10494 = MATRIX_ROW_START_CHARPOS (row) + delta;
10495 BYTEPOS (this_line_start_pos)
10496 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10497
10498 CHARPOS (this_line_end_pos)
10499 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10500 BYTEPOS (this_line_end_pos)
10501 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10502
10503 this_line_y = w->cursor.y;
10504 this_line_pixel_height = row->height;
10505 this_line_vpos = w->cursor.vpos;
10506 this_line_start_x = row->x;
10507 }
10508 else
10509 CHARPOS (this_line_start_pos) = 0;
10510 }
10511 }
10512
10513
10514 /* Run window scroll functions, if any, for WINDOW with new window
10515 start STARTP. Sets the window start of WINDOW to that position.
10516
10517 We assume that the window's buffer is really current. */
10518
10519 static INLINE struct text_pos
10520 run_window_scroll_functions (window, startp)
10521 Lisp_Object window;
10522 struct text_pos startp;
10523 {
10524 struct window *w = XWINDOW (window);
10525 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10526
10527 if (current_buffer != XBUFFER (w->buffer))
10528 abort ();
10529
10530 if (!NILP (Vwindow_scroll_functions))
10531 {
10532 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10533 make_number (CHARPOS (startp)));
10534 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10535 /* In case the hook functions switch buffers. */
10536 if (current_buffer != XBUFFER (w->buffer))
10537 set_buffer_internal_1 (XBUFFER (w->buffer));
10538 }
10539
10540 return startp;
10541 }
10542
10543
10544 /* Make sure the line containing the cursor is fully visible.
10545 A value of 1 means there is nothing to be done.
10546 (Either the line is fully visible, or it cannot be made so,
10547 or we cannot tell.)
10548 A value of 0 means the caller should do scrolling
10549 as if point had gone off the screen. */
10550
10551 static int
10552 make_cursor_line_fully_visible (w)
10553 struct window *w;
10554 {
10555 struct glyph_matrix *matrix;
10556 struct glyph_row *row;
10557 int window_height;
10558
10559 /* It's not always possible to find the cursor, e.g, when a window
10560 is full of overlay strings. Don't do anything in that case. */
10561 if (w->cursor.vpos < 0)
10562 return 1;
10563
10564 matrix = w->desired_matrix;
10565 row = MATRIX_ROW (matrix, w->cursor.vpos);
10566
10567 /* If the cursor row is not partially visible, there's nothing to do. */
10568 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10569 return 1;
10570
10571 /* If the row the cursor is in is taller than the window's height,
10572 it's not clear what to do, so do nothing. */
10573 window_height = window_box_height (w);
10574 if (row->height >= window_height)
10575 return 1;
10576
10577 return 0;
10578
10579 #if 0
10580 /* This code used to try to scroll the window just enough to make
10581 the line visible. It returned 0 to say that the caller should
10582 allocate larger glyph matrices. */
10583
10584 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10585 {
10586 int dy = row->height - row->visible_height;
10587 w->vscroll = 0;
10588 w->cursor.y += dy;
10589 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10590 }
10591 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10592 {
10593 int dy = - (row->height - row->visible_height);
10594 w->vscroll = dy;
10595 w->cursor.y += dy;
10596 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10597 }
10598
10599 /* When we change the cursor y-position of the selected window,
10600 change this_line_y as well so that the display optimization for
10601 the cursor line of the selected window in redisplay_internal uses
10602 the correct y-position. */
10603 if (w == XWINDOW (selected_window))
10604 this_line_y = w->cursor.y;
10605
10606 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10607 redisplay with larger matrices. */
10608 if (matrix->nrows < required_matrix_height (w))
10609 {
10610 fonts_changed_p = 1;
10611 return 0;
10612 }
10613
10614 return 1;
10615 #endif /* 0 */
10616 }
10617
10618
10619 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10620 non-zero means only WINDOW is redisplayed in redisplay_internal.
10621 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10622 in redisplay_window to bring a partially visible line into view in
10623 the case that only the cursor has moved.
10624
10625 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10626 last screen line's vertical height extends past the end of the screen.
10627
10628 Value is
10629
10630 1 if scrolling succeeded
10631
10632 0 if scrolling didn't find point.
10633
10634 -1 if new fonts have been loaded so that we must interrupt
10635 redisplay, adjust glyph matrices, and try again. */
10636
10637 enum
10638 {
10639 SCROLLING_SUCCESS,
10640 SCROLLING_FAILED,
10641 SCROLLING_NEED_LARGER_MATRICES
10642 };
10643
10644 static int
10645 try_scrolling (window, just_this_one_p, scroll_conservatively,
10646 scroll_step, temp_scroll_step, last_line_misfit)
10647 Lisp_Object window;
10648 int just_this_one_p;
10649 EMACS_INT scroll_conservatively, scroll_step;
10650 int temp_scroll_step;
10651 int last_line_misfit;
10652 {
10653 struct window *w = XWINDOW (window);
10654 struct frame *f = XFRAME (w->frame);
10655 struct text_pos scroll_margin_pos;
10656 struct text_pos pos;
10657 struct text_pos startp;
10658 struct it it;
10659 Lisp_Object window_end;
10660 int this_scroll_margin;
10661 int dy = 0;
10662 int scroll_max;
10663 int rc;
10664 int amount_to_scroll = 0;
10665 Lisp_Object aggressive;
10666 int height;
10667 int end_scroll_margin;
10668
10669 #if GLYPH_DEBUG
10670 debug_method_add (w, "try_scrolling");
10671 #endif
10672
10673 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10674
10675 /* Compute scroll margin height in pixels. We scroll when point is
10676 within this distance from the top or bottom of the window. */
10677 if (scroll_margin > 0)
10678 {
10679 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10680 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10681 }
10682 else
10683 this_scroll_margin = 0;
10684
10685 /* Compute how much we should try to scroll maximally to bring point
10686 into view. */
10687 if (scroll_step || scroll_conservatively || temp_scroll_step)
10688 scroll_max = max (scroll_step,
10689 max (scroll_conservatively, temp_scroll_step));
10690 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10691 || NUMBERP (current_buffer->scroll_up_aggressively))
10692 /* We're trying to scroll because of aggressive scrolling
10693 but no scroll_step is set. Choose an arbitrary one. Maybe
10694 there should be a variable for this. */
10695 scroll_max = 10;
10696 else
10697 scroll_max = 0;
10698 scroll_max *= FRAME_LINE_HEIGHT (f);
10699
10700 /* Decide whether we have to scroll down. Start at the window end
10701 and move this_scroll_margin up to find the position of the scroll
10702 margin. */
10703 window_end = Fwindow_end (window, Qt);
10704
10705 too_near_end:
10706
10707 CHARPOS (scroll_margin_pos) = XINT (window_end);
10708 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10709
10710 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10711 if (end_scroll_margin)
10712 {
10713 start_display (&it, w, scroll_margin_pos);
10714 move_it_vertically (&it, - end_scroll_margin);
10715 scroll_margin_pos = it.current.pos;
10716 }
10717
10718 if (PT >= CHARPOS (scroll_margin_pos))
10719 {
10720 int y0;
10721
10722 /* Point is in the scroll margin at the bottom of the window, or
10723 below. Compute a new window start that makes point visible. */
10724
10725 /* Compute the distance from the scroll margin to PT.
10726 Give up if the distance is greater than scroll_max. */
10727 start_display (&it, w, scroll_margin_pos);
10728 y0 = it.current_y;
10729 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10730 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10731
10732 /* To make point visible, we have to move the window start
10733 down so that the line the cursor is in is visible, which
10734 means we have to add in the height of the cursor line. */
10735 dy = line_bottom_y (&it) - y0;
10736
10737 if (dy > scroll_max)
10738 return SCROLLING_FAILED;
10739
10740 /* Move the window start down. If scrolling conservatively,
10741 move it just enough down to make point visible. If
10742 scroll_step is set, move it down by scroll_step. */
10743 start_display (&it, w, startp);
10744
10745 if (scroll_conservatively)
10746 /* Set AMOUNT_TO_SCROLL to at least one line,
10747 and at most scroll_conservatively lines. */
10748 amount_to_scroll
10749 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10750 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10751 else if (scroll_step || temp_scroll_step)
10752 amount_to_scroll = scroll_max;
10753 else
10754 {
10755 aggressive = current_buffer->scroll_up_aggressively;
10756 height = WINDOW_BOX_TEXT_HEIGHT (w);
10757 if (NUMBERP (aggressive))
10758 amount_to_scroll = XFLOATINT (aggressive) * height;
10759 }
10760
10761 if (amount_to_scroll <= 0)
10762 return SCROLLING_FAILED;
10763
10764 /* If moving by amount_to_scroll leaves STARTP unchanged,
10765 move it down one screen line. */
10766
10767 move_it_vertically (&it, amount_to_scroll);
10768 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10769 move_it_by_lines (&it, 1, 1);
10770 startp = it.current.pos;
10771 }
10772 else
10773 {
10774 /* See if point is inside the scroll margin at the top of the
10775 window. */
10776 scroll_margin_pos = startp;
10777 if (this_scroll_margin)
10778 {
10779 start_display (&it, w, startp);
10780 move_it_vertically (&it, this_scroll_margin);
10781 scroll_margin_pos = it.current.pos;
10782 }
10783
10784 if (PT < CHARPOS (scroll_margin_pos))
10785 {
10786 /* Point is in the scroll margin at the top of the window or
10787 above what is displayed in the window. */
10788 int y0;
10789
10790 /* Compute the vertical distance from PT to the scroll
10791 margin position. Give up if distance is greater than
10792 scroll_max. */
10793 SET_TEXT_POS (pos, PT, PT_BYTE);
10794 start_display (&it, w, pos);
10795 y0 = it.current_y;
10796 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10797 it.last_visible_y, -1,
10798 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10799 dy = it.current_y - y0;
10800 if (dy > scroll_max)
10801 return SCROLLING_FAILED;
10802
10803 /* Compute new window start. */
10804 start_display (&it, w, startp);
10805
10806 if (scroll_conservatively)
10807 amount_to_scroll =
10808 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
10809 else if (scroll_step || temp_scroll_step)
10810 amount_to_scroll = scroll_max;
10811 else
10812 {
10813 aggressive = current_buffer->scroll_down_aggressively;
10814 height = WINDOW_BOX_TEXT_HEIGHT (w);
10815 if (NUMBERP (aggressive))
10816 amount_to_scroll = XFLOATINT (aggressive) * height;
10817 }
10818
10819 if (amount_to_scroll <= 0)
10820 return SCROLLING_FAILED;
10821
10822 move_it_vertically (&it, - amount_to_scroll);
10823 startp = it.current.pos;
10824 }
10825 }
10826
10827 /* Run window scroll functions. */
10828 startp = run_window_scroll_functions (window, startp);
10829
10830 /* Display the window. Give up if new fonts are loaded, or if point
10831 doesn't appear. */
10832 if (!try_window (window, startp))
10833 rc = SCROLLING_NEED_LARGER_MATRICES;
10834 else if (w->cursor.vpos < 0)
10835 {
10836 clear_glyph_matrix (w->desired_matrix);
10837 rc = SCROLLING_FAILED;
10838 }
10839 else
10840 {
10841 /* Maybe forget recorded base line for line number display. */
10842 if (!just_this_one_p
10843 || current_buffer->clip_changed
10844 || BEG_UNCHANGED < CHARPOS (startp))
10845 w->base_line_number = Qnil;
10846
10847 /* If cursor ends up on a partially visible line,
10848 treat that as being off the bottom of the screen. */
10849 if (! make_cursor_line_fully_visible (w))
10850 {
10851 clear_glyph_matrix (w->desired_matrix);
10852 last_line_misfit = 1;
10853 goto too_near_end;
10854 }
10855 rc = SCROLLING_SUCCESS;
10856 }
10857
10858 return rc;
10859 }
10860
10861
10862 /* Compute a suitable window start for window W if display of W starts
10863 on a continuation line. Value is non-zero if a new window start
10864 was computed.
10865
10866 The new window start will be computed, based on W's width, starting
10867 from the start of the continued line. It is the start of the
10868 screen line with the minimum distance from the old start W->start. */
10869
10870 static int
10871 compute_window_start_on_continuation_line (w)
10872 struct window *w;
10873 {
10874 struct text_pos pos, start_pos;
10875 int window_start_changed_p = 0;
10876
10877 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
10878
10879 /* If window start is on a continuation line... Window start may be
10880 < BEGV in case there's invisible text at the start of the
10881 buffer (M-x rmail, for example). */
10882 if (CHARPOS (start_pos) > BEGV
10883 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
10884 {
10885 struct it it;
10886 struct glyph_row *row;
10887
10888 /* Handle the case that the window start is out of range. */
10889 if (CHARPOS (start_pos) < BEGV)
10890 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
10891 else if (CHARPOS (start_pos) > ZV)
10892 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
10893
10894 /* Find the start of the continued line. This should be fast
10895 because scan_buffer is fast (newline cache). */
10896 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
10897 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
10898 row, DEFAULT_FACE_ID);
10899 reseat_at_previous_visible_line_start (&it);
10900
10901 /* If the line start is "too far" away from the window start,
10902 say it takes too much time to compute a new window start. */
10903 if (CHARPOS (start_pos) - IT_CHARPOS (it)
10904 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
10905 {
10906 int min_distance, distance;
10907
10908 /* Move forward by display lines to find the new window
10909 start. If window width was enlarged, the new start can
10910 be expected to be > the old start. If window width was
10911 decreased, the new window start will be < the old start.
10912 So, we're looking for the display line start with the
10913 minimum distance from the old window start. */
10914 pos = it.current.pos;
10915 min_distance = INFINITY;
10916 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
10917 distance < min_distance)
10918 {
10919 min_distance = distance;
10920 pos = it.current.pos;
10921 move_it_by_lines (&it, 1, 0);
10922 }
10923
10924 /* Set the window start there. */
10925 SET_MARKER_FROM_TEXT_POS (w->start, pos);
10926 window_start_changed_p = 1;
10927 }
10928 }
10929
10930 return window_start_changed_p;
10931 }
10932
10933
10934 /* Try cursor movement in case text has not changed in window WINDOW,
10935 with window start STARTP. Value is
10936
10937 CURSOR_MOVEMENT_SUCCESS if successful
10938
10939 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
10940
10941 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
10942 display. *SCROLL_STEP is set to 1, under certain circumstances, if
10943 we want to scroll as if scroll-step were set to 1. See the code.
10944
10945 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
10946 which case we have to abort this redisplay, and adjust matrices
10947 first. */
10948
10949 enum
10950 {
10951 CURSOR_MOVEMENT_SUCCESS,
10952 CURSOR_MOVEMENT_CANNOT_BE_USED,
10953 CURSOR_MOVEMENT_MUST_SCROLL,
10954 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
10955 };
10956
10957 static int
10958 try_cursor_movement (window, startp, scroll_step)
10959 Lisp_Object window;
10960 struct text_pos startp;
10961 int *scroll_step;
10962 {
10963 struct window *w = XWINDOW (window);
10964 struct frame *f = XFRAME (w->frame);
10965 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
10966
10967 #if GLYPH_DEBUG
10968 if (inhibit_try_cursor_movement)
10969 return rc;
10970 #endif
10971
10972 /* Handle case where text has not changed, only point, and it has
10973 not moved off the frame. */
10974 if (/* Point may be in this window. */
10975 PT >= CHARPOS (startp)
10976 /* Selective display hasn't changed. */
10977 && !current_buffer->clip_changed
10978 /* Function force-mode-line-update is used to force a thorough
10979 redisplay. It sets either windows_or_buffers_changed or
10980 update_mode_lines. So don't take a shortcut here for these
10981 cases. */
10982 && !update_mode_lines
10983 && !windows_or_buffers_changed
10984 && !cursor_type_changed
10985 /* Can't use this case if highlighting a region. When a
10986 region exists, cursor movement has to do more than just
10987 set the cursor. */
10988 && !(!NILP (Vtransient_mark_mode)
10989 && !NILP (current_buffer->mark_active))
10990 && NILP (w->region_showing)
10991 && NILP (Vshow_trailing_whitespace)
10992 /* Right after splitting windows, last_point may be nil. */
10993 && INTEGERP (w->last_point)
10994 /* This code is not used for mini-buffer for the sake of the case
10995 of redisplaying to replace an echo area message; since in
10996 that case the mini-buffer contents per se are usually
10997 unchanged. This code is of no real use in the mini-buffer
10998 since the handling of this_line_start_pos, etc., in redisplay
10999 handles the same cases. */
11000 && !EQ (window, minibuf_window)
11001 /* When splitting windows or for new windows, it happens that
11002 redisplay is called with a nil window_end_vpos or one being
11003 larger than the window. This should really be fixed in
11004 window.c. I don't have this on my list, now, so we do
11005 approximately the same as the old redisplay code. --gerd. */
11006 && INTEGERP (w->window_end_vpos)
11007 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11008 && (FRAME_WINDOW_P (f)
11009 || !MARKERP (Voverlay_arrow_position)
11010 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11011 {
11012 int this_scroll_margin;
11013 struct glyph_row *row = NULL;
11014
11015 #if GLYPH_DEBUG
11016 debug_method_add (w, "cursor movement");
11017 #endif
11018
11019 /* Scroll if point within this distance from the top or bottom
11020 of the window. This is a pixel value. */
11021 this_scroll_margin = max (0, scroll_margin);
11022 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11023 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11024
11025 /* Start with the row the cursor was displayed during the last
11026 not paused redisplay. Give up if that row is not valid. */
11027 if (w->last_cursor.vpos < 0
11028 || w->last_cursor.vpos >= w->current_matrix->nrows)
11029 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11030 else
11031 {
11032 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11033 if (row->mode_line_p)
11034 ++row;
11035 if (!row->enabled_p)
11036 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11037 }
11038
11039 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11040 {
11041 int scroll_p = 0;
11042 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11043
11044 if (PT > XFASTINT (w->last_point))
11045 {
11046 /* Point has moved forward. */
11047 while (MATRIX_ROW_END_CHARPOS (row) < PT
11048 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11049 {
11050 xassert (row->enabled_p);
11051 ++row;
11052 }
11053
11054 /* The end position of a row equals the start position
11055 of the next row. If PT is there, we would rather
11056 display it in the next line. */
11057 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11058 && MATRIX_ROW_END_CHARPOS (row) == PT
11059 && !cursor_row_p (w, row))
11060 ++row;
11061
11062 /* If within the scroll margin, scroll. Note that
11063 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11064 the next line would be drawn, and that
11065 this_scroll_margin can be zero. */
11066 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11067 || PT > MATRIX_ROW_END_CHARPOS (row)
11068 /* Line is completely visible last line in window
11069 and PT is to be set in the next line. */
11070 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11071 && PT == MATRIX_ROW_END_CHARPOS (row)
11072 && !row->ends_at_zv_p
11073 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11074 scroll_p = 1;
11075 }
11076 else if (PT < XFASTINT (w->last_point))
11077 {
11078 /* Cursor has to be moved backward. Note that PT >=
11079 CHARPOS (startp) because of the outer
11080 if-statement. */
11081 while (!row->mode_line_p
11082 && (MATRIX_ROW_START_CHARPOS (row) > PT
11083 || (MATRIX_ROW_START_CHARPOS (row) == PT
11084 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11085 && (row->y > this_scroll_margin
11086 || CHARPOS (startp) == BEGV))
11087 {
11088 xassert (row->enabled_p);
11089 --row;
11090 }
11091
11092 /* Consider the following case: Window starts at BEGV,
11093 there is invisible, intangible text at BEGV, so that
11094 display starts at some point START > BEGV. It can
11095 happen that we are called with PT somewhere between
11096 BEGV and START. Try to handle that case. */
11097 if (row < w->current_matrix->rows
11098 || row->mode_line_p)
11099 {
11100 row = w->current_matrix->rows;
11101 if (row->mode_line_p)
11102 ++row;
11103 }
11104
11105 /* Due to newlines in overlay strings, we may have to
11106 skip forward over overlay strings. */
11107 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11108 && MATRIX_ROW_END_CHARPOS (row) == PT
11109 && !cursor_row_p (w, row))
11110 ++row;
11111
11112 /* If within the scroll margin, scroll. */
11113 if (row->y < this_scroll_margin
11114 && CHARPOS (startp) != BEGV)
11115 scroll_p = 1;
11116 }
11117
11118 if (PT < MATRIX_ROW_START_CHARPOS (row)
11119 || PT > MATRIX_ROW_END_CHARPOS (row))
11120 {
11121 /* if PT is not in the glyph row, give up. */
11122 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11123 }
11124 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11125 {
11126 if (PT == MATRIX_ROW_END_CHARPOS (row)
11127 && !row->ends_at_zv_p
11128 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11129 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11130 else if (row->height > window_box_height (w))
11131 {
11132 /* If we end up in a partially visible line, let's
11133 make it fully visible, except when it's taller
11134 than the window, in which case we can't do much
11135 about it. */
11136 *scroll_step = 1;
11137 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11138 }
11139 else
11140 {
11141 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11142 if (!make_cursor_line_fully_visible (w))
11143 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11144 else
11145 rc = CURSOR_MOVEMENT_SUCCESS;
11146 }
11147 }
11148 else if (scroll_p)
11149 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11150 else
11151 {
11152 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11153 rc = CURSOR_MOVEMENT_SUCCESS;
11154 }
11155 }
11156 }
11157
11158 return rc;
11159 }
11160
11161 void
11162 set_vertical_scroll_bar (w)
11163 struct window *w;
11164 {
11165 int start, end, whole;
11166
11167 /* Calculate the start and end positions for the current window.
11168 At some point, it would be nice to choose between scrollbars
11169 which reflect the whole buffer size, with special markers
11170 indicating narrowing, and scrollbars which reflect only the
11171 visible region.
11172
11173 Note that mini-buffers sometimes aren't displaying any text. */
11174 if (!MINI_WINDOW_P (w)
11175 || (w == XWINDOW (minibuf_window)
11176 && NILP (echo_area_buffer[0])))
11177 {
11178 struct buffer *buf = XBUFFER (w->buffer);
11179 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11180 start = marker_position (w->start) - BUF_BEGV (buf);
11181 /* I don't think this is guaranteed to be right. For the
11182 moment, we'll pretend it is. */
11183 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11184
11185 if (end < start)
11186 end = start;
11187 if (whole < (end - start))
11188 whole = end - start;
11189 }
11190 else
11191 start = end = whole = 0;
11192
11193 /* Indicate what this scroll bar ought to be displaying now. */
11194 if (FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
11195 (*FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
11196 (w, end - start, whole, start);
11197 }
11198
11199
11200 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11201 selected_window is redisplayed.
11202
11203 We can return without actually redisplaying the window if
11204 fonts_changed_p is nonzero. In that case, redisplay_internal will
11205 retry. */
11206
11207 static void
11208 redisplay_window (window, just_this_one_p)
11209 Lisp_Object window;
11210 int just_this_one_p;
11211 {
11212 struct window *w = XWINDOW (window);
11213 struct frame *f = XFRAME (w->frame);
11214 struct buffer *buffer = XBUFFER (w->buffer);
11215 struct buffer *old = current_buffer;
11216 struct text_pos lpoint, opoint, startp;
11217 int update_mode_line;
11218 int tem;
11219 struct it it;
11220 /* Record it now because it's overwritten. */
11221 int current_matrix_up_to_date_p = 0;
11222 int used_current_matrix_p = 0;
11223 /* This is less strict than current_matrix_up_to_date_p.
11224 It indictes that the buffer contents and narrowing are unchanged. */
11225 int buffer_unchanged_p = 0;
11226 int temp_scroll_step = 0;
11227 int count = SPECPDL_INDEX ();
11228 int rc;
11229 int centering_position;
11230 int last_line_misfit = 0;
11231
11232 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11233 opoint = lpoint;
11234
11235 /* W must be a leaf window here. */
11236 xassert (!NILP (w->buffer));
11237 #if GLYPH_DEBUG
11238 *w->desired_matrix->method = 0;
11239 #endif
11240
11241 specbind (Qinhibit_point_motion_hooks, Qt);
11242
11243 reconsider_clip_changes (w, buffer);
11244
11245 /* Has the mode line to be updated? */
11246 update_mode_line = (!NILP (w->update_mode_line)
11247 || update_mode_lines
11248 || buffer->clip_changed
11249 || buffer->prevent_redisplay_optimizations_p);
11250
11251 if (MINI_WINDOW_P (w))
11252 {
11253 if (w == XWINDOW (echo_area_window)
11254 && !NILP (echo_area_buffer[0]))
11255 {
11256 if (update_mode_line)
11257 /* We may have to update a tty frame's menu bar or a
11258 tool-bar. Example `M-x C-h C-h C-g'. */
11259 goto finish_menu_bars;
11260 else
11261 /* We've already displayed the echo area glyphs in this window. */
11262 goto finish_scroll_bars;
11263 }
11264 else if ((w != XWINDOW (minibuf_window)
11265 || minibuf_level == 0)
11266 /* When buffer is nonempty, redisplay window normally. */
11267 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11268 /* Quail displays non-mini buffers in minibuffer window.
11269 In that case, redisplay the window normally. */
11270 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11271 {
11272 /* W is a mini-buffer window, but it's not active, so clear
11273 it. */
11274 int yb = window_text_bottom_y (w);
11275 struct glyph_row *row;
11276 int y;
11277
11278 for (y = 0, row = w->desired_matrix->rows;
11279 y < yb;
11280 y += row->height, ++row)
11281 blank_row (w, row, y);
11282 goto finish_scroll_bars;
11283 }
11284
11285 clear_glyph_matrix (w->desired_matrix);
11286 }
11287
11288 /* Otherwise set up data on this window; select its buffer and point
11289 value. */
11290 /* Really select the buffer, for the sake of buffer-local
11291 variables. */
11292 set_buffer_internal_1 (XBUFFER (w->buffer));
11293 SET_TEXT_POS (opoint, PT, PT_BYTE);
11294
11295 current_matrix_up_to_date_p
11296 = (!NILP (w->window_end_valid)
11297 && !current_buffer->clip_changed
11298 && !current_buffer->prevent_redisplay_optimizations_p
11299 && XFASTINT (w->last_modified) >= MODIFF
11300 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11301
11302 buffer_unchanged_p
11303 = (!NILP (w->window_end_valid)
11304 && !current_buffer->clip_changed
11305 && XFASTINT (w->last_modified) >= MODIFF
11306 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11307
11308 /* When windows_or_buffers_changed is non-zero, we can't rely on
11309 the window end being valid, so set it to nil there. */
11310 if (windows_or_buffers_changed)
11311 {
11312 /* If window starts on a continuation line, maybe adjust the
11313 window start in case the window's width changed. */
11314 if (XMARKER (w->start)->buffer == current_buffer)
11315 compute_window_start_on_continuation_line (w);
11316
11317 w->window_end_valid = Qnil;
11318 }
11319
11320 /* Some sanity checks. */
11321 CHECK_WINDOW_END (w);
11322 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11323 abort ();
11324 if (BYTEPOS (opoint) < CHARPOS (opoint))
11325 abort ();
11326
11327 /* If %c is in mode line, update it if needed. */
11328 if (!NILP (w->column_number_displayed)
11329 /* This alternative quickly identifies a common case
11330 where no change is needed. */
11331 && !(PT == XFASTINT (w->last_point)
11332 && XFASTINT (w->last_modified) >= MODIFF
11333 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11334 && (XFASTINT (w->column_number_displayed)
11335 != (int) current_column ())) /* iftc */
11336 update_mode_line = 1;
11337
11338 /* Count number of windows showing the selected buffer. An indirect
11339 buffer counts as its base buffer. */
11340 if (!just_this_one_p)
11341 {
11342 struct buffer *current_base, *window_base;
11343 current_base = current_buffer;
11344 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11345 if (current_base->base_buffer)
11346 current_base = current_base->base_buffer;
11347 if (window_base->base_buffer)
11348 window_base = window_base->base_buffer;
11349 if (current_base == window_base)
11350 buffer_shared++;
11351 }
11352
11353 /* Point refers normally to the selected window. For any other
11354 window, set up appropriate value. */
11355 if (!EQ (window, selected_window))
11356 {
11357 int new_pt = XMARKER (w->pointm)->charpos;
11358 int new_pt_byte = marker_byte_position (w->pointm);
11359 if (new_pt < BEGV)
11360 {
11361 new_pt = BEGV;
11362 new_pt_byte = BEGV_BYTE;
11363 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11364 }
11365 else if (new_pt > (ZV - 1))
11366 {
11367 new_pt = ZV;
11368 new_pt_byte = ZV_BYTE;
11369 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11370 }
11371
11372 /* We don't use SET_PT so that the point-motion hooks don't run. */
11373 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11374 }
11375
11376 /* If any of the character widths specified in the display table
11377 have changed, invalidate the width run cache. It's true that
11378 this may be a bit late to catch such changes, but the rest of
11379 redisplay goes (non-fatally) haywire when the display table is
11380 changed, so why should we worry about doing any better? */
11381 if (current_buffer->width_run_cache)
11382 {
11383 struct Lisp_Char_Table *disptab = buffer_display_table ();
11384
11385 if (! disptab_matches_widthtab (disptab,
11386 XVECTOR (current_buffer->width_table)))
11387 {
11388 invalidate_region_cache (current_buffer,
11389 current_buffer->width_run_cache,
11390 BEG, Z);
11391 recompute_width_table (current_buffer, disptab);
11392 }
11393 }
11394
11395 /* If window-start is screwed up, choose a new one. */
11396 if (XMARKER (w->start)->buffer != current_buffer)
11397 goto recenter;
11398
11399 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11400
11401 /* If someone specified a new starting point but did not insist,
11402 check whether it can be used. */
11403 if (!NILP (w->optional_new_start)
11404 && CHARPOS (startp) >= BEGV
11405 && CHARPOS (startp) <= ZV)
11406 {
11407 w->optional_new_start = Qnil;
11408 start_display (&it, w, startp);
11409 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11410 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11411 if (IT_CHARPOS (it) == PT)
11412 w->force_start = Qt;
11413 /* IT may overshoot PT if text at PT is invisible. */
11414 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11415 w->force_start = Qt;
11416
11417
11418 }
11419
11420 /* Handle case where place to start displaying has been specified,
11421 unless the specified location is outside the accessible range. */
11422 if (!NILP (w->force_start)
11423 || w->frozen_window_start_p)
11424 {
11425 /* We set this later on if we have to adjust point. */
11426 int new_vpos = -1;
11427
11428 w->force_start = Qnil;
11429 w->vscroll = 0;
11430 w->window_end_valid = Qnil;
11431
11432 /* Forget any recorded base line for line number display. */
11433 if (!buffer_unchanged_p)
11434 w->base_line_number = Qnil;
11435
11436 /* Redisplay the mode line. Select the buffer properly for that.
11437 Also, run the hook window-scroll-functions
11438 because we have scrolled. */
11439 /* Note, we do this after clearing force_start because
11440 if there's an error, it is better to forget about force_start
11441 than to get into an infinite loop calling the hook functions
11442 and having them get more errors. */
11443 if (!update_mode_line
11444 || ! NILP (Vwindow_scroll_functions))
11445 {
11446 update_mode_line = 1;
11447 w->update_mode_line = Qt;
11448 startp = run_window_scroll_functions (window, startp);
11449 }
11450
11451 w->last_modified = make_number (0);
11452 w->last_overlay_modified = make_number (0);
11453 if (CHARPOS (startp) < BEGV)
11454 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11455 else if (CHARPOS (startp) > ZV)
11456 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11457
11458 /* Redisplay, then check if cursor has been set during the
11459 redisplay. Give up if new fonts were loaded. */
11460 if (!try_window (window, startp))
11461 {
11462 w->force_start = Qt;
11463 clear_glyph_matrix (w->desired_matrix);
11464 goto need_larger_matrices;
11465 }
11466
11467 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11468 {
11469 /* If point does not appear, try to move point so it does
11470 appear. The desired matrix has been built above, so we
11471 can use it here. */
11472 new_vpos = window_box_height (w) / 2;
11473 }
11474
11475 if (!make_cursor_line_fully_visible (w))
11476 {
11477 /* Point does appear, but on a line partly visible at end of window.
11478 Move it back to a fully-visible line. */
11479 new_vpos = window_box_height (w);
11480 }
11481
11482 /* If we need to move point for either of the above reasons,
11483 now actually do it. */
11484 if (new_vpos >= 0)
11485 {
11486 struct glyph_row *row;
11487
11488 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11489 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11490 ++row;
11491
11492 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11493 MATRIX_ROW_START_BYTEPOS (row));
11494
11495 if (w != XWINDOW (selected_window))
11496 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11497 else if (current_buffer == old)
11498 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11499
11500 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11501
11502 /* If we are highlighting the region, then we just changed
11503 the region, so redisplay to show it. */
11504 if (!NILP (Vtransient_mark_mode)
11505 && !NILP (current_buffer->mark_active))
11506 {
11507 clear_glyph_matrix (w->desired_matrix);
11508 if (!try_window (window, startp))
11509 goto need_larger_matrices;
11510 }
11511 }
11512
11513 #if GLYPH_DEBUG
11514 debug_method_add (w, "forced window start");
11515 #endif
11516 goto done;
11517 }
11518
11519 /* Handle case where text has not changed, only point, and it has
11520 not moved off the frame, and we are not retrying after hscroll.
11521 (current_matrix_up_to_date_p is nonzero when retrying.) */
11522 if (current_matrix_up_to_date_p
11523 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11524 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11525 {
11526 switch (rc)
11527 {
11528 case CURSOR_MOVEMENT_SUCCESS:
11529 used_current_matrix_p = 1;
11530 goto done;
11531
11532 #if 0 /* try_cursor_movement never returns this value. */
11533 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11534 goto need_larger_matrices;
11535 #endif
11536
11537 case CURSOR_MOVEMENT_MUST_SCROLL:
11538 goto try_to_scroll;
11539
11540 default:
11541 abort ();
11542 }
11543 }
11544 /* If current starting point was originally the beginning of a line
11545 but no longer is, find a new starting point. */
11546 else if (!NILP (w->start_at_line_beg)
11547 && !(CHARPOS (startp) <= BEGV
11548 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11549 {
11550 #if GLYPH_DEBUG
11551 debug_method_add (w, "recenter 1");
11552 #endif
11553 goto recenter;
11554 }
11555
11556 /* Try scrolling with try_window_id. Value is > 0 if update has
11557 been done, it is -1 if we know that the same window start will
11558 not work. It is 0 if unsuccessful for some other reason. */
11559 else if ((tem = try_window_id (w)) != 0)
11560 {
11561 #if GLYPH_DEBUG
11562 debug_method_add (w, "try_window_id %d", tem);
11563 #endif
11564
11565 if (fonts_changed_p)
11566 goto need_larger_matrices;
11567 if (tem > 0)
11568 goto done;
11569
11570 /* Otherwise try_window_id has returned -1 which means that we
11571 don't want the alternative below this comment to execute. */
11572 }
11573 else if (CHARPOS (startp) >= BEGV
11574 && CHARPOS (startp) <= ZV
11575 && PT >= CHARPOS (startp)
11576 && (CHARPOS (startp) < ZV
11577 /* Avoid starting at end of buffer. */
11578 || CHARPOS (startp) == BEGV
11579 || (XFASTINT (w->last_modified) >= MODIFF
11580 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11581 {
11582 #if GLYPH_DEBUG
11583 debug_method_add (w, "same window start");
11584 #endif
11585
11586 /* Try to redisplay starting at same place as before.
11587 If point has not moved off frame, accept the results. */
11588 if (!current_matrix_up_to_date_p
11589 /* Don't use try_window_reusing_current_matrix in this case
11590 because a window scroll function can have changed the
11591 buffer. */
11592 || !NILP (Vwindow_scroll_functions)
11593 || MINI_WINDOW_P (w)
11594 || !(used_current_matrix_p =
11595 try_window_reusing_current_matrix (w)))
11596 {
11597 IF_DEBUG (debug_method_add (w, "1"));
11598 try_window (window, startp);
11599 }
11600
11601 if (fonts_changed_p)
11602 goto need_larger_matrices;
11603
11604 if (w->cursor.vpos >= 0)
11605 {
11606 if (!just_this_one_p
11607 || current_buffer->clip_changed
11608 || BEG_UNCHANGED < CHARPOS (startp))
11609 /* Forget any recorded base line for line number display. */
11610 w->base_line_number = Qnil;
11611
11612 if (!make_cursor_line_fully_visible (w))
11613 {
11614 clear_glyph_matrix (w->desired_matrix);
11615 last_line_misfit = 1;
11616 }
11617 /* Drop through and scroll. */
11618 else
11619 goto done;
11620 }
11621 else
11622 clear_glyph_matrix (w->desired_matrix);
11623 }
11624
11625 try_to_scroll:
11626
11627 w->last_modified = make_number (0);
11628 w->last_overlay_modified = make_number (0);
11629
11630 /* Redisplay the mode line. Select the buffer properly for that. */
11631 if (!update_mode_line)
11632 {
11633 update_mode_line = 1;
11634 w->update_mode_line = Qt;
11635 }
11636
11637 /* Try to scroll by specified few lines. */
11638 if ((scroll_conservatively
11639 || scroll_step
11640 || temp_scroll_step
11641 || NUMBERP (current_buffer->scroll_up_aggressively)
11642 || NUMBERP (current_buffer->scroll_down_aggressively))
11643 && !current_buffer->clip_changed
11644 && CHARPOS (startp) >= BEGV
11645 && CHARPOS (startp) <= ZV)
11646 {
11647 /* The function returns -1 if new fonts were loaded, 1 if
11648 successful, 0 if not successful. */
11649 int rc = try_scrolling (window, just_this_one_p,
11650 scroll_conservatively,
11651 scroll_step,
11652 temp_scroll_step, last_line_misfit);
11653 switch (rc)
11654 {
11655 case SCROLLING_SUCCESS:
11656 goto done;
11657
11658 case SCROLLING_NEED_LARGER_MATRICES:
11659 goto need_larger_matrices;
11660
11661 case SCROLLING_FAILED:
11662 break;
11663
11664 default:
11665 abort ();
11666 }
11667 }
11668
11669 /* Finally, just choose place to start which centers point */
11670
11671 recenter:
11672 centering_position = window_box_height (w) / 2;
11673
11674 point_at_top:
11675 /* Jump here with centering_position already set to 0. */
11676
11677 #if GLYPH_DEBUG
11678 debug_method_add (w, "recenter");
11679 #endif
11680
11681 /* w->vscroll = 0; */
11682
11683 /* Forget any previously recorded base line for line number display. */
11684 if (!buffer_unchanged_p)
11685 w->base_line_number = Qnil;
11686
11687 /* Move backward half the height of the window. */
11688 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11689 it.current_y = it.last_visible_y;
11690 move_it_vertically_backward (&it, centering_position);
11691 xassert (IT_CHARPOS (it) >= BEGV);
11692
11693 /* The function move_it_vertically_backward may move over more
11694 than the specified y-distance. If it->w is small, e.g. a
11695 mini-buffer window, we may end up in front of the window's
11696 display area. Start displaying at the start of the line
11697 containing PT in this case. */
11698 if (it.current_y <= 0)
11699 {
11700 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11701 move_it_vertically (&it, 0);
11702 xassert (IT_CHARPOS (it) <= PT);
11703 it.current_y = 0;
11704 }
11705
11706 it.current_x = it.hpos = 0;
11707
11708 /* Set startp here explicitly in case that helps avoid an infinite loop
11709 in case the window-scroll-functions functions get errors. */
11710 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11711
11712 /* Run scroll hooks. */
11713 startp = run_window_scroll_functions (window, it.current.pos);
11714
11715 /* Redisplay the window. */
11716 if (!current_matrix_up_to_date_p
11717 || windows_or_buffers_changed
11718 || cursor_type_changed
11719 /* Don't use try_window_reusing_current_matrix in this case
11720 because it can have changed the buffer. */
11721 || !NILP (Vwindow_scroll_functions)
11722 || !just_this_one_p
11723 || MINI_WINDOW_P (w)
11724 || !(used_current_matrix_p =
11725 try_window_reusing_current_matrix (w)))
11726 try_window (window, startp);
11727
11728 /* If new fonts have been loaded (due to fontsets), give up. We
11729 have to start a new redisplay since we need to re-adjust glyph
11730 matrices. */
11731 if (fonts_changed_p)
11732 goto need_larger_matrices;
11733
11734 /* If cursor did not appear assume that the middle of the window is
11735 in the first line of the window. Do it again with the next line.
11736 (Imagine a window of height 100, displaying two lines of height
11737 60. Moving back 50 from it->last_visible_y will end in the first
11738 line.) */
11739 if (w->cursor.vpos < 0)
11740 {
11741 if (!NILP (w->window_end_valid)
11742 && PT >= Z - XFASTINT (w->window_end_pos))
11743 {
11744 clear_glyph_matrix (w->desired_matrix);
11745 move_it_by_lines (&it, 1, 0);
11746 try_window (window, it.current.pos);
11747 }
11748 else if (PT < IT_CHARPOS (it))
11749 {
11750 clear_glyph_matrix (w->desired_matrix);
11751 move_it_by_lines (&it, -1, 0);
11752 try_window (window, it.current.pos);
11753 }
11754 else
11755 {
11756 /* Not much we can do about it. */
11757 }
11758 }
11759
11760 /* Consider the following case: Window starts at BEGV, there is
11761 invisible, intangible text at BEGV, so that display starts at
11762 some point START > BEGV. It can happen that we are called with
11763 PT somewhere between BEGV and START. Try to handle that case. */
11764 if (w->cursor.vpos < 0)
11765 {
11766 struct glyph_row *row = w->current_matrix->rows;
11767 if (row->mode_line_p)
11768 ++row;
11769 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11770 }
11771
11772 if (!make_cursor_line_fully_visible (w))
11773 {
11774 /* If vscroll is enabled, disable it and try again. */
11775 if (w->vscroll)
11776 {
11777 w->vscroll = 0;
11778 clear_glyph_matrix (w->desired_matrix);
11779 goto recenter;
11780 }
11781
11782 /* If centering point failed to make the whole line visible,
11783 put point at the top instead. That has to make the whole line
11784 visible, if it can be done. */
11785 centering_position = 0;
11786 goto point_at_top;
11787 }
11788
11789 done:
11790
11791 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11792 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11793 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11794 ? Qt : Qnil);
11795
11796 /* Display the mode line, if we must. */
11797 if ((update_mode_line
11798 /* If window not full width, must redo its mode line
11799 if (a) the window to its side is being redone and
11800 (b) we do a frame-based redisplay. This is a consequence
11801 of how inverted lines are drawn in frame-based redisplay. */
11802 || (!just_this_one_p
11803 && !FRAME_WINDOW_P (f)
11804 && !WINDOW_FULL_WIDTH_P (w))
11805 /* Line number to display. */
11806 || INTEGERP (w->base_line_pos)
11807 /* Column number is displayed and different from the one displayed. */
11808 || (!NILP (w->column_number_displayed)
11809 && (XFASTINT (w->column_number_displayed)
11810 != (int) current_column ()))) /* iftc */
11811 /* This means that the window has a mode line. */
11812 && (WINDOW_WANTS_MODELINE_P (w)
11813 || WINDOW_WANTS_HEADER_LINE_P (w)))
11814 {
11815 display_mode_lines (w);
11816
11817 /* If mode line height has changed, arrange for a thorough
11818 immediate redisplay using the correct mode line height. */
11819 if (WINDOW_WANTS_MODELINE_P (w)
11820 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
11821 {
11822 fonts_changed_p = 1;
11823 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
11824 = DESIRED_MODE_LINE_HEIGHT (w);
11825 }
11826
11827 /* If top line height has changed, arrange for a thorough
11828 immediate redisplay using the correct mode line height. */
11829 if (WINDOW_WANTS_HEADER_LINE_P (w)
11830 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
11831 {
11832 fonts_changed_p = 1;
11833 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
11834 = DESIRED_HEADER_LINE_HEIGHT (w);
11835 }
11836
11837 if (fonts_changed_p)
11838 goto need_larger_matrices;
11839 }
11840
11841 if (!line_number_displayed
11842 && !BUFFERP (w->base_line_pos))
11843 {
11844 w->base_line_pos = Qnil;
11845 w->base_line_number = Qnil;
11846 }
11847
11848 finish_menu_bars:
11849
11850 /* When we reach a frame's selected window, redo the frame's menu bar. */
11851 if (update_mode_line
11852 && EQ (FRAME_SELECTED_WINDOW (f), window))
11853 {
11854 int redisplay_menu_p = 0;
11855 int redisplay_tool_bar_p = 0;
11856
11857 if (FRAME_WINDOW_P (f))
11858 {
11859 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
11860 || defined (USE_GTK)
11861 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
11862 #else
11863 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11864 #endif
11865 }
11866 else
11867 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11868
11869 if (redisplay_menu_p)
11870 display_menu_bar (w);
11871
11872 #ifdef HAVE_WINDOW_SYSTEM
11873 #ifdef USE_GTK
11874 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
11875 #else
11876 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
11877 && (FRAME_TOOL_BAR_LINES (f) > 0
11878 || auto_resize_tool_bars_p);
11879
11880 #endif
11881
11882 if (redisplay_tool_bar_p)
11883 redisplay_tool_bar (f);
11884 #endif
11885 }
11886
11887 #ifdef HAVE_WINDOW_SYSTEM
11888 if (update_window_fringes (w, 0)
11889 && !just_this_one_p
11890 && (used_current_matrix_p || overlay_arrow_seen)
11891 && !w->pseudo_window_p)
11892 {
11893 update_begin (f);
11894 BLOCK_INPUT;
11895 draw_window_fringes (w);
11896 UNBLOCK_INPUT;
11897 update_end (f);
11898 }
11899 #endif /* HAVE_WINDOW_SYSTEM */
11900
11901 /* We go to this label, with fonts_changed_p nonzero,
11902 if it is necessary to try again using larger glyph matrices.
11903 We have to redeem the scroll bar even in this case,
11904 because the loop in redisplay_internal expects that. */
11905 need_larger_matrices:
11906 ;
11907 finish_scroll_bars:
11908
11909 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
11910 {
11911 /* Set the thumb's position and size. */
11912 set_vertical_scroll_bar (w);
11913
11914 /* Note that we actually used the scroll bar attached to this
11915 window, so it shouldn't be deleted at the end of redisplay. */
11916 if (FRAME_DISPLAY (f)->redeem_scroll_bar_hook)
11917 (*FRAME_DISPLAY (f)->redeem_scroll_bar_hook) (w);
11918 }
11919
11920 /* Restore current_buffer and value of point in it. */
11921 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
11922 set_buffer_internal_1 (old);
11923 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
11924
11925 unbind_to (count, Qnil);
11926 }
11927
11928
11929 /* Build the complete desired matrix of WINDOW with a window start
11930 buffer position POS. Value is non-zero if successful. It is zero
11931 if fonts were loaded during redisplay which makes re-adjusting
11932 glyph matrices necessary. */
11933
11934 int
11935 try_window (window, pos)
11936 Lisp_Object window;
11937 struct text_pos pos;
11938 {
11939 struct window *w = XWINDOW (window);
11940 struct it it;
11941 struct glyph_row *last_text_row = NULL;
11942
11943 /* Make POS the new window start. */
11944 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
11945
11946 /* Mark cursor position as unknown. No overlay arrow seen. */
11947 w->cursor.vpos = -1;
11948 overlay_arrow_seen = 0;
11949
11950 /* Initialize iterator and info to start at POS. */
11951 start_display (&it, w, pos);
11952
11953 /* Display all lines of W. */
11954 while (it.current_y < it.last_visible_y)
11955 {
11956 if (display_line (&it))
11957 last_text_row = it.glyph_row - 1;
11958 if (fonts_changed_p)
11959 return 0;
11960 }
11961
11962 /* If bottom moved off end of frame, change mode line percentage. */
11963 if (XFASTINT (w->window_end_pos) <= 0
11964 && Z != IT_CHARPOS (it))
11965 w->update_mode_line = Qt;
11966
11967 /* Set window_end_pos to the offset of the last character displayed
11968 on the window from the end of current_buffer. Set
11969 window_end_vpos to its row number. */
11970 if (last_text_row)
11971 {
11972 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
11973 w->window_end_bytepos
11974 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
11975 w->window_end_pos
11976 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
11977 w->window_end_vpos
11978 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
11979 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
11980 ->displays_text_p);
11981 }
11982 else
11983 {
11984 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
11985 w->window_end_pos = make_number (Z - ZV);
11986 w->window_end_vpos = make_number (0);
11987 }
11988
11989 /* But that is not valid info until redisplay finishes. */
11990 w->window_end_valid = Qnil;
11991 return 1;
11992 }
11993
11994
11995 \f
11996 /************************************************************************
11997 Window redisplay reusing current matrix when buffer has not changed
11998 ************************************************************************/
11999
12000 /* Try redisplay of window W showing an unchanged buffer with a
12001 different window start than the last time it was displayed by
12002 reusing its current matrix. Value is non-zero if successful.
12003 W->start is the new window start. */
12004
12005 static int
12006 try_window_reusing_current_matrix (w)
12007 struct window *w;
12008 {
12009 struct frame *f = XFRAME (w->frame);
12010 struct glyph_row *row, *bottom_row;
12011 struct it it;
12012 struct run run;
12013 struct text_pos start, new_start;
12014 int nrows_scrolled, i;
12015 struct glyph_row *last_text_row;
12016 struct glyph_row *last_reused_text_row;
12017 struct glyph_row *start_row;
12018 int start_vpos, min_y, max_y;
12019
12020 #if GLYPH_DEBUG
12021 if (inhibit_try_window_reusing)
12022 return 0;
12023 #endif
12024
12025 if (/* This function doesn't handle terminal frames. */
12026 !FRAME_WINDOW_P (f)
12027 /* Don't try to reuse the display if windows have been split
12028 or such. */
12029 || windows_or_buffers_changed
12030 || cursor_type_changed)
12031 return 0;
12032
12033 /* Can't do this if region may have changed. */
12034 if ((!NILP (Vtransient_mark_mode)
12035 && !NILP (current_buffer->mark_active))
12036 || !NILP (w->region_showing)
12037 || !NILP (Vshow_trailing_whitespace))
12038 return 0;
12039
12040 /* If top-line visibility has changed, give up. */
12041 if (WINDOW_WANTS_HEADER_LINE_P (w)
12042 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12043 return 0;
12044
12045 /* Give up if old or new display is scrolled vertically. We could
12046 make this function handle this, but right now it doesn't. */
12047 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12048 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12049 return 0;
12050
12051 /* The variable new_start now holds the new window start. The old
12052 start `start' can be determined from the current matrix. */
12053 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12054 start = start_row->start.pos;
12055 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12056
12057 /* Clear the desired matrix for the display below. */
12058 clear_glyph_matrix (w->desired_matrix);
12059
12060 if (CHARPOS (new_start) <= CHARPOS (start))
12061 {
12062 int first_row_y;
12063
12064 /* Don't use this method if the display starts with an ellipsis
12065 displayed for invisible text. It's not easy to handle that case
12066 below, and it's certainly not worth the effort since this is
12067 not a frequent case. */
12068 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12069 return 0;
12070
12071 IF_DEBUG (debug_method_add (w, "twu1"));
12072
12073 /* Display up to a row that can be reused. The variable
12074 last_text_row is set to the last row displayed that displays
12075 text. Note that it.vpos == 0 if or if not there is a
12076 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12077 start_display (&it, w, new_start);
12078 first_row_y = it.current_y;
12079 w->cursor.vpos = -1;
12080 last_text_row = last_reused_text_row = NULL;
12081
12082 while (it.current_y < it.last_visible_y
12083 && IT_CHARPOS (it) < CHARPOS (start)
12084 && !fonts_changed_p)
12085 if (display_line (&it))
12086 last_text_row = it.glyph_row - 1;
12087
12088 /* A value of current_y < last_visible_y means that we stopped
12089 at the previous window start, which in turn means that we
12090 have at least one reusable row. */
12091 if (it.current_y < it.last_visible_y)
12092 {
12093 /* IT.vpos always starts from 0; it counts text lines. */
12094 nrows_scrolled = it.vpos;
12095
12096 /* Find PT if not already found in the lines displayed. */
12097 if (w->cursor.vpos < 0)
12098 {
12099 int dy = it.current_y - first_row_y;
12100
12101 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12102 row = row_containing_pos (w, PT, row, NULL, dy);
12103 if (row)
12104 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12105 dy, nrows_scrolled);
12106 else
12107 {
12108 clear_glyph_matrix (w->desired_matrix);
12109 return 0;
12110 }
12111 }
12112
12113 /* Scroll the display. Do it before the current matrix is
12114 changed. The problem here is that update has not yet
12115 run, i.e. part of the current matrix is not up to date.
12116 scroll_run_hook will clear the cursor, and use the
12117 current matrix to get the height of the row the cursor is
12118 in. */
12119 run.current_y = first_row_y;
12120 run.desired_y = it.current_y;
12121 run.height = it.last_visible_y - it.current_y;
12122
12123 if (run.height > 0 && run.current_y != run.desired_y)
12124 {
12125 update_begin (f);
12126 FRAME_RIF (f)->update_window_begin_hook (w);
12127 FRAME_RIF (f)->clear_window_mouse_face (w);
12128 FRAME_RIF (f)->scroll_run_hook (w, &run);
12129 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
12130 update_end (f);
12131 }
12132
12133 /* Shift current matrix down by nrows_scrolled lines. */
12134 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12135 rotate_matrix (w->current_matrix,
12136 start_vpos,
12137 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12138 nrows_scrolled);
12139
12140 /* Disable lines that must be updated. */
12141 for (i = 0; i < it.vpos; ++i)
12142 (start_row + i)->enabled_p = 0;
12143
12144 /* Re-compute Y positions. */
12145 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12146 max_y = it.last_visible_y;
12147 for (row = start_row + nrows_scrolled;
12148 row < bottom_row;
12149 ++row)
12150 {
12151 row->y = it.current_y;
12152 row->visible_height = row->height;
12153
12154 if (row->y < min_y)
12155 row->visible_height -= min_y - row->y;
12156 if (row->y + row->height > max_y)
12157 row->visible_height -= row->y + row->height - max_y;
12158 row->redraw_fringe_bitmaps_p = 1;
12159
12160 it.current_y += row->height;
12161
12162 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12163 last_reused_text_row = row;
12164 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12165 break;
12166 }
12167
12168 /* Disable lines in the current matrix which are now
12169 below the window. */
12170 for (++row; row < bottom_row; ++row)
12171 row->enabled_p = 0;
12172 }
12173
12174 /* Update window_end_pos etc.; last_reused_text_row is the last
12175 reused row from the current matrix containing text, if any.
12176 The value of last_text_row is the last displayed line
12177 containing text. */
12178 if (last_reused_text_row)
12179 {
12180 w->window_end_bytepos
12181 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12182 w->window_end_pos
12183 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12184 w->window_end_vpos
12185 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12186 w->current_matrix));
12187 }
12188 else if (last_text_row)
12189 {
12190 w->window_end_bytepos
12191 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12192 w->window_end_pos
12193 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12194 w->window_end_vpos
12195 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12196 }
12197 else
12198 {
12199 /* This window must be completely empty. */
12200 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12201 w->window_end_pos = make_number (Z - ZV);
12202 w->window_end_vpos = make_number (0);
12203 }
12204 w->window_end_valid = Qnil;
12205
12206 /* Update hint: don't try scrolling again in update_window. */
12207 w->desired_matrix->no_scrolling_p = 1;
12208
12209 #if GLYPH_DEBUG
12210 debug_method_add (w, "try_window_reusing_current_matrix 1");
12211 #endif
12212 return 1;
12213 }
12214 else if (CHARPOS (new_start) > CHARPOS (start))
12215 {
12216 struct glyph_row *pt_row, *row;
12217 struct glyph_row *first_reusable_row;
12218 struct glyph_row *first_row_to_display;
12219 int dy;
12220 int yb = window_text_bottom_y (w);
12221
12222 /* Find the row starting at new_start, if there is one. Don't
12223 reuse a partially visible line at the end. */
12224 first_reusable_row = start_row;
12225 while (first_reusable_row->enabled_p
12226 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12227 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12228 < CHARPOS (new_start)))
12229 ++first_reusable_row;
12230
12231 /* Give up if there is no row to reuse. */
12232 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12233 || !first_reusable_row->enabled_p
12234 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12235 != CHARPOS (new_start)))
12236 return 0;
12237
12238 /* We can reuse fully visible rows beginning with
12239 first_reusable_row to the end of the window. Set
12240 first_row_to_display to the first row that cannot be reused.
12241 Set pt_row to the row containing point, if there is any. */
12242 pt_row = NULL;
12243 for (first_row_to_display = first_reusable_row;
12244 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12245 ++first_row_to_display)
12246 {
12247 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12248 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12249 pt_row = first_row_to_display;
12250 }
12251
12252 /* Start displaying at the start of first_row_to_display. */
12253 xassert (first_row_to_display->y < yb);
12254 init_to_row_start (&it, w, first_row_to_display);
12255
12256 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12257 - start_vpos);
12258 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12259 - nrows_scrolled);
12260 it.current_y = (first_row_to_display->y - first_reusable_row->y
12261 + WINDOW_HEADER_LINE_HEIGHT (w));
12262
12263 /* Display lines beginning with first_row_to_display in the
12264 desired matrix. Set last_text_row to the last row displayed
12265 that displays text. */
12266 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12267 if (pt_row == NULL)
12268 w->cursor.vpos = -1;
12269 last_text_row = NULL;
12270 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12271 if (display_line (&it))
12272 last_text_row = it.glyph_row - 1;
12273
12274 /* Give up If point isn't in a row displayed or reused. */
12275 if (w->cursor.vpos < 0)
12276 {
12277 clear_glyph_matrix (w->desired_matrix);
12278 return 0;
12279 }
12280
12281 /* If point is in a reused row, adjust y and vpos of the cursor
12282 position. */
12283 if (pt_row)
12284 {
12285 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12286 w->current_matrix);
12287 w->cursor.y -= first_reusable_row->y;
12288 }
12289
12290 /* Scroll the display. */
12291 run.current_y = first_reusable_row->y;
12292 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12293 run.height = it.last_visible_y - run.current_y;
12294 dy = run.current_y - run.desired_y;
12295
12296 if (run.height)
12297 {
12298 update_begin (f);
12299 FRAME_RIF (f)->update_window_begin_hook (w);
12300 FRAME_RIF (f)->clear_window_mouse_face (w);
12301 FRAME_RIF (f)->scroll_run_hook (w, &run);
12302 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
12303 update_end (f);
12304 }
12305
12306 /* Adjust Y positions of reused rows. */
12307 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12308 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12309 max_y = it.last_visible_y;
12310 for (row = first_reusable_row; row < first_row_to_display; ++row)
12311 {
12312 row->y -= dy;
12313 row->visible_height = row->height;
12314 if (row->y < min_y)
12315 row->visible_height -= min_y - row->y;
12316 if (row->y + row->height > max_y)
12317 row->visible_height -= row->y + row->height - max_y;
12318 row->redraw_fringe_bitmaps_p = 1;
12319 }
12320
12321 /* Scroll the current matrix. */
12322 xassert (nrows_scrolled > 0);
12323 rotate_matrix (w->current_matrix,
12324 start_vpos,
12325 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12326 -nrows_scrolled);
12327
12328 /* Disable rows not reused. */
12329 for (row -= nrows_scrolled; row < bottom_row; ++row)
12330 row->enabled_p = 0;
12331
12332 /* Adjust window end. A null value of last_text_row means that
12333 the window end is in reused rows which in turn means that
12334 only its vpos can have changed. */
12335 if (last_text_row)
12336 {
12337 w->window_end_bytepos
12338 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12339 w->window_end_pos
12340 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12341 w->window_end_vpos
12342 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12343 }
12344 else
12345 {
12346 w->window_end_vpos
12347 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12348 }
12349
12350 w->window_end_valid = Qnil;
12351 w->desired_matrix->no_scrolling_p = 1;
12352
12353 #if GLYPH_DEBUG
12354 debug_method_add (w, "try_window_reusing_current_matrix 2");
12355 #endif
12356 return 1;
12357 }
12358
12359 return 0;
12360 }
12361
12362
12363 \f
12364 /************************************************************************
12365 Window redisplay reusing current matrix when buffer has changed
12366 ************************************************************************/
12367
12368 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12369 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12370 int *, int *));
12371 static struct glyph_row *
12372 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12373 struct glyph_row *));
12374
12375
12376 /* Return the last row in MATRIX displaying text. If row START is
12377 non-null, start searching with that row. IT gives the dimensions
12378 of the display. Value is null if matrix is empty; otherwise it is
12379 a pointer to the row found. */
12380
12381 static struct glyph_row *
12382 find_last_row_displaying_text (matrix, it, start)
12383 struct glyph_matrix *matrix;
12384 struct it *it;
12385 struct glyph_row *start;
12386 {
12387 struct glyph_row *row, *row_found;
12388
12389 /* Set row_found to the last row in IT->w's current matrix
12390 displaying text. The loop looks funny but think of partially
12391 visible lines. */
12392 row_found = NULL;
12393 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12394 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12395 {
12396 xassert (row->enabled_p);
12397 row_found = row;
12398 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12399 break;
12400 ++row;
12401 }
12402
12403 return row_found;
12404 }
12405
12406
12407 /* Return the last row in the current matrix of W that is not affected
12408 by changes at the start of current_buffer that occurred since W's
12409 current matrix was built. Value is null if no such row exists.
12410
12411 BEG_UNCHANGED us the number of characters unchanged at the start of
12412 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12413 first changed character in current_buffer. Characters at positions <
12414 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12415 when the current matrix was built. */
12416
12417 static struct glyph_row *
12418 find_last_unchanged_at_beg_row (w)
12419 struct window *w;
12420 {
12421 int first_changed_pos = BEG + BEG_UNCHANGED;
12422 struct glyph_row *row;
12423 struct glyph_row *row_found = NULL;
12424 int yb = window_text_bottom_y (w);
12425
12426 /* Find the last row displaying unchanged text. */
12427 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12428 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12429 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12430 {
12431 if (/* If row ends before first_changed_pos, it is unchanged,
12432 except in some case. */
12433 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12434 /* When row ends in ZV and we write at ZV it is not
12435 unchanged. */
12436 && !row->ends_at_zv_p
12437 /* When first_changed_pos is the end of a continued line,
12438 row is not unchanged because it may be no longer
12439 continued. */
12440 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12441 && (row->continued_p
12442 || row->exact_window_width_line_p)))
12443 row_found = row;
12444
12445 /* Stop if last visible row. */
12446 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12447 break;
12448
12449 ++row;
12450 }
12451
12452 return row_found;
12453 }
12454
12455
12456 /* Find the first glyph row in the current matrix of W that is not
12457 affected by changes at the end of current_buffer since the
12458 time W's current matrix was built.
12459
12460 Return in *DELTA the number of chars by which buffer positions in
12461 unchanged text at the end of current_buffer must be adjusted.
12462
12463 Return in *DELTA_BYTES the corresponding number of bytes.
12464
12465 Value is null if no such row exists, i.e. all rows are affected by
12466 changes. */
12467
12468 static struct glyph_row *
12469 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12470 struct window *w;
12471 int *delta, *delta_bytes;
12472 {
12473 struct glyph_row *row;
12474 struct glyph_row *row_found = NULL;
12475
12476 *delta = *delta_bytes = 0;
12477
12478 /* Display must not have been paused, otherwise the current matrix
12479 is not up to date. */
12480 if (NILP (w->window_end_valid))
12481 abort ();
12482
12483 /* A value of window_end_pos >= END_UNCHANGED means that the window
12484 end is in the range of changed text. If so, there is no
12485 unchanged row at the end of W's current matrix. */
12486 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12487 return NULL;
12488
12489 /* Set row to the last row in W's current matrix displaying text. */
12490 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12491
12492 /* If matrix is entirely empty, no unchanged row exists. */
12493 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12494 {
12495 /* The value of row is the last glyph row in the matrix having a
12496 meaningful buffer position in it. The end position of row
12497 corresponds to window_end_pos. This allows us to translate
12498 buffer positions in the current matrix to current buffer
12499 positions for characters not in changed text. */
12500 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12501 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12502 int last_unchanged_pos, last_unchanged_pos_old;
12503 struct glyph_row *first_text_row
12504 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12505
12506 *delta = Z - Z_old;
12507 *delta_bytes = Z_BYTE - Z_BYTE_old;
12508
12509 /* Set last_unchanged_pos to the buffer position of the last
12510 character in the buffer that has not been changed. Z is the
12511 index + 1 of the last character in current_buffer, i.e. by
12512 subtracting END_UNCHANGED we get the index of the last
12513 unchanged character, and we have to add BEG to get its buffer
12514 position. */
12515 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12516 last_unchanged_pos_old = last_unchanged_pos - *delta;
12517
12518 /* Search backward from ROW for a row displaying a line that
12519 starts at a minimum position >= last_unchanged_pos_old. */
12520 for (; row > first_text_row; --row)
12521 {
12522 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12523 abort ();
12524
12525 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12526 row_found = row;
12527 }
12528 }
12529
12530 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12531 abort ();
12532
12533 return row_found;
12534 }
12535
12536
12537 /* Make sure that glyph rows in the current matrix of window W
12538 reference the same glyph memory as corresponding rows in the
12539 frame's frame matrix. This function is called after scrolling W's
12540 current matrix on a terminal frame in try_window_id and
12541 try_window_reusing_current_matrix. */
12542
12543 static void
12544 sync_frame_with_window_matrix_rows (w)
12545 struct window *w;
12546 {
12547 struct frame *f = XFRAME (w->frame);
12548 struct glyph_row *window_row, *window_row_end, *frame_row;
12549
12550 /* Preconditions: W must be a leaf window and full-width. Its frame
12551 must have a frame matrix. */
12552 xassert (NILP (w->hchild) && NILP (w->vchild));
12553 xassert (WINDOW_FULL_WIDTH_P (w));
12554 xassert (!FRAME_WINDOW_P (f));
12555
12556 /* If W is a full-width window, glyph pointers in W's current matrix
12557 have, by definition, to be the same as glyph pointers in the
12558 corresponding frame matrix. Note that frame matrices have no
12559 marginal areas (see build_frame_matrix). */
12560 window_row = w->current_matrix->rows;
12561 window_row_end = window_row + w->current_matrix->nrows;
12562 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12563 while (window_row < window_row_end)
12564 {
12565 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12566 struct glyph *end = window_row->glyphs[LAST_AREA];
12567
12568 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12569 frame_row->glyphs[TEXT_AREA] = start;
12570 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12571 frame_row->glyphs[LAST_AREA] = end;
12572
12573 /* Disable frame rows whose corresponding window rows have
12574 been disabled in try_window_id. */
12575 if (!window_row->enabled_p)
12576 frame_row->enabled_p = 0;
12577
12578 ++window_row, ++frame_row;
12579 }
12580 }
12581
12582
12583 /* Find the glyph row in window W containing CHARPOS. Consider all
12584 rows between START and END (not inclusive). END null means search
12585 all rows to the end of the display area of W. Value is the row
12586 containing CHARPOS or null. */
12587
12588 struct glyph_row *
12589 row_containing_pos (w, charpos, start, end, dy)
12590 struct window *w;
12591 int charpos;
12592 struct glyph_row *start, *end;
12593 int dy;
12594 {
12595 struct glyph_row *row = start;
12596 int last_y;
12597
12598 /* If we happen to start on a header-line, skip that. */
12599 if (row->mode_line_p)
12600 ++row;
12601
12602 if ((end && row >= end) || !row->enabled_p)
12603 return NULL;
12604
12605 last_y = window_text_bottom_y (w) - dy;
12606
12607 while (1)
12608 {
12609 /* Give up if we have gone too far. */
12610 if (end && row >= end)
12611 return NULL;
12612 /* This formerly returned if they were equal.
12613 I think that both quantities are of a "last plus one" type;
12614 if so, when they are equal, the row is within the screen. -- rms. */
12615 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12616 return NULL;
12617
12618 /* If it is in this row, return this row. */
12619 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12620 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12621 /* The end position of a row equals the start
12622 position of the next row. If CHARPOS is there, we
12623 would rather display it in the next line, except
12624 when this line ends in ZV. */
12625 && !row->ends_at_zv_p
12626 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12627 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12628 return row;
12629 ++row;
12630 }
12631 }
12632
12633
12634 /* Try to redisplay window W by reusing its existing display. W's
12635 current matrix must be up to date when this function is called,
12636 i.e. window_end_valid must not be nil.
12637
12638 Value is
12639
12640 1 if display has been updated
12641 0 if otherwise unsuccessful
12642 -1 if redisplay with same window start is known not to succeed
12643
12644 The following steps are performed:
12645
12646 1. Find the last row in the current matrix of W that is not
12647 affected by changes at the start of current_buffer. If no such row
12648 is found, give up.
12649
12650 2. Find the first row in W's current matrix that is not affected by
12651 changes at the end of current_buffer. Maybe there is no such row.
12652
12653 3. Display lines beginning with the row + 1 found in step 1 to the
12654 row found in step 2 or, if step 2 didn't find a row, to the end of
12655 the window.
12656
12657 4. If cursor is not known to appear on the window, give up.
12658
12659 5. If display stopped at the row found in step 2, scroll the
12660 display and current matrix as needed.
12661
12662 6. Maybe display some lines at the end of W, if we must. This can
12663 happen under various circumstances, like a partially visible line
12664 becoming fully visible, or because newly displayed lines are displayed
12665 in smaller font sizes.
12666
12667 7. Update W's window end information. */
12668
12669 static int
12670 try_window_id (w)
12671 struct window *w;
12672 {
12673 struct frame *f = XFRAME (w->frame);
12674 struct glyph_matrix *current_matrix = w->current_matrix;
12675 struct glyph_matrix *desired_matrix = w->desired_matrix;
12676 struct glyph_row *last_unchanged_at_beg_row;
12677 struct glyph_row *first_unchanged_at_end_row;
12678 struct glyph_row *row;
12679 struct glyph_row *bottom_row;
12680 int bottom_vpos;
12681 struct it it;
12682 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12683 struct text_pos start_pos;
12684 struct run run;
12685 int first_unchanged_at_end_vpos = 0;
12686 struct glyph_row *last_text_row, *last_text_row_at_end;
12687 struct text_pos start;
12688 int first_changed_charpos, last_changed_charpos;
12689
12690 #if GLYPH_DEBUG
12691 if (inhibit_try_window_id)
12692 return 0;
12693 #endif
12694
12695 /* This is handy for debugging. */
12696 #if 0
12697 #define GIVE_UP(X) \
12698 do { \
12699 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12700 return 0; \
12701 } while (0)
12702 #else
12703 #define GIVE_UP(X) return 0
12704 #endif
12705
12706 SET_TEXT_POS_FROM_MARKER (start, w->start);
12707
12708 /* Don't use this for mini-windows because these can show
12709 messages and mini-buffers, and we don't handle that here. */
12710 if (MINI_WINDOW_P (w))
12711 GIVE_UP (1);
12712
12713 /* This flag is used to prevent redisplay optimizations. */
12714 if (windows_or_buffers_changed || cursor_type_changed)
12715 GIVE_UP (2);
12716
12717 /* Verify that narrowing has not changed.
12718 Also verify that we were not told to prevent redisplay optimizations.
12719 It would be nice to further
12720 reduce the number of cases where this prevents try_window_id. */
12721 if (current_buffer->clip_changed
12722 || current_buffer->prevent_redisplay_optimizations_p)
12723 GIVE_UP (3);
12724
12725 /* Window must either use window-based redisplay or be full width. */
12726 if (!FRAME_WINDOW_P (f)
12727 && (!FRAME_LINE_INS_DEL_OK (f)
12728 || !WINDOW_FULL_WIDTH_P (w)))
12729 GIVE_UP (4);
12730
12731 /* Give up if point is not known NOT to appear in W. */
12732 if (PT < CHARPOS (start))
12733 GIVE_UP (5);
12734
12735 /* Another way to prevent redisplay optimizations. */
12736 if (XFASTINT (w->last_modified) == 0)
12737 GIVE_UP (6);
12738
12739 /* Verify that window is not hscrolled. */
12740 if (XFASTINT (w->hscroll) != 0)
12741 GIVE_UP (7);
12742
12743 /* Verify that display wasn't paused. */
12744 if (NILP (w->window_end_valid))
12745 GIVE_UP (8);
12746
12747 /* Can't use this if highlighting a region because a cursor movement
12748 will do more than just set the cursor. */
12749 if (!NILP (Vtransient_mark_mode)
12750 && !NILP (current_buffer->mark_active))
12751 GIVE_UP (9);
12752
12753 /* Likewise if highlighting trailing whitespace. */
12754 if (!NILP (Vshow_trailing_whitespace))
12755 GIVE_UP (11);
12756
12757 /* Likewise if showing a region. */
12758 if (!NILP (w->region_showing))
12759 GIVE_UP (10);
12760
12761 /* Can use this if overlay arrow position and or string have changed. */
12762 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
12763 || !EQ (last_arrow_string, Voverlay_arrow_string))
12764 GIVE_UP (12);
12765
12766
12767 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12768 only if buffer has really changed. The reason is that the gap is
12769 initially at Z for freshly visited files. The code below would
12770 set end_unchanged to 0 in that case. */
12771 if (MODIFF > SAVE_MODIFF
12772 /* This seems to happen sometimes after saving a buffer. */
12773 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12774 {
12775 if (GPT - BEG < BEG_UNCHANGED)
12776 BEG_UNCHANGED = GPT - BEG;
12777 if (Z - GPT < END_UNCHANGED)
12778 END_UNCHANGED = Z - GPT;
12779 }
12780
12781 /* The position of the first and last character that has been changed. */
12782 first_changed_charpos = BEG + BEG_UNCHANGED;
12783 last_changed_charpos = Z - END_UNCHANGED;
12784
12785 /* If window starts after a line end, and the last change is in
12786 front of that newline, then changes don't affect the display.
12787 This case happens with stealth-fontification. Note that although
12788 the display is unchanged, glyph positions in the matrix have to
12789 be adjusted, of course. */
12790 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12791 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12792 && ((last_changed_charpos < CHARPOS (start)
12793 && CHARPOS (start) == BEGV)
12794 || (last_changed_charpos < CHARPOS (start) - 1
12795 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12796 {
12797 int Z_old, delta, Z_BYTE_old, delta_bytes;
12798 struct glyph_row *r0;
12799
12800 /* Compute how many chars/bytes have been added to or removed
12801 from the buffer. */
12802 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12803 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12804 delta = Z - Z_old;
12805 delta_bytes = Z_BYTE - Z_BYTE_old;
12806
12807 /* Give up if PT is not in the window. Note that it already has
12808 been checked at the start of try_window_id that PT is not in
12809 front of the window start. */
12810 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12811 GIVE_UP (13);
12812
12813 /* If window start is unchanged, we can reuse the whole matrix
12814 as is, after adjusting glyph positions. No need to compute
12815 the window end again, since its offset from Z hasn't changed. */
12816 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12817 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12818 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
12819 /* PT must not be in a partially visible line. */
12820 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
12821 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12822 {
12823 /* Adjust positions in the glyph matrix. */
12824 if (delta || delta_bytes)
12825 {
12826 struct glyph_row *r1
12827 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
12828 increment_matrix_positions (w->current_matrix,
12829 MATRIX_ROW_VPOS (r0, current_matrix),
12830 MATRIX_ROW_VPOS (r1, current_matrix),
12831 delta, delta_bytes);
12832 }
12833
12834 /* Set the cursor. */
12835 row = row_containing_pos (w, PT, r0, NULL, 0);
12836 if (row)
12837 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12838 else
12839 abort ();
12840 return 1;
12841 }
12842 }
12843
12844 /* Handle the case that changes are all below what is displayed in
12845 the window, and that PT is in the window. This shortcut cannot
12846 be taken if ZV is visible in the window, and text has been added
12847 there that is visible in the window. */
12848 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
12849 /* ZV is not visible in the window, or there are no
12850 changes at ZV, actually. */
12851 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
12852 || first_changed_charpos == last_changed_charpos))
12853 {
12854 struct glyph_row *r0;
12855
12856 /* Give up if PT is not in the window. Note that it already has
12857 been checked at the start of try_window_id that PT is not in
12858 front of the window start. */
12859 if (PT >= MATRIX_ROW_END_CHARPOS (row))
12860 GIVE_UP (14);
12861
12862 /* If window start is unchanged, we can reuse the whole matrix
12863 as is, without changing glyph positions since no text has
12864 been added/removed in front of the window end. */
12865 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12866 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
12867 /* PT must not be in a partially visible line. */
12868 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
12869 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12870 {
12871 /* We have to compute the window end anew since text
12872 can have been added/removed after it. */
12873 w->window_end_pos
12874 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
12875 w->window_end_bytepos
12876 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
12877
12878 /* Set the cursor. */
12879 row = row_containing_pos (w, PT, r0, NULL, 0);
12880 if (row)
12881 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12882 else
12883 abort ();
12884 return 2;
12885 }
12886 }
12887
12888 /* Give up if window start is in the changed area.
12889
12890 The condition used to read
12891
12892 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
12893
12894 but why that was tested escapes me at the moment. */
12895 if (CHARPOS (start) >= first_changed_charpos
12896 && CHARPOS (start) <= last_changed_charpos)
12897 GIVE_UP (15);
12898
12899 /* Check that window start agrees with the start of the first glyph
12900 row in its current matrix. Check this after we know the window
12901 start is not in changed text, otherwise positions would not be
12902 comparable. */
12903 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
12904 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
12905 GIVE_UP (16);
12906
12907 /* Give up if the window ends in strings. Overlay strings
12908 at the end are difficult to handle, so don't try. */
12909 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
12910 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
12911 GIVE_UP (20);
12912
12913 /* Compute the position at which we have to start displaying new
12914 lines. Some of the lines at the top of the window might be
12915 reusable because they are not displaying changed text. Find the
12916 last row in W's current matrix not affected by changes at the
12917 start of current_buffer. Value is null if changes start in the
12918 first line of window. */
12919 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
12920 if (last_unchanged_at_beg_row)
12921 {
12922 /* Avoid starting to display in the moddle of a character, a TAB
12923 for instance. This is easier than to set up the iterator
12924 exactly, and it's not a frequent case, so the additional
12925 effort wouldn't really pay off. */
12926 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
12927 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
12928 && last_unchanged_at_beg_row > w->current_matrix->rows)
12929 --last_unchanged_at_beg_row;
12930
12931 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
12932 GIVE_UP (17);
12933
12934 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
12935 GIVE_UP (18);
12936 start_pos = it.current.pos;
12937
12938 /* Start displaying new lines in the desired matrix at the same
12939 vpos we would use in the current matrix, i.e. below
12940 last_unchanged_at_beg_row. */
12941 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
12942 current_matrix);
12943 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
12944 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
12945
12946 xassert (it.hpos == 0 && it.current_x == 0);
12947 }
12948 else
12949 {
12950 /* There are no reusable lines at the start of the window.
12951 Start displaying in the first text line. */
12952 start_display (&it, w, start);
12953 it.vpos = it.first_vpos;
12954 start_pos = it.current.pos;
12955 }
12956
12957 /* Find the first row that is not affected by changes at the end of
12958 the buffer. Value will be null if there is no unchanged row, in
12959 which case we must redisplay to the end of the window. delta
12960 will be set to the value by which buffer positions beginning with
12961 first_unchanged_at_end_row have to be adjusted due to text
12962 changes. */
12963 first_unchanged_at_end_row
12964 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
12965 IF_DEBUG (debug_delta = delta);
12966 IF_DEBUG (debug_delta_bytes = delta_bytes);
12967
12968 /* Set stop_pos to the buffer position up to which we will have to
12969 display new lines. If first_unchanged_at_end_row != NULL, this
12970 is the buffer position of the start of the line displayed in that
12971 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
12972 that we don't stop at a buffer position. */
12973 stop_pos = 0;
12974 if (first_unchanged_at_end_row)
12975 {
12976 xassert (last_unchanged_at_beg_row == NULL
12977 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
12978
12979 /* If this is a continuation line, move forward to the next one
12980 that isn't. Changes in lines above affect this line.
12981 Caution: this may move first_unchanged_at_end_row to a row
12982 not displaying text. */
12983 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
12984 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
12985 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
12986 < it.last_visible_y))
12987 ++first_unchanged_at_end_row;
12988
12989 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
12990 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
12991 >= it.last_visible_y))
12992 first_unchanged_at_end_row = NULL;
12993 else
12994 {
12995 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
12996 + delta);
12997 first_unchanged_at_end_vpos
12998 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
12999 xassert (stop_pos >= Z - END_UNCHANGED);
13000 }
13001 }
13002 else if (last_unchanged_at_beg_row == NULL)
13003 GIVE_UP (19);
13004
13005
13006 #if GLYPH_DEBUG
13007
13008 /* Either there is no unchanged row at the end, or the one we have
13009 now displays text. This is a necessary condition for the window
13010 end pos calculation at the end of this function. */
13011 xassert (first_unchanged_at_end_row == NULL
13012 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13013
13014 debug_last_unchanged_at_beg_vpos
13015 = (last_unchanged_at_beg_row
13016 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13017 : -1);
13018 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13019
13020 #endif /* GLYPH_DEBUG != 0 */
13021
13022
13023 /* Display new lines. Set last_text_row to the last new line
13024 displayed which has text on it, i.e. might end up as being the
13025 line where the window_end_vpos is. */
13026 w->cursor.vpos = -1;
13027 last_text_row = NULL;
13028 overlay_arrow_seen = 0;
13029 while (it.current_y < it.last_visible_y
13030 && !fonts_changed_p
13031 && (first_unchanged_at_end_row == NULL
13032 || IT_CHARPOS (it) < stop_pos))
13033 {
13034 if (display_line (&it))
13035 last_text_row = it.glyph_row - 1;
13036 }
13037
13038 if (fonts_changed_p)
13039 return -1;
13040
13041
13042 /* Compute differences in buffer positions, y-positions etc. for
13043 lines reused at the bottom of the window. Compute what we can
13044 scroll. */
13045 if (first_unchanged_at_end_row
13046 /* No lines reused because we displayed everything up to the
13047 bottom of the window. */
13048 && it.current_y < it.last_visible_y)
13049 {
13050 dvpos = (it.vpos
13051 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13052 current_matrix));
13053 dy = it.current_y - first_unchanged_at_end_row->y;
13054 run.current_y = first_unchanged_at_end_row->y;
13055 run.desired_y = run.current_y + dy;
13056 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13057 }
13058 else
13059 {
13060 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13061 first_unchanged_at_end_row = NULL;
13062 }
13063 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13064
13065
13066 /* Find the cursor if not already found. We have to decide whether
13067 PT will appear on this window (it sometimes doesn't, but this is
13068 not a very frequent case.) This decision has to be made before
13069 the current matrix is altered. A value of cursor.vpos < 0 means
13070 that PT is either in one of the lines beginning at
13071 first_unchanged_at_end_row or below the window. Don't care for
13072 lines that might be displayed later at the window end; as
13073 mentioned, this is not a frequent case. */
13074 if (w->cursor.vpos < 0)
13075 {
13076 /* Cursor in unchanged rows at the top? */
13077 if (PT < CHARPOS (start_pos)
13078 && last_unchanged_at_beg_row)
13079 {
13080 row = row_containing_pos (w, PT,
13081 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13082 last_unchanged_at_beg_row + 1, 0);
13083 if (row)
13084 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13085 }
13086
13087 /* Start from first_unchanged_at_end_row looking for PT. */
13088 else if (first_unchanged_at_end_row)
13089 {
13090 row = row_containing_pos (w, PT - delta,
13091 first_unchanged_at_end_row, NULL, 0);
13092 if (row)
13093 set_cursor_from_row (w, row, w->current_matrix, delta,
13094 delta_bytes, dy, dvpos);
13095 }
13096
13097 /* Give up if cursor was not found. */
13098 if (w->cursor.vpos < 0)
13099 {
13100 clear_glyph_matrix (w->desired_matrix);
13101 return -1;
13102 }
13103 }
13104
13105 /* Don't let the cursor end in the scroll margins. */
13106 {
13107 int this_scroll_margin, cursor_height;
13108
13109 this_scroll_margin = max (0, scroll_margin);
13110 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13111 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13112 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13113
13114 if ((w->cursor.y < this_scroll_margin
13115 && CHARPOS (start) > BEGV)
13116 /* Don't take scroll margin into account at the bottom because
13117 old redisplay didn't do it either. */
13118 || w->cursor.y + cursor_height > it.last_visible_y)
13119 {
13120 w->cursor.vpos = -1;
13121 clear_glyph_matrix (w->desired_matrix);
13122 return -1;
13123 }
13124 }
13125
13126 /* Scroll the display. Do it before changing the current matrix so
13127 that xterm.c doesn't get confused about where the cursor glyph is
13128 found. */
13129 if (dy && run.height)
13130 {
13131 update_begin (f);
13132
13133 if (FRAME_WINDOW_P (f))
13134 {
13135 FRAME_RIF (f)->update_window_begin_hook (w);
13136 FRAME_RIF (f)->clear_window_mouse_face (w);
13137 FRAME_RIF (f)->scroll_run_hook (w, &run);
13138 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13139 }
13140 else
13141 {
13142 /* Terminal frame. In this case, dvpos gives the number of
13143 lines to scroll by; dvpos < 0 means scroll up. */
13144 int first_unchanged_at_end_vpos
13145 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13146 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13147 int end = (WINDOW_TOP_EDGE_LINE (w)
13148 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13149 + window_internal_height (w));
13150
13151 /* Perform the operation on the screen. */
13152 if (dvpos > 0)
13153 {
13154 /* Scroll last_unchanged_at_beg_row to the end of the
13155 window down dvpos lines. */
13156 set_terminal_window (end);
13157
13158 /* On dumb terminals delete dvpos lines at the end
13159 before inserting dvpos empty lines. */
13160 if (!FRAME_SCROLL_REGION_OK (f))
13161 ins_del_lines (end - dvpos, -dvpos);
13162
13163 /* Insert dvpos empty lines in front of
13164 last_unchanged_at_beg_row. */
13165 ins_del_lines (from, dvpos);
13166 }
13167 else if (dvpos < 0)
13168 {
13169 /* Scroll up last_unchanged_at_beg_vpos to the end of
13170 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13171 set_terminal_window (end);
13172
13173 /* Delete dvpos lines in front of
13174 last_unchanged_at_beg_vpos. ins_del_lines will set
13175 the cursor to the given vpos and emit |dvpos| delete
13176 line sequences. */
13177 ins_del_lines (from + dvpos, dvpos);
13178
13179 /* On a dumb terminal insert dvpos empty lines at the
13180 end. */
13181 if (!FRAME_SCROLL_REGION_OK (f))
13182 ins_del_lines (end + dvpos, -dvpos);
13183 }
13184
13185 set_terminal_window (0);
13186 }
13187
13188 update_end (f);
13189 }
13190
13191 /* Shift reused rows of the current matrix to the right position.
13192 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13193 text. */
13194 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13195 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13196 if (dvpos < 0)
13197 {
13198 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13199 bottom_vpos, dvpos);
13200 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13201 bottom_vpos, 0);
13202 }
13203 else if (dvpos > 0)
13204 {
13205 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13206 bottom_vpos, dvpos);
13207 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13208 first_unchanged_at_end_vpos + dvpos, 0);
13209 }
13210
13211 /* For frame-based redisplay, make sure that current frame and window
13212 matrix are in sync with respect to glyph memory. */
13213 if (!FRAME_WINDOW_P (f))
13214 sync_frame_with_window_matrix_rows (w);
13215
13216 /* Adjust buffer positions in reused rows. */
13217 if (delta)
13218 increment_matrix_positions (current_matrix,
13219 first_unchanged_at_end_vpos + dvpos,
13220 bottom_vpos, delta, delta_bytes);
13221
13222 /* Adjust Y positions. */
13223 if (dy)
13224 shift_glyph_matrix (w, current_matrix,
13225 first_unchanged_at_end_vpos + dvpos,
13226 bottom_vpos, dy);
13227
13228 if (first_unchanged_at_end_row)
13229 first_unchanged_at_end_row += dvpos;
13230
13231 /* If scrolling up, there may be some lines to display at the end of
13232 the window. */
13233 last_text_row_at_end = NULL;
13234 if (dy < 0)
13235 {
13236 /* Scrolling up can leave for example a partially visible line
13237 at the end of the window to be redisplayed. */
13238 /* Set last_row to the glyph row in the current matrix where the
13239 window end line is found. It has been moved up or down in
13240 the matrix by dvpos. */
13241 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13242 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13243
13244 /* If last_row is the window end line, it should display text. */
13245 xassert (last_row->displays_text_p);
13246
13247 /* If window end line was partially visible before, begin
13248 displaying at that line. Otherwise begin displaying with the
13249 line following it. */
13250 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13251 {
13252 init_to_row_start (&it, w, last_row);
13253 it.vpos = last_vpos;
13254 it.current_y = last_row->y;
13255 }
13256 else
13257 {
13258 init_to_row_end (&it, w, last_row);
13259 it.vpos = 1 + last_vpos;
13260 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13261 ++last_row;
13262 }
13263
13264 /* We may start in a continuation line. If so, we have to
13265 get the right continuation_lines_width and current_x. */
13266 it.continuation_lines_width = last_row->continuation_lines_width;
13267 it.hpos = it.current_x = 0;
13268
13269 /* Display the rest of the lines at the window end. */
13270 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13271 while (it.current_y < it.last_visible_y
13272 && !fonts_changed_p)
13273 {
13274 /* Is it always sure that the display agrees with lines in
13275 the current matrix? I don't think so, so we mark rows
13276 displayed invalid in the current matrix by setting their
13277 enabled_p flag to zero. */
13278 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13279 if (display_line (&it))
13280 last_text_row_at_end = it.glyph_row - 1;
13281 }
13282 }
13283
13284 /* Update window_end_pos and window_end_vpos. */
13285 if (first_unchanged_at_end_row
13286 && first_unchanged_at_end_row->y < it.last_visible_y
13287 && !last_text_row_at_end)
13288 {
13289 /* Window end line if one of the preserved rows from the current
13290 matrix. Set row to the last row displaying text in current
13291 matrix starting at first_unchanged_at_end_row, after
13292 scrolling. */
13293 xassert (first_unchanged_at_end_row->displays_text_p);
13294 row = find_last_row_displaying_text (w->current_matrix, &it,
13295 first_unchanged_at_end_row);
13296 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13297
13298 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13299 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13300 w->window_end_vpos
13301 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13302 xassert (w->window_end_bytepos >= 0);
13303 IF_DEBUG (debug_method_add (w, "A"));
13304 }
13305 else if (last_text_row_at_end)
13306 {
13307 w->window_end_pos
13308 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13309 w->window_end_bytepos
13310 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13311 w->window_end_vpos
13312 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13313 xassert (w->window_end_bytepos >= 0);
13314 IF_DEBUG (debug_method_add (w, "B"));
13315 }
13316 else if (last_text_row)
13317 {
13318 /* We have displayed either to the end of the window or at the
13319 end of the window, i.e. the last row with text is to be found
13320 in the desired matrix. */
13321 w->window_end_pos
13322 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13323 w->window_end_bytepos
13324 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13325 w->window_end_vpos
13326 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13327 xassert (w->window_end_bytepos >= 0);
13328 }
13329 else if (first_unchanged_at_end_row == NULL
13330 && last_text_row == NULL
13331 && last_text_row_at_end == NULL)
13332 {
13333 /* Displayed to end of window, but no line containing text was
13334 displayed. Lines were deleted at the end of the window. */
13335 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13336 int vpos = XFASTINT (w->window_end_vpos);
13337 struct glyph_row *current_row = current_matrix->rows + vpos;
13338 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13339
13340 for (row = NULL;
13341 row == NULL && vpos >= first_vpos;
13342 --vpos, --current_row, --desired_row)
13343 {
13344 if (desired_row->enabled_p)
13345 {
13346 if (desired_row->displays_text_p)
13347 row = desired_row;
13348 }
13349 else if (current_row->displays_text_p)
13350 row = current_row;
13351 }
13352
13353 xassert (row != NULL);
13354 w->window_end_vpos = make_number (vpos + 1);
13355 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13356 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13357 xassert (w->window_end_bytepos >= 0);
13358 IF_DEBUG (debug_method_add (w, "C"));
13359 }
13360 else
13361 abort ();
13362
13363 #if 0 /* This leads to problems, for instance when the cursor is
13364 at ZV, and the cursor line displays no text. */
13365 /* Disable rows below what's displayed in the window. This makes
13366 debugging easier. */
13367 enable_glyph_matrix_rows (current_matrix,
13368 XFASTINT (w->window_end_vpos) + 1,
13369 bottom_vpos, 0);
13370 #endif
13371
13372 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13373 debug_end_vpos = XFASTINT (w->window_end_vpos));
13374
13375 /* Record that display has not been completed. */
13376 w->window_end_valid = Qnil;
13377 w->desired_matrix->no_scrolling_p = 1;
13378 return 3;
13379
13380 #undef GIVE_UP
13381 }
13382
13383
13384 \f
13385 /***********************************************************************
13386 More debugging support
13387 ***********************************************************************/
13388
13389 #if GLYPH_DEBUG
13390
13391 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13392 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13393 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13394
13395
13396 /* Dump the contents of glyph matrix MATRIX on stderr.
13397
13398 GLYPHS 0 means don't show glyph contents.
13399 GLYPHS 1 means show glyphs in short form
13400 GLYPHS > 1 means show glyphs in long form. */
13401
13402 void
13403 dump_glyph_matrix (matrix, glyphs)
13404 struct glyph_matrix *matrix;
13405 int glyphs;
13406 {
13407 int i;
13408 for (i = 0; i < matrix->nrows; ++i)
13409 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13410 }
13411
13412
13413 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13414 the glyph row and area where the glyph comes from. */
13415
13416 void
13417 dump_glyph (row, glyph, area)
13418 struct glyph_row *row;
13419 struct glyph *glyph;
13420 int area;
13421 {
13422 if (glyph->type == CHAR_GLYPH)
13423 {
13424 fprintf (stderr,
13425 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13426 glyph - row->glyphs[TEXT_AREA],
13427 'C',
13428 glyph->charpos,
13429 (BUFFERP (glyph->object)
13430 ? 'B'
13431 : (STRINGP (glyph->object)
13432 ? 'S'
13433 : '-')),
13434 glyph->pixel_width,
13435 glyph->u.ch,
13436 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13437 ? glyph->u.ch
13438 : '.'),
13439 glyph->face_id,
13440 glyph->left_box_line_p,
13441 glyph->right_box_line_p);
13442 }
13443 else if (glyph->type == STRETCH_GLYPH)
13444 {
13445 fprintf (stderr,
13446 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13447 glyph - row->glyphs[TEXT_AREA],
13448 'S',
13449 glyph->charpos,
13450 (BUFFERP (glyph->object)
13451 ? 'B'
13452 : (STRINGP (glyph->object)
13453 ? 'S'
13454 : '-')),
13455 glyph->pixel_width,
13456 0,
13457 '.',
13458 glyph->face_id,
13459 glyph->left_box_line_p,
13460 glyph->right_box_line_p);
13461 }
13462 else if (glyph->type == IMAGE_GLYPH)
13463 {
13464 fprintf (stderr,
13465 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13466 glyph - row->glyphs[TEXT_AREA],
13467 'I',
13468 glyph->charpos,
13469 (BUFFERP (glyph->object)
13470 ? 'B'
13471 : (STRINGP (glyph->object)
13472 ? 'S'
13473 : '-')),
13474 glyph->pixel_width,
13475 glyph->u.img_id,
13476 '.',
13477 glyph->face_id,
13478 glyph->left_box_line_p,
13479 glyph->right_box_line_p);
13480 }
13481 }
13482
13483
13484 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13485 GLYPHS 0 means don't show glyph contents.
13486 GLYPHS 1 means show glyphs in short form
13487 GLYPHS > 1 means show glyphs in long form. */
13488
13489 void
13490 dump_glyph_row (row, vpos, glyphs)
13491 struct glyph_row *row;
13492 int vpos, glyphs;
13493 {
13494 if (glyphs != 1)
13495 {
13496 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13497 fprintf (stderr, "=======================================================================\n");
13498
13499 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13500 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13501 vpos,
13502 MATRIX_ROW_START_CHARPOS (row),
13503 MATRIX_ROW_END_CHARPOS (row),
13504 row->used[TEXT_AREA],
13505 row->contains_overlapping_glyphs_p,
13506 row->enabled_p,
13507 row->truncated_on_left_p,
13508 row->truncated_on_right_p,
13509 row->overlay_arrow_p,
13510 row->continued_p,
13511 MATRIX_ROW_CONTINUATION_LINE_P (row),
13512 row->displays_text_p,
13513 row->ends_at_zv_p,
13514 row->fill_line_p,
13515 row->ends_in_middle_of_char_p,
13516 row->starts_in_middle_of_char_p,
13517 row->mouse_face_p,
13518 row->x,
13519 row->y,
13520 row->pixel_width,
13521 row->height,
13522 row->visible_height,
13523 row->ascent,
13524 row->phys_ascent);
13525 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13526 row->end.overlay_string_index,
13527 row->continuation_lines_width);
13528 fprintf (stderr, "%9d %5d\n",
13529 CHARPOS (row->start.string_pos),
13530 CHARPOS (row->end.string_pos));
13531 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13532 row->end.dpvec_index);
13533 }
13534
13535 if (glyphs > 1)
13536 {
13537 int area;
13538
13539 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13540 {
13541 struct glyph *glyph = row->glyphs[area];
13542 struct glyph *glyph_end = glyph + row->used[area];
13543
13544 /* Glyph for a line end in text. */
13545 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13546 ++glyph_end;
13547
13548 if (glyph < glyph_end)
13549 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13550
13551 for (; glyph < glyph_end; ++glyph)
13552 dump_glyph (row, glyph, area);
13553 }
13554 }
13555 else if (glyphs == 1)
13556 {
13557 int area;
13558
13559 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13560 {
13561 char *s = (char *) alloca (row->used[area] + 1);
13562 int i;
13563
13564 for (i = 0; i < row->used[area]; ++i)
13565 {
13566 struct glyph *glyph = row->glyphs[area] + i;
13567 if (glyph->type == CHAR_GLYPH
13568 && glyph->u.ch < 0x80
13569 && glyph->u.ch >= ' ')
13570 s[i] = glyph->u.ch;
13571 else
13572 s[i] = '.';
13573 }
13574
13575 s[i] = '\0';
13576 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13577 }
13578 }
13579 }
13580
13581
13582 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13583 Sdump_glyph_matrix, 0, 1, "p",
13584 doc: /* Dump the current matrix of the selected window to stderr.
13585 Shows contents of glyph row structures. With non-nil
13586 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13587 glyphs in short form, otherwise show glyphs in long form. */)
13588 (glyphs)
13589 Lisp_Object glyphs;
13590 {
13591 struct window *w = XWINDOW (selected_window);
13592 struct buffer *buffer = XBUFFER (w->buffer);
13593
13594 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13595 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13596 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13597 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13598 fprintf (stderr, "=============================================\n");
13599 dump_glyph_matrix (w->current_matrix,
13600 NILP (glyphs) ? 0 : XINT (glyphs));
13601 return Qnil;
13602 }
13603
13604
13605 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13606 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13607 ()
13608 {
13609 struct frame *f = XFRAME (selected_frame);
13610 dump_glyph_matrix (f->current_matrix, 1);
13611 return Qnil;
13612 }
13613
13614
13615 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13616 doc: /* Dump glyph row ROW to stderr.
13617 GLYPH 0 means don't dump glyphs.
13618 GLYPH 1 means dump glyphs in short form.
13619 GLYPH > 1 or omitted means dump glyphs in long form. */)
13620 (row, glyphs)
13621 Lisp_Object row, glyphs;
13622 {
13623 struct glyph_matrix *matrix;
13624 int vpos;
13625
13626 CHECK_NUMBER (row);
13627 matrix = XWINDOW (selected_window)->current_matrix;
13628 vpos = XINT (row);
13629 if (vpos >= 0 && vpos < matrix->nrows)
13630 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13631 vpos,
13632 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13633 return Qnil;
13634 }
13635
13636
13637 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13638 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13639 GLYPH 0 means don't dump glyphs.
13640 GLYPH 1 means dump glyphs in short form.
13641 GLYPH > 1 or omitted means dump glyphs in long form. */)
13642 (row, glyphs)
13643 Lisp_Object row, glyphs;
13644 {
13645 struct frame *sf = SELECTED_FRAME ();
13646 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13647 int vpos;
13648
13649 CHECK_NUMBER (row);
13650 vpos = XINT (row);
13651 if (vpos >= 0 && vpos < m->nrows)
13652 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13653 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13654 return Qnil;
13655 }
13656
13657
13658 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13659 doc: /* Toggle tracing of redisplay.
13660 With ARG, turn tracing on if and only if ARG is positive. */)
13661 (arg)
13662 Lisp_Object arg;
13663 {
13664 if (NILP (arg))
13665 trace_redisplay_p = !trace_redisplay_p;
13666 else
13667 {
13668 arg = Fprefix_numeric_value (arg);
13669 trace_redisplay_p = XINT (arg) > 0;
13670 }
13671
13672 return Qnil;
13673 }
13674
13675
13676 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13677 doc: /* Like `format', but print result to stderr.
13678 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13679 (nargs, args)
13680 int nargs;
13681 Lisp_Object *args;
13682 {
13683 Lisp_Object s = Fformat (nargs, args);
13684 fprintf (stderr, "%s", SDATA (s));
13685 return Qnil;
13686 }
13687
13688 #endif /* GLYPH_DEBUG */
13689
13690
13691 \f
13692 /***********************************************************************
13693 Building Desired Matrix Rows
13694 ***********************************************************************/
13695
13696 /* Return a temporary glyph row holding the glyphs of an overlay
13697 arrow. Only used for non-window-redisplay windows. */
13698
13699 static struct glyph_row *
13700 get_overlay_arrow_glyph_row (w)
13701 struct window *w;
13702 {
13703 struct frame *f = XFRAME (WINDOW_FRAME (w));
13704 struct buffer *buffer = XBUFFER (w->buffer);
13705 struct buffer *old = current_buffer;
13706 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13707 int arrow_len = SCHARS (Voverlay_arrow_string);
13708 const unsigned char *arrow_end = arrow_string + arrow_len;
13709 const unsigned char *p;
13710 struct it it;
13711 int multibyte_p;
13712 int n_glyphs_before;
13713
13714 set_buffer_temp (buffer);
13715 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13716 it.glyph_row->used[TEXT_AREA] = 0;
13717 SET_TEXT_POS (it.position, 0, 0);
13718
13719 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13720 p = arrow_string;
13721 while (p < arrow_end)
13722 {
13723 Lisp_Object face, ilisp;
13724
13725 /* Get the next character. */
13726 if (multibyte_p)
13727 it.c = string_char_and_length (p, arrow_len, &it.len);
13728 else
13729 it.c = *p, it.len = 1;
13730 p += it.len;
13731
13732 /* Get its face. */
13733 ilisp = make_number (p - arrow_string);
13734 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
13735 it.face_id = compute_char_face (f, it.c, face);
13736
13737 /* Compute its width, get its glyphs. */
13738 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13739 SET_TEXT_POS (it.position, -1, -1);
13740 PRODUCE_GLYPHS (&it);
13741
13742 /* If this character doesn't fit any more in the line, we have
13743 to remove some glyphs. */
13744 if (it.current_x > it.last_visible_x)
13745 {
13746 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13747 break;
13748 }
13749 }
13750
13751 set_buffer_temp (old);
13752 return it.glyph_row;
13753 }
13754
13755
13756 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13757 glyphs are only inserted for terminal frames since we can't really
13758 win with truncation glyphs when partially visible glyphs are
13759 involved. Which glyphs to insert is determined by
13760 produce_special_glyphs. */
13761
13762 static void
13763 insert_left_trunc_glyphs (it)
13764 struct it *it;
13765 {
13766 struct it truncate_it;
13767 struct glyph *from, *end, *to, *toend;
13768
13769 xassert (!FRAME_WINDOW_P (it->f));
13770
13771 /* Get the truncation glyphs. */
13772 truncate_it = *it;
13773 truncate_it.current_x = 0;
13774 truncate_it.face_id = DEFAULT_FACE_ID;
13775 truncate_it.glyph_row = &scratch_glyph_row;
13776 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13777 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13778 truncate_it.object = make_number (0);
13779 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13780
13781 /* Overwrite glyphs from IT with truncation glyphs. */
13782 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13783 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13784 to = it->glyph_row->glyphs[TEXT_AREA];
13785 toend = to + it->glyph_row->used[TEXT_AREA];
13786
13787 while (from < end)
13788 *to++ = *from++;
13789
13790 /* There may be padding glyphs left over. Overwrite them too. */
13791 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13792 {
13793 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13794 while (from < end)
13795 *to++ = *from++;
13796 }
13797
13798 if (to > toend)
13799 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13800 }
13801
13802
13803 /* Compute the pixel height and width of IT->glyph_row.
13804
13805 Most of the time, ascent and height of a display line will be equal
13806 to the max_ascent and max_height values of the display iterator
13807 structure. This is not the case if
13808
13809 1. We hit ZV without displaying anything. In this case, max_ascent
13810 and max_height will be zero.
13811
13812 2. We have some glyphs that don't contribute to the line height.
13813 (The glyph row flag contributes_to_line_height_p is for future
13814 pixmap extensions).
13815
13816 The first case is easily covered by using default values because in
13817 these cases, the line height does not really matter, except that it
13818 must not be zero. */
13819
13820 static void
13821 compute_line_metrics (it)
13822 struct it *it;
13823 {
13824 struct glyph_row *row = it->glyph_row;
13825 int area, i;
13826
13827 if (FRAME_WINDOW_P (it->f))
13828 {
13829 int i, min_y, max_y;
13830
13831 /* The line may consist of one space only, that was added to
13832 place the cursor on it. If so, the row's height hasn't been
13833 computed yet. */
13834 if (row->height == 0)
13835 {
13836 if (it->max_ascent + it->max_descent == 0)
13837 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
13838 row->ascent = it->max_ascent;
13839 row->height = it->max_ascent + it->max_descent;
13840 row->phys_ascent = it->max_phys_ascent;
13841 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
13842 }
13843
13844 /* Compute the width of this line. */
13845 row->pixel_width = row->x;
13846 for (i = 0; i < row->used[TEXT_AREA]; ++i)
13847 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
13848
13849 xassert (row->pixel_width >= 0);
13850 xassert (row->ascent >= 0 && row->height > 0);
13851
13852 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
13853 || MATRIX_ROW_OVERLAPS_PRED_P (row));
13854
13855 /* If first line's physical ascent is larger than its logical
13856 ascent, use the physical ascent, and make the row taller.
13857 This makes accented characters fully visible. */
13858 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
13859 && row->phys_ascent > row->ascent)
13860 {
13861 row->height += row->phys_ascent - row->ascent;
13862 row->ascent = row->phys_ascent;
13863 }
13864
13865 /* Compute how much of the line is visible. */
13866 row->visible_height = row->height;
13867
13868 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
13869 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
13870
13871 if (row->y < min_y)
13872 row->visible_height -= min_y - row->y;
13873 if (row->y + row->height > max_y)
13874 row->visible_height -= row->y + row->height - max_y;
13875 }
13876 else
13877 {
13878 row->pixel_width = row->used[TEXT_AREA];
13879 if (row->continued_p)
13880 row->pixel_width -= it->continuation_pixel_width;
13881 else if (row->truncated_on_right_p)
13882 row->pixel_width -= it->truncation_pixel_width;
13883 row->ascent = row->phys_ascent = 0;
13884 row->height = row->phys_height = row->visible_height = 1;
13885 }
13886
13887 /* Compute a hash code for this row. */
13888 row->hash = 0;
13889 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13890 for (i = 0; i < row->used[area]; ++i)
13891 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
13892 + row->glyphs[area][i].u.val
13893 + row->glyphs[area][i].face_id
13894 + row->glyphs[area][i].padding_p
13895 + (row->glyphs[area][i].type << 2));
13896
13897 it->max_ascent = it->max_descent = 0;
13898 it->max_phys_ascent = it->max_phys_descent = 0;
13899 }
13900
13901
13902 /* Append one space to the glyph row of iterator IT if doing a
13903 window-based redisplay. DEFAULT_FACE_P non-zero means let the
13904 space have the default face, otherwise let it have the same face as
13905 IT->face_id. Value is non-zero if a space was added.
13906
13907 This function is called to make sure that there is always one glyph
13908 at the end of a glyph row that the cursor can be set on under
13909 window-systems. (If there weren't such a glyph we would not know
13910 how wide and tall a box cursor should be displayed).
13911
13912 At the same time this space let's a nicely handle clearing to the
13913 end of the line if the row ends in italic text. */
13914
13915 static int
13916 append_space (it, default_face_p)
13917 struct it *it;
13918 int default_face_p;
13919 {
13920 if (FRAME_WINDOW_P (it->f))
13921 {
13922 int n = it->glyph_row->used[TEXT_AREA];
13923
13924 if (it->glyph_row->glyphs[TEXT_AREA] + n
13925 < it->glyph_row->glyphs[1 + TEXT_AREA])
13926 {
13927 /* Save some values that must not be changed.
13928 Must save IT->c and IT->len because otherwise
13929 ITERATOR_AT_END_P wouldn't work anymore after
13930 append_space has been called. */
13931 enum display_element_type saved_what = it->what;
13932 int saved_c = it->c, saved_len = it->len;
13933 int saved_x = it->current_x;
13934 int saved_face_id = it->face_id;
13935 struct text_pos saved_pos;
13936 Lisp_Object saved_object;
13937 struct face *face;
13938
13939 saved_object = it->object;
13940 saved_pos = it->position;
13941
13942 it->what = IT_CHARACTER;
13943 bzero (&it->position, sizeof it->position);
13944 it->object = make_number (0);
13945 it->c = ' ';
13946 it->len = 1;
13947
13948 if (default_face_p)
13949 it->face_id = DEFAULT_FACE_ID;
13950 else if (it->face_before_selective_p)
13951 it->face_id = it->saved_face_id;
13952 face = FACE_FROM_ID (it->f, it->face_id);
13953 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
13954
13955 PRODUCE_GLYPHS (it);
13956
13957 it->current_x = saved_x;
13958 it->object = saved_object;
13959 it->position = saved_pos;
13960 it->what = saved_what;
13961 it->face_id = saved_face_id;
13962 it->len = saved_len;
13963 it->c = saved_c;
13964 return 1;
13965 }
13966 }
13967
13968 return 0;
13969 }
13970
13971
13972 /* Extend the face of the last glyph in the text area of IT->glyph_row
13973 to the end of the display line. Called from display_line.
13974 If the glyph row is empty, add a space glyph to it so that we
13975 know the face to draw. Set the glyph row flag fill_line_p. */
13976
13977 static void
13978 extend_face_to_end_of_line (it)
13979 struct it *it;
13980 {
13981 struct face *face;
13982 struct frame *f = it->f;
13983
13984 /* If line is already filled, do nothing. */
13985 if (it->current_x >= it->last_visible_x)
13986 return;
13987
13988 /* Face extension extends the background and box of IT->face_id
13989 to the end of the line. If the background equals the background
13990 of the frame, we don't have to do anything. */
13991 if (it->face_before_selective_p)
13992 face = FACE_FROM_ID (it->f, it->saved_face_id);
13993 else
13994 face = FACE_FROM_ID (f, it->face_id);
13995
13996 if (FRAME_WINDOW_P (f)
13997 && face->box == FACE_NO_BOX
13998 && face->background == FRAME_BACKGROUND_PIXEL (f)
13999 && !face->stipple)
14000 return;
14001
14002 /* Set the glyph row flag indicating that the face of the last glyph
14003 in the text area has to be drawn to the end of the text area. */
14004 it->glyph_row->fill_line_p = 1;
14005
14006 /* If current character of IT is not ASCII, make sure we have the
14007 ASCII face. This will be automatically undone the next time
14008 get_next_display_element returns a multibyte character. Note
14009 that the character will always be single byte in unibyte text. */
14010 if (!SINGLE_BYTE_CHAR_P (it->c))
14011 {
14012 it->face_id = FACE_FOR_CHAR (f, face, 0);
14013 }
14014
14015 if (FRAME_WINDOW_P (f))
14016 {
14017 /* If the row is empty, add a space with the current face of IT,
14018 so that we know which face to draw. */
14019 if (it->glyph_row->used[TEXT_AREA] == 0)
14020 {
14021 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14022 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14023 it->glyph_row->used[TEXT_AREA] = 1;
14024 }
14025 }
14026 else
14027 {
14028 /* Save some values that must not be changed. */
14029 int saved_x = it->current_x;
14030 struct text_pos saved_pos;
14031 Lisp_Object saved_object;
14032 enum display_element_type saved_what = it->what;
14033 int saved_face_id = it->face_id;
14034
14035 saved_object = it->object;
14036 saved_pos = it->position;
14037
14038 it->what = IT_CHARACTER;
14039 bzero (&it->position, sizeof it->position);
14040 it->object = make_number (0);
14041 it->c = ' ';
14042 it->len = 1;
14043 it->face_id = face->id;
14044
14045 PRODUCE_GLYPHS (it);
14046
14047 while (it->current_x <= it->last_visible_x)
14048 PRODUCE_GLYPHS (it);
14049
14050 /* Don't count these blanks really. It would let us insert a left
14051 truncation glyph below and make us set the cursor on them, maybe. */
14052 it->current_x = saved_x;
14053 it->object = saved_object;
14054 it->position = saved_pos;
14055 it->what = saved_what;
14056 it->face_id = saved_face_id;
14057 }
14058 }
14059
14060
14061 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14062 trailing whitespace. */
14063
14064 static int
14065 trailing_whitespace_p (charpos)
14066 int charpos;
14067 {
14068 int bytepos = CHAR_TO_BYTE (charpos);
14069 int c = 0;
14070
14071 while (bytepos < ZV_BYTE
14072 && (c = FETCH_CHAR (bytepos),
14073 c == ' ' || c == '\t'))
14074 ++bytepos;
14075
14076 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14077 {
14078 if (bytepos != PT_BYTE)
14079 return 1;
14080 }
14081 return 0;
14082 }
14083
14084
14085 /* Highlight trailing whitespace, if any, in ROW. */
14086
14087 void
14088 highlight_trailing_whitespace (f, row)
14089 struct frame *f;
14090 struct glyph_row *row;
14091 {
14092 int used = row->used[TEXT_AREA];
14093
14094 if (used)
14095 {
14096 struct glyph *start = row->glyphs[TEXT_AREA];
14097 struct glyph *glyph = start + used - 1;
14098
14099 /* Skip over glyphs inserted to display the cursor at the
14100 end of a line, for extending the face of the last glyph
14101 to the end of the line on terminals, and for truncation
14102 and continuation glyphs. */
14103 while (glyph >= start
14104 && glyph->type == CHAR_GLYPH
14105 && INTEGERP (glyph->object))
14106 --glyph;
14107
14108 /* If last glyph is a space or stretch, and it's trailing
14109 whitespace, set the face of all trailing whitespace glyphs in
14110 IT->glyph_row to `trailing-whitespace'. */
14111 if (glyph >= start
14112 && BUFFERP (glyph->object)
14113 && (glyph->type == STRETCH_GLYPH
14114 || (glyph->type == CHAR_GLYPH
14115 && glyph->u.ch == ' '))
14116 && trailing_whitespace_p (glyph->charpos))
14117 {
14118 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14119
14120 while (glyph >= start
14121 && BUFFERP (glyph->object)
14122 && (glyph->type == STRETCH_GLYPH
14123 || (glyph->type == CHAR_GLYPH
14124 && glyph->u.ch == ' ')))
14125 (glyph--)->face_id = face_id;
14126 }
14127 }
14128 }
14129
14130
14131 /* Value is non-zero if glyph row ROW in window W should be
14132 used to hold the cursor. */
14133
14134 static int
14135 cursor_row_p (w, row)
14136 struct window *w;
14137 struct glyph_row *row;
14138 {
14139 int cursor_row_p = 1;
14140
14141 if (PT == MATRIX_ROW_END_CHARPOS (row))
14142 {
14143 /* If the row ends with a newline from a string, we don't want
14144 the cursor there (if the row is continued it doesn't end in a
14145 newline). */
14146 if (CHARPOS (row->end.string_pos) >= 0
14147 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14148 cursor_row_p = row->continued_p;
14149
14150 /* If the row ends at ZV, display the cursor at the end of that
14151 row instead of at the start of the row below. */
14152 else if (row->ends_at_zv_p)
14153 cursor_row_p = 1;
14154 else
14155 cursor_row_p = 0;
14156 }
14157
14158 return cursor_row_p;
14159 }
14160
14161
14162 /* Construct the glyph row IT->glyph_row in the desired matrix of
14163 IT->w from text at the current position of IT. See dispextern.h
14164 for an overview of struct it. Value is non-zero if
14165 IT->glyph_row displays text, as opposed to a line displaying ZV
14166 only. */
14167
14168 static int
14169 display_line (it)
14170 struct it *it;
14171 {
14172 struct glyph_row *row = it->glyph_row;
14173
14174 /* We always start displaying at hpos zero even if hscrolled. */
14175 xassert (it->hpos == 0 && it->current_x == 0);
14176
14177 /* We must not display in a row that's not a text row. */
14178 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14179 < it->w->desired_matrix->nrows);
14180
14181 /* Is IT->w showing the region? */
14182 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14183
14184 /* Clear the result glyph row and enable it. */
14185 prepare_desired_row (row);
14186
14187 row->y = it->current_y;
14188 row->start = it->start;
14189 row->continuation_lines_width = it->continuation_lines_width;
14190 row->displays_text_p = 1;
14191 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14192 it->starts_in_middle_of_char_p = 0;
14193
14194 /* Arrange the overlays nicely for our purposes. Usually, we call
14195 display_line on only one line at a time, in which case this
14196 can't really hurt too much, or we call it on lines which appear
14197 one after another in the buffer, in which case all calls to
14198 recenter_overlay_lists but the first will be pretty cheap. */
14199 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14200
14201 /* Move over display elements that are not visible because we are
14202 hscrolled. This may stop at an x-position < IT->first_visible_x
14203 if the first glyph is partially visible or if we hit a line end. */
14204 if (it->current_x < it->first_visible_x)
14205 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14206 MOVE_TO_POS | MOVE_TO_X);
14207
14208 /* Get the initial row height. This is either the height of the
14209 text hscrolled, if there is any, or zero. */
14210 row->ascent = it->max_ascent;
14211 row->height = it->max_ascent + it->max_descent;
14212 row->phys_ascent = it->max_phys_ascent;
14213 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14214
14215 /* Loop generating characters. The loop is left with IT on the next
14216 character to display. */
14217 while (1)
14218 {
14219 int n_glyphs_before, hpos_before, x_before;
14220 int x, i, nglyphs;
14221 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14222
14223 /* Retrieve the next thing to display. Value is zero if end of
14224 buffer reached. */
14225 if (!get_next_display_element (it))
14226 {
14227 /* Maybe add a space at the end of this line that is used to
14228 display the cursor there under X. Set the charpos of the
14229 first glyph of blank lines not corresponding to any text
14230 to -1. */
14231 #ifdef HAVE_WINDOW_SYSTEM
14232 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14233 row->exact_window_width_line_p = 1;
14234 else
14235 #endif /* HAVE_WINDOW_SYSTEM */
14236 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14237 || row->used[TEXT_AREA] == 0)
14238 {
14239 row->glyphs[TEXT_AREA]->charpos = -1;
14240 row->displays_text_p = 0;
14241
14242 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14243 && (!MINI_WINDOW_P (it->w)
14244 || (minibuf_level && EQ (it->window, minibuf_window))))
14245 row->indicate_empty_line_p = 1;
14246 }
14247
14248 it->continuation_lines_width = 0;
14249 row->ends_at_zv_p = 1;
14250 break;
14251 }
14252
14253 /* Now, get the metrics of what we want to display. This also
14254 generates glyphs in `row' (which is IT->glyph_row). */
14255 n_glyphs_before = row->used[TEXT_AREA];
14256 x = it->current_x;
14257
14258 /* Remember the line height so far in case the next element doesn't
14259 fit on the line. */
14260 if (!it->truncate_lines_p)
14261 {
14262 ascent = it->max_ascent;
14263 descent = it->max_descent;
14264 phys_ascent = it->max_phys_ascent;
14265 phys_descent = it->max_phys_descent;
14266 }
14267
14268 PRODUCE_GLYPHS (it);
14269
14270 /* If this display element was in marginal areas, continue with
14271 the next one. */
14272 if (it->area != TEXT_AREA)
14273 {
14274 row->ascent = max (row->ascent, it->max_ascent);
14275 row->height = max (row->height, it->max_ascent + it->max_descent);
14276 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14277 row->phys_height = max (row->phys_height,
14278 it->max_phys_ascent + it->max_phys_descent);
14279 set_iterator_to_next (it, 1);
14280 continue;
14281 }
14282
14283 /* Does the display element fit on the line? If we truncate
14284 lines, we should draw past the right edge of the window. If
14285 we don't truncate, we want to stop so that we can display the
14286 continuation glyph before the right margin. If lines are
14287 continued, there are two possible strategies for characters
14288 resulting in more than 1 glyph (e.g. tabs): Display as many
14289 glyphs as possible in this line and leave the rest for the
14290 continuation line, or display the whole element in the next
14291 line. Original redisplay did the former, so we do it also. */
14292 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14293 hpos_before = it->hpos;
14294 x_before = x;
14295
14296 if (/* Not a newline. */
14297 nglyphs > 0
14298 /* Glyphs produced fit entirely in the line. */
14299 && it->current_x < it->last_visible_x)
14300 {
14301 it->hpos += nglyphs;
14302 row->ascent = max (row->ascent, it->max_ascent);
14303 row->height = max (row->height, it->max_ascent + it->max_descent);
14304 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14305 row->phys_height = max (row->phys_height,
14306 it->max_phys_ascent + it->max_phys_descent);
14307 if (it->current_x - it->pixel_width < it->first_visible_x)
14308 row->x = x - it->first_visible_x;
14309 }
14310 else
14311 {
14312 int new_x;
14313 struct glyph *glyph;
14314
14315 for (i = 0; i < nglyphs; ++i, x = new_x)
14316 {
14317 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14318 new_x = x + glyph->pixel_width;
14319
14320 if (/* Lines are continued. */
14321 !it->truncate_lines_p
14322 && (/* Glyph doesn't fit on the line. */
14323 new_x > it->last_visible_x
14324 /* Or it fits exactly on a window system frame. */
14325 || (new_x == it->last_visible_x
14326 && FRAME_WINDOW_P (it->f))))
14327 {
14328 /* End of a continued line. */
14329
14330 if (it->hpos == 0
14331 || (new_x == it->last_visible_x
14332 && FRAME_WINDOW_P (it->f)))
14333 {
14334 /* Current glyph is the only one on the line or
14335 fits exactly on the line. We must continue
14336 the line because we can't draw the cursor
14337 after the glyph. */
14338 row->continued_p = 1;
14339 it->current_x = new_x;
14340 it->continuation_lines_width += new_x;
14341 ++it->hpos;
14342 if (i == nglyphs - 1)
14343 {
14344 set_iterator_to_next (it, 1);
14345 #ifdef HAVE_WINDOW_SYSTEM
14346 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14347 {
14348 if (!get_next_display_element (it))
14349 {
14350 row->exact_window_width_line_p = 1;
14351 it->continuation_lines_width = 0;
14352 row->continued_p = 0;
14353 row->ends_at_zv_p = 1;
14354 }
14355 else if (ITERATOR_AT_END_OF_LINE_P (it))
14356 {
14357 row->continued_p = 0;
14358 row->exact_window_width_line_p = 1;
14359 }
14360 }
14361 #endif /* HAVE_WINDOW_SYSTEM */
14362 }
14363 }
14364 else if (CHAR_GLYPH_PADDING_P (*glyph)
14365 && !FRAME_WINDOW_P (it->f))
14366 {
14367 /* A padding glyph that doesn't fit on this line.
14368 This means the whole character doesn't fit
14369 on the line. */
14370 row->used[TEXT_AREA] = n_glyphs_before;
14371
14372 /* Fill the rest of the row with continuation
14373 glyphs like in 20.x. */
14374 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14375 < row->glyphs[1 + TEXT_AREA])
14376 produce_special_glyphs (it, IT_CONTINUATION);
14377
14378 row->continued_p = 1;
14379 it->current_x = x_before;
14380 it->continuation_lines_width += x_before;
14381
14382 /* Restore the height to what it was before the
14383 element not fitting on the line. */
14384 it->max_ascent = ascent;
14385 it->max_descent = descent;
14386 it->max_phys_ascent = phys_ascent;
14387 it->max_phys_descent = phys_descent;
14388 }
14389 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14390 {
14391 /* A TAB that extends past the right edge of the
14392 window. This produces a single glyph on
14393 window system frames. We leave the glyph in
14394 this row and let it fill the row, but don't
14395 consume the TAB. */
14396 it->continuation_lines_width += it->last_visible_x;
14397 row->ends_in_middle_of_char_p = 1;
14398 row->continued_p = 1;
14399 glyph->pixel_width = it->last_visible_x - x;
14400 it->starts_in_middle_of_char_p = 1;
14401 }
14402 else
14403 {
14404 /* Something other than a TAB that draws past
14405 the right edge of the window. Restore
14406 positions to values before the element. */
14407 row->used[TEXT_AREA] = n_glyphs_before + i;
14408
14409 /* Display continuation glyphs. */
14410 if (!FRAME_WINDOW_P (it->f))
14411 produce_special_glyphs (it, IT_CONTINUATION);
14412 row->continued_p = 1;
14413
14414 it->continuation_lines_width += x;
14415
14416 if (nglyphs > 1 && i > 0)
14417 {
14418 row->ends_in_middle_of_char_p = 1;
14419 it->starts_in_middle_of_char_p = 1;
14420 }
14421
14422 /* Restore the height to what it was before the
14423 element not fitting on the line. */
14424 it->max_ascent = ascent;
14425 it->max_descent = descent;
14426 it->max_phys_ascent = phys_ascent;
14427 it->max_phys_descent = phys_descent;
14428 }
14429
14430 break;
14431 }
14432 else if (new_x > it->first_visible_x)
14433 {
14434 /* Increment number of glyphs actually displayed. */
14435 ++it->hpos;
14436
14437 if (x < it->first_visible_x)
14438 /* Glyph is partially visible, i.e. row starts at
14439 negative X position. */
14440 row->x = x - it->first_visible_x;
14441 }
14442 else
14443 {
14444 /* Glyph is completely off the left margin of the
14445 window. This should not happen because of the
14446 move_it_in_display_line at the start of this
14447 function, unless the text display area of the
14448 window is empty. */
14449 xassert (it->first_visible_x <= it->last_visible_x);
14450 }
14451 }
14452
14453 row->ascent = max (row->ascent, it->max_ascent);
14454 row->height = max (row->height, it->max_ascent + it->max_descent);
14455 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14456 row->phys_height = max (row->phys_height,
14457 it->max_phys_ascent + it->max_phys_descent);
14458
14459 /* End of this display line if row is continued. */
14460 if (row->continued_p || row->ends_at_zv_p)
14461 break;
14462 }
14463
14464 at_end_of_line:
14465 /* Is this a line end? If yes, we're also done, after making
14466 sure that a non-default face is extended up to the right
14467 margin of the window. */
14468 if (ITERATOR_AT_END_OF_LINE_P (it))
14469 {
14470 int used_before = row->used[TEXT_AREA];
14471
14472 row->ends_in_newline_from_string_p = STRINGP (it->object);
14473
14474 #ifdef HAVE_WINDOW_SYSTEM
14475 /* Add a space at the end of the line that is used to
14476 display the cursor there. */
14477 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14478 append_space (it, 0);
14479 #endif /* HAVE_WINDOW_SYSTEM */
14480
14481 /* Extend the face to the end of the line. */
14482 extend_face_to_end_of_line (it);
14483
14484 /* Make sure we have the position. */
14485 if (used_before == 0)
14486 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14487
14488 /* Consume the line end. This skips over invisible lines. */
14489 set_iterator_to_next (it, 1);
14490 it->continuation_lines_width = 0;
14491 break;
14492 }
14493
14494 /* Proceed with next display element. Note that this skips
14495 over lines invisible because of selective display. */
14496 set_iterator_to_next (it, 1);
14497
14498 /* If we truncate lines, we are done when the last displayed
14499 glyphs reach past the right margin of the window. */
14500 if (it->truncate_lines_p
14501 && (FRAME_WINDOW_P (it->f)
14502 ? (it->current_x >= it->last_visible_x)
14503 : (it->current_x > it->last_visible_x)))
14504 {
14505 /* Maybe add truncation glyphs. */
14506 if (!FRAME_WINDOW_P (it->f))
14507 {
14508 int i, n;
14509
14510 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14511 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14512 break;
14513
14514 for (n = row->used[TEXT_AREA]; i < n; ++i)
14515 {
14516 row->used[TEXT_AREA] = i;
14517 produce_special_glyphs (it, IT_TRUNCATION);
14518 }
14519 }
14520 #ifdef HAVE_WINDOW_SYSTEM
14521 else
14522 {
14523 /* Don't truncate if we can overflow newline into fringe. */
14524 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14525 {
14526 if (!get_next_display_element (it))
14527 {
14528 #ifdef HAVE_WINDOW_SYSTEM
14529 it->continuation_lines_width = 0;
14530 row->ends_at_zv_p = 1;
14531 row->exact_window_width_line_p = 1;
14532 break;
14533 #endif /* HAVE_WINDOW_SYSTEM */
14534 }
14535 if (ITERATOR_AT_END_OF_LINE_P (it))
14536 {
14537 row->exact_window_width_line_p = 1;
14538 goto at_end_of_line;
14539 }
14540 }
14541 }
14542 #endif /* HAVE_WINDOW_SYSTEM */
14543
14544 row->truncated_on_right_p = 1;
14545 it->continuation_lines_width = 0;
14546 reseat_at_next_visible_line_start (it, 0);
14547 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14548 it->hpos = hpos_before;
14549 it->current_x = x_before;
14550 break;
14551 }
14552 }
14553
14554 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14555 at the left window margin. */
14556 if (it->first_visible_x
14557 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14558 {
14559 if (!FRAME_WINDOW_P (it->f))
14560 insert_left_trunc_glyphs (it);
14561 row->truncated_on_left_p = 1;
14562 }
14563
14564 /* If the start of this line is the overlay arrow-position, then
14565 mark this glyph row as the one containing the overlay arrow.
14566 This is clearly a mess with variable size fonts. It would be
14567 better to let it be displayed like cursors under X. */
14568 if (MARKERP (Voverlay_arrow_position)
14569 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
14570 && (MATRIX_ROW_START_CHARPOS (row)
14571 == marker_position (Voverlay_arrow_position))
14572 && STRINGP (Voverlay_arrow_string)
14573 && ! overlay_arrow_seen)
14574 {
14575 /* Overlay arrow in window redisplay is a fringe bitmap. */
14576 if (!FRAME_WINDOW_P (it->f))
14577 {
14578 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
14579 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14580 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14581 struct glyph *p = row->glyphs[TEXT_AREA];
14582 struct glyph *p2, *end;
14583
14584 /* Copy the arrow glyphs. */
14585 while (glyph < arrow_end)
14586 *p++ = *glyph++;
14587
14588 /* Throw away padding glyphs. */
14589 p2 = p;
14590 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14591 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14592 ++p2;
14593 if (p2 > p)
14594 {
14595 while (p2 < end)
14596 *p++ = *p2++;
14597 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14598 }
14599 }
14600
14601 overlay_arrow_seen = 1;
14602 row->overlay_arrow_p = 1;
14603 }
14604
14605 /* Compute pixel dimensions of this line. */
14606 compute_line_metrics (it);
14607
14608 /* Remember the position at which this line ends. */
14609 row->end = it->current;
14610
14611 /* Save fringe bitmaps in this row. */
14612 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14613 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14614 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14615 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14616
14617 it->left_user_fringe_bitmap = 0;
14618 it->left_user_fringe_face_id = 0;
14619 it->right_user_fringe_bitmap = 0;
14620 it->right_user_fringe_face_id = 0;
14621
14622 /* Maybe set the cursor. */
14623 if (it->w->cursor.vpos < 0
14624 && PT >= MATRIX_ROW_START_CHARPOS (row)
14625 && PT <= MATRIX_ROW_END_CHARPOS (row)
14626 && cursor_row_p (it->w, row))
14627 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14628
14629 /* Highlight trailing whitespace. */
14630 if (!NILP (Vshow_trailing_whitespace))
14631 highlight_trailing_whitespace (it->f, it->glyph_row);
14632
14633 /* Prepare for the next line. This line starts horizontally at (X
14634 HPOS) = (0 0). Vertical positions are incremented. As a
14635 convenience for the caller, IT->glyph_row is set to the next
14636 row to be used. */
14637 it->current_x = it->hpos = 0;
14638 it->current_y += row->height;
14639 ++it->vpos;
14640 ++it->glyph_row;
14641 it->start = it->current;
14642 return row->displays_text_p;
14643 }
14644
14645
14646 \f
14647 /***********************************************************************
14648 Menu Bar
14649 ***********************************************************************/
14650
14651 /* Redisplay the menu bar in the frame for window W.
14652
14653 The menu bar of X frames that don't have X toolkit support is
14654 displayed in a special window W->frame->menu_bar_window.
14655
14656 The menu bar of terminal frames is treated specially as far as
14657 glyph matrices are concerned. Menu bar lines are not part of
14658 windows, so the update is done directly on the frame matrix rows
14659 for the menu bar. */
14660
14661 static void
14662 display_menu_bar (w)
14663 struct window *w;
14664 {
14665 struct frame *f = XFRAME (WINDOW_FRAME (w));
14666 struct it it;
14667 Lisp_Object items;
14668 int i;
14669
14670 /* Don't do all this for graphical frames. */
14671 #ifdef HAVE_NTGUI
14672 if (!NILP (Vwindow_system))
14673 return;
14674 #endif
14675 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14676 if (FRAME_X_P (f))
14677 return;
14678 #endif
14679 #ifdef MAC_OS
14680 if (FRAME_MAC_P (f))
14681 return;
14682 #endif
14683
14684 #ifdef USE_X_TOOLKIT
14685 xassert (!FRAME_WINDOW_P (f));
14686 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14687 it.first_visible_x = 0;
14688 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14689 #else /* not USE_X_TOOLKIT */
14690 if (FRAME_WINDOW_P (f))
14691 {
14692 /* Menu bar lines are displayed in the desired matrix of the
14693 dummy window menu_bar_window. */
14694 struct window *menu_w;
14695 xassert (WINDOWP (f->menu_bar_window));
14696 menu_w = XWINDOW (f->menu_bar_window);
14697 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14698 MENU_FACE_ID);
14699 it.first_visible_x = 0;
14700 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14701 }
14702 else
14703 {
14704 /* This is a TTY frame, i.e. character hpos/vpos are used as
14705 pixel x/y. */
14706 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14707 MENU_FACE_ID);
14708 it.first_visible_x = 0;
14709 it.last_visible_x = FRAME_COLS (f);
14710 }
14711 #endif /* not USE_X_TOOLKIT */
14712
14713 if (! mode_line_inverse_video)
14714 /* Force the menu-bar to be displayed in the default face. */
14715 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14716
14717 /* Clear all rows of the menu bar. */
14718 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14719 {
14720 struct glyph_row *row = it.glyph_row + i;
14721 clear_glyph_row (row);
14722 row->enabled_p = 1;
14723 row->full_width_p = 1;
14724 }
14725
14726 /* Display all items of the menu bar. */
14727 items = FRAME_MENU_BAR_ITEMS (it.f);
14728 for (i = 0; i < XVECTOR (items)->size; i += 4)
14729 {
14730 Lisp_Object string;
14731
14732 /* Stop at nil string. */
14733 string = AREF (items, i + 1);
14734 if (NILP (string))
14735 break;
14736
14737 /* Remember where item was displayed. */
14738 AREF (items, i + 3) = make_number (it.hpos);
14739
14740 /* Display the item, pad with one space. */
14741 if (it.current_x < it.last_visible_x)
14742 display_string (NULL, string, Qnil, 0, 0, &it,
14743 SCHARS (string) + 1, 0, 0, -1);
14744 }
14745
14746 /* Fill out the line with spaces. */
14747 if (it.current_x < it.last_visible_x)
14748 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14749
14750 /* Compute the total height of the lines. */
14751 compute_line_metrics (&it);
14752 }
14753
14754
14755 \f
14756 /***********************************************************************
14757 Mode Line
14758 ***********************************************************************/
14759
14760 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14761 FORCE is non-zero, redisplay mode lines unconditionally.
14762 Otherwise, redisplay only mode lines that are garbaged. Value is
14763 the number of windows whose mode lines were redisplayed. */
14764
14765 static int
14766 redisplay_mode_lines (window, force)
14767 Lisp_Object window;
14768 int force;
14769 {
14770 int nwindows = 0;
14771
14772 while (!NILP (window))
14773 {
14774 struct window *w = XWINDOW (window);
14775
14776 if (WINDOWP (w->hchild))
14777 nwindows += redisplay_mode_lines (w->hchild, force);
14778 else if (WINDOWP (w->vchild))
14779 nwindows += redisplay_mode_lines (w->vchild, force);
14780 else if (force
14781 || FRAME_GARBAGED_P (XFRAME (w->frame))
14782 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14783 {
14784 struct text_pos lpoint;
14785 struct buffer *old = current_buffer;
14786
14787 /* Set the window's buffer for the mode line display. */
14788 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14789 set_buffer_internal_1 (XBUFFER (w->buffer));
14790
14791 /* Point refers normally to the selected window. For any
14792 other window, set up appropriate value. */
14793 if (!EQ (window, selected_window))
14794 {
14795 struct text_pos pt;
14796
14797 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14798 if (CHARPOS (pt) < BEGV)
14799 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14800 else if (CHARPOS (pt) > (ZV - 1))
14801 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14802 else
14803 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14804 }
14805
14806 /* Display mode lines. */
14807 clear_glyph_matrix (w->desired_matrix);
14808 if (display_mode_lines (w))
14809 {
14810 ++nwindows;
14811 w->must_be_updated_p = 1;
14812 }
14813
14814 /* Restore old settings. */
14815 set_buffer_internal_1 (old);
14816 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14817 }
14818
14819 window = w->next;
14820 }
14821
14822 return nwindows;
14823 }
14824
14825
14826 /* Display the mode and/or top line of window W. Value is the number
14827 of mode lines displayed. */
14828
14829 static int
14830 display_mode_lines (w)
14831 struct window *w;
14832 {
14833 Lisp_Object old_selected_window, old_selected_frame;
14834 int n = 0;
14835
14836 old_selected_frame = selected_frame;
14837 selected_frame = w->frame;
14838 old_selected_window = selected_window;
14839 XSETWINDOW (selected_window, w);
14840
14841 /* These will be set while the mode line specs are processed. */
14842 line_number_displayed = 0;
14843 w->column_number_displayed = Qnil;
14844
14845 if (WINDOW_WANTS_MODELINE_P (w))
14846 {
14847 struct window *sel_w = XWINDOW (old_selected_window);
14848
14849 /* Select mode line face based on the real selected window. */
14850 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
14851 current_buffer->mode_line_format);
14852 ++n;
14853 }
14854
14855 if (WINDOW_WANTS_HEADER_LINE_P (w))
14856 {
14857 display_mode_line (w, HEADER_LINE_FACE_ID,
14858 current_buffer->header_line_format);
14859 ++n;
14860 }
14861
14862 selected_frame = old_selected_frame;
14863 selected_window = old_selected_window;
14864 return n;
14865 }
14866
14867
14868 /* Display mode or top line of window W. FACE_ID specifies which line
14869 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14870 FORMAT is the mode line format to display. Value is the pixel
14871 height of the mode line displayed. */
14872
14873 static int
14874 display_mode_line (w, face_id, format)
14875 struct window *w;
14876 enum face_id face_id;
14877 Lisp_Object format;
14878 {
14879 struct it it;
14880 struct face *face;
14881
14882 init_iterator (&it, w, -1, -1, NULL, face_id);
14883 prepare_desired_row (it.glyph_row);
14884
14885 if (! mode_line_inverse_video)
14886 /* Force the mode-line to be displayed in the default face. */
14887 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14888
14889 /* Temporarily make frame's keyboard the current kboard so that
14890 kboard-local variables in the mode_line_format will get the right
14891 values. */
14892 push_frame_kboard (it.f);
14893 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
14894 pop_frame_kboard ();
14895
14896 /* Fill up with spaces. */
14897 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
14898
14899 compute_line_metrics (&it);
14900 it.glyph_row->full_width_p = 1;
14901 it.glyph_row->mode_line_p = 1;
14902 it.glyph_row->continued_p = 0;
14903 it.glyph_row->truncated_on_left_p = 0;
14904 it.glyph_row->truncated_on_right_p = 0;
14905
14906 /* Make a 3D mode-line have a shadow at its right end. */
14907 face = FACE_FROM_ID (it.f, face_id);
14908 extend_face_to_end_of_line (&it);
14909 if (face->box != FACE_NO_BOX)
14910 {
14911 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
14912 + it.glyph_row->used[TEXT_AREA] - 1);
14913 last->right_box_line_p = 1;
14914 }
14915
14916 return it.glyph_row->height;
14917 }
14918
14919 /* Alist that caches the results of :propertize.
14920 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
14921 Lisp_Object mode_line_proptrans_alist;
14922
14923 /* List of strings making up the mode-line. */
14924 Lisp_Object mode_line_string_list;
14925
14926 /* Base face property when building propertized mode line string. */
14927 static Lisp_Object mode_line_string_face;
14928 static Lisp_Object mode_line_string_face_prop;
14929
14930
14931 /* Contribute ELT to the mode line for window IT->w. How it
14932 translates into text depends on its data type.
14933
14934 IT describes the display environment in which we display, as usual.
14935
14936 DEPTH is the depth in recursion. It is used to prevent
14937 infinite recursion here.
14938
14939 FIELD_WIDTH is the number of characters the display of ELT should
14940 occupy in the mode line, and PRECISION is the maximum number of
14941 characters to display from ELT's representation. See
14942 display_string for details.
14943
14944 Returns the hpos of the end of the text generated by ELT.
14945
14946 PROPS is a property list to add to any string we encounter.
14947
14948 If RISKY is nonzero, remove (disregard) any properties in any string
14949 we encounter, and ignore :eval and :propertize.
14950
14951 If the global variable `frame_title_ptr' is non-NULL, then the output
14952 is passed to `store_frame_title' instead of `display_string'. */
14953
14954 static int
14955 display_mode_element (it, depth, field_width, precision, elt, props, risky)
14956 struct it *it;
14957 int depth;
14958 int field_width, precision;
14959 Lisp_Object elt, props;
14960 int risky;
14961 {
14962 int n = 0, field, prec;
14963 int literal = 0;
14964
14965 tail_recurse:
14966 if (depth > 100)
14967 elt = build_string ("*too-deep*");
14968
14969 depth++;
14970
14971 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
14972 {
14973 case Lisp_String:
14974 {
14975 /* A string: output it and check for %-constructs within it. */
14976 unsigned char c;
14977 const unsigned char *this, *lisp_string;
14978
14979 if (!NILP (props) || risky)
14980 {
14981 Lisp_Object oprops, aelt;
14982 oprops = Ftext_properties_at (make_number (0), elt);
14983
14984 if (NILP (Fequal (props, oprops)) || risky)
14985 {
14986 /* If the starting string has properties,
14987 merge the specified ones onto the existing ones. */
14988 if (! NILP (oprops) && !risky)
14989 {
14990 Lisp_Object tem;
14991
14992 oprops = Fcopy_sequence (oprops);
14993 tem = props;
14994 while (CONSP (tem))
14995 {
14996 oprops = Fplist_put (oprops, XCAR (tem),
14997 XCAR (XCDR (tem)));
14998 tem = XCDR (XCDR (tem));
14999 }
15000 props = oprops;
15001 }
15002
15003 aelt = Fassoc (elt, mode_line_proptrans_alist);
15004 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15005 {
15006 mode_line_proptrans_alist
15007 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15008 elt = XCAR (aelt);
15009 }
15010 else
15011 {
15012 Lisp_Object tem;
15013
15014 elt = Fcopy_sequence (elt);
15015 Fset_text_properties (make_number (0), Flength (elt),
15016 props, elt);
15017 /* Add this item to mode_line_proptrans_alist. */
15018 mode_line_proptrans_alist
15019 = Fcons (Fcons (elt, props),
15020 mode_line_proptrans_alist);
15021 /* Truncate mode_line_proptrans_alist
15022 to at most 50 elements. */
15023 tem = Fnthcdr (make_number (50),
15024 mode_line_proptrans_alist);
15025 if (! NILP (tem))
15026 XSETCDR (tem, Qnil);
15027 }
15028 }
15029 }
15030
15031 this = SDATA (elt);
15032 lisp_string = this;
15033
15034 if (literal)
15035 {
15036 prec = precision - n;
15037 if (frame_title_ptr)
15038 n += store_frame_title (SDATA (elt), -1, prec);
15039 else if (!NILP (mode_line_string_list))
15040 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15041 else
15042 n += display_string (NULL, elt, Qnil, 0, 0, it,
15043 0, prec, 0, STRING_MULTIBYTE (elt));
15044
15045 break;
15046 }
15047
15048 while ((precision <= 0 || n < precision)
15049 && *this
15050 && (frame_title_ptr
15051 || !NILP (mode_line_string_list)
15052 || it->current_x < it->last_visible_x))
15053 {
15054 const unsigned char *last = this;
15055
15056 /* Advance to end of string or next format specifier. */
15057 while ((c = *this++) != '\0' && c != '%')
15058 ;
15059
15060 if (this - 1 != last)
15061 {
15062 /* Output to end of string or up to '%'. Field width
15063 is length of string. Don't output more than
15064 PRECISION allows us. */
15065 --this;
15066
15067 prec = chars_in_text (last, this - last);
15068 if (precision > 0 && prec > precision - n)
15069 prec = precision - n;
15070
15071 if (frame_title_ptr)
15072 n += store_frame_title (last, 0, prec);
15073 else if (!NILP (mode_line_string_list))
15074 {
15075 int bytepos = last - lisp_string;
15076 int charpos = string_byte_to_char (elt, bytepos);
15077 n += store_mode_line_string (NULL,
15078 Fsubstring (elt, make_number (charpos),
15079 make_number (charpos + prec)),
15080 0, 0, 0, Qnil);
15081 }
15082 else
15083 {
15084 int bytepos = last - lisp_string;
15085 int charpos = string_byte_to_char (elt, bytepos);
15086 n += display_string (NULL, elt, Qnil, 0, charpos,
15087 it, 0, prec, 0,
15088 STRING_MULTIBYTE (elt));
15089 }
15090 }
15091 else /* c == '%' */
15092 {
15093 const unsigned char *percent_position = this;
15094
15095 /* Get the specified minimum width. Zero means
15096 don't pad. */
15097 field = 0;
15098 while ((c = *this++) >= '0' && c <= '9')
15099 field = field * 10 + c - '0';
15100
15101 /* Don't pad beyond the total padding allowed. */
15102 if (field_width - n > 0 && field > field_width - n)
15103 field = field_width - n;
15104
15105 /* Note that either PRECISION <= 0 or N < PRECISION. */
15106 prec = precision - n;
15107
15108 if (c == 'M')
15109 n += display_mode_element (it, depth, field, prec,
15110 Vglobal_mode_string, props,
15111 risky);
15112 else if (c != 0)
15113 {
15114 int multibyte;
15115 int bytepos, charpos;
15116 unsigned char *spec;
15117
15118 bytepos = percent_position - lisp_string;
15119 charpos = (STRING_MULTIBYTE (elt)
15120 ? string_byte_to_char (elt, bytepos)
15121 : bytepos);
15122
15123 spec
15124 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15125
15126 if (frame_title_ptr)
15127 n += store_frame_title (spec, field, prec);
15128 else if (!NILP (mode_line_string_list))
15129 {
15130 int len = strlen (spec);
15131 Lisp_Object tem = make_string (spec, len);
15132 props = Ftext_properties_at (make_number (charpos), elt);
15133 /* Should only keep face property in props */
15134 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15135 }
15136 else
15137 {
15138 int nglyphs_before, nwritten;
15139
15140 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15141 nwritten = display_string (spec, Qnil, elt,
15142 charpos, 0, it,
15143 field, prec, 0,
15144 multibyte);
15145
15146 /* Assign to the glyphs written above the
15147 string where the `%x' came from, position
15148 of the `%'. */
15149 if (nwritten > 0)
15150 {
15151 struct glyph *glyph
15152 = (it->glyph_row->glyphs[TEXT_AREA]
15153 + nglyphs_before);
15154 int i;
15155
15156 for (i = 0; i < nwritten; ++i)
15157 {
15158 glyph[i].object = elt;
15159 glyph[i].charpos = charpos;
15160 }
15161
15162 n += nwritten;
15163 }
15164 }
15165 }
15166 else /* c == 0 */
15167 break;
15168 }
15169 }
15170 }
15171 break;
15172
15173 case Lisp_Symbol:
15174 /* A symbol: process the value of the symbol recursively
15175 as if it appeared here directly. Avoid error if symbol void.
15176 Special case: if value of symbol is a string, output the string
15177 literally. */
15178 {
15179 register Lisp_Object tem;
15180
15181 /* If the variable is not marked as risky to set
15182 then its contents are risky to use. */
15183 if (NILP (Fget (elt, Qrisky_local_variable)))
15184 risky = 1;
15185
15186 tem = Fboundp (elt);
15187 if (!NILP (tem))
15188 {
15189 tem = Fsymbol_value (elt);
15190 /* If value is a string, output that string literally:
15191 don't check for % within it. */
15192 if (STRINGP (tem))
15193 literal = 1;
15194
15195 if (!EQ (tem, elt))
15196 {
15197 /* Give up right away for nil or t. */
15198 elt = tem;
15199 goto tail_recurse;
15200 }
15201 }
15202 }
15203 break;
15204
15205 case Lisp_Cons:
15206 {
15207 register Lisp_Object car, tem;
15208
15209 /* A cons cell: five distinct cases.
15210 If first element is :eval or :propertize, do something special.
15211 If first element is a string or a cons, process all the elements
15212 and effectively concatenate them.
15213 If first element is a negative number, truncate displaying cdr to
15214 at most that many characters. If positive, pad (with spaces)
15215 to at least that many characters.
15216 If first element is a symbol, process the cadr or caddr recursively
15217 according to whether the symbol's value is non-nil or nil. */
15218 car = XCAR (elt);
15219 if (EQ (car, QCeval))
15220 {
15221 /* An element of the form (:eval FORM) means evaluate FORM
15222 and use the result as mode line elements. */
15223
15224 if (risky)
15225 break;
15226
15227 if (CONSP (XCDR (elt)))
15228 {
15229 Lisp_Object spec;
15230 spec = safe_eval (XCAR (XCDR (elt)));
15231 n += display_mode_element (it, depth, field_width - n,
15232 precision - n, spec, props,
15233 risky);
15234 }
15235 }
15236 else if (EQ (car, QCpropertize))
15237 {
15238 /* An element of the form (:propertize ELT PROPS...)
15239 means display ELT but applying properties PROPS. */
15240
15241 if (risky)
15242 break;
15243
15244 if (CONSP (XCDR (elt)))
15245 n += display_mode_element (it, depth, field_width - n,
15246 precision - n, XCAR (XCDR (elt)),
15247 XCDR (XCDR (elt)), risky);
15248 }
15249 else if (SYMBOLP (car))
15250 {
15251 tem = Fboundp (car);
15252 elt = XCDR (elt);
15253 if (!CONSP (elt))
15254 goto invalid;
15255 /* elt is now the cdr, and we know it is a cons cell.
15256 Use its car if CAR has a non-nil value. */
15257 if (!NILP (tem))
15258 {
15259 tem = Fsymbol_value (car);
15260 if (!NILP (tem))
15261 {
15262 elt = XCAR (elt);
15263 goto tail_recurse;
15264 }
15265 }
15266 /* Symbol's value is nil (or symbol is unbound)
15267 Get the cddr of the original list
15268 and if possible find the caddr and use that. */
15269 elt = XCDR (elt);
15270 if (NILP (elt))
15271 break;
15272 else if (!CONSP (elt))
15273 goto invalid;
15274 elt = XCAR (elt);
15275 goto tail_recurse;
15276 }
15277 else if (INTEGERP (car))
15278 {
15279 register int lim = XINT (car);
15280 elt = XCDR (elt);
15281 if (lim < 0)
15282 {
15283 /* Negative int means reduce maximum width. */
15284 if (precision <= 0)
15285 precision = -lim;
15286 else
15287 precision = min (precision, -lim);
15288 }
15289 else if (lim > 0)
15290 {
15291 /* Padding specified. Don't let it be more than
15292 current maximum. */
15293 if (precision > 0)
15294 lim = min (precision, lim);
15295
15296 /* If that's more padding than already wanted, queue it.
15297 But don't reduce padding already specified even if
15298 that is beyond the current truncation point. */
15299 field_width = max (lim, field_width);
15300 }
15301 goto tail_recurse;
15302 }
15303 else if (STRINGP (car) || CONSP (car))
15304 {
15305 register int limit = 50;
15306 /* Limit is to protect against circular lists. */
15307 while (CONSP (elt)
15308 && --limit > 0
15309 && (precision <= 0 || n < precision))
15310 {
15311 n += display_mode_element (it, depth, field_width - n,
15312 precision - n, XCAR (elt),
15313 props, risky);
15314 elt = XCDR (elt);
15315 }
15316 }
15317 }
15318 break;
15319
15320 default:
15321 invalid:
15322 elt = build_string ("*invalid*");
15323 goto tail_recurse;
15324 }
15325
15326 /* Pad to FIELD_WIDTH. */
15327 if (field_width > 0 && n < field_width)
15328 {
15329 if (frame_title_ptr)
15330 n += store_frame_title ("", field_width - n, 0);
15331 else if (!NILP (mode_line_string_list))
15332 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15333 else
15334 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15335 0, 0, 0);
15336 }
15337
15338 return n;
15339 }
15340
15341 /* Store a mode-line string element in mode_line_string_list.
15342
15343 If STRING is non-null, display that C string. Otherwise, the Lisp
15344 string LISP_STRING is displayed.
15345
15346 FIELD_WIDTH is the minimum number of output glyphs to produce.
15347 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15348 with spaces. FIELD_WIDTH <= 0 means don't pad.
15349
15350 PRECISION is the maximum number of characters to output from
15351 STRING. PRECISION <= 0 means don't truncate the string.
15352
15353 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15354 properties to the string.
15355
15356 PROPS are the properties to add to the string.
15357 The mode_line_string_face face property is always added to the string.
15358 */
15359
15360 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15361 char *string;
15362 Lisp_Object lisp_string;
15363 int copy_string;
15364 int field_width;
15365 int precision;
15366 Lisp_Object props;
15367 {
15368 int len;
15369 int n = 0;
15370
15371 if (string != NULL)
15372 {
15373 len = strlen (string);
15374 if (precision > 0 && len > precision)
15375 len = precision;
15376 lisp_string = make_string (string, len);
15377 if (NILP (props))
15378 props = mode_line_string_face_prop;
15379 else if (!NILP (mode_line_string_face))
15380 {
15381 Lisp_Object face = Fplist_get (props, Qface);
15382 props = Fcopy_sequence (props);
15383 if (NILP (face))
15384 face = mode_line_string_face;
15385 else
15386 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15387 props = Fplist_put (props, Qface, face);
15388 }
15389 Fadd_text_properties (make_number (0), make_number (len),
15390 props, lisp_string);
15391 }
15392 else
15393 {
15394 len = XFASTINT (Flength (lisp_string));
15395 if (precision > 0 && len > precision)
15396 {
15397 len = precision;
15398 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15399 precision = -1;
15400 }
15401 if (!NILP (mode_line_string_face))
15402 {
15403 Lisp_Object face;
15404 if (NILP (props))
15405 props = Ftext_properties_at (make_number (0), lisp_string);
15406 face = Fplist_get (props, Qface);
15407 if (NILP (face))
15408 face = mode_line_string_face;
15409 else
15410 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15411 props = Fcons (Qface, Fcons (face, Qnil));
15412 if (copy_string)
15413 lisp_string = Fcopy_sequence (lisp_string);
15414 }
15415 if (!NILP (props))
15416 Fadd_text_properties (make_number (0), make_number (len),
15417 props, lisp_string);
15418 }
15419
15420 if (len > 0)
15421 {
15422 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15423 n += len;
15424 }
15425
15426 if (field_width > len)
15427 {
15428 field_width -= len;
15429 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15430 if (!NILP (props))
15431 Fadd_text_properties (make_number (0), make_number (field_width),
15432 props, lisp_string);
15433 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15434 n += field_width;
15435 }
15436
15437 return n;
15438 }
15439
15440
15441 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15442 0, 3, 0,
15443 doc: /* Return the mode-line of selected window as a string.
15444 First optional arg FORMAT specifies a different format string (see
15445 `mode-line-format' for details) to use. If FORMAT is t, return
15446 the buffer's header-line. Second optional arg WINDOW specifies a
15447 different window to use as the context for the formatting.
15448 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15449 (format, window, no_props)
15450 Lisp_Object format, window, no_props;
15451 {
15452 struct it it;
15453 int len;
15454 struct window *w;
15455 struct buffer *old_buffer = NULL;
15456 enum face_id face_id = DEFAULT_FACE_ID;
15457
15458 if (NILP (window))
15459 window = selected_window;
15460 CHECK_WINDOW (window);
15461 w = XWINDOW (window);
15462 CHECK_BUFFER (w->buffer);
15463
15464 if (XBUFFER (w->buffer) != current_buffer)
15465 {
15466 old_buffer = current_buffer;
15467 set_buffer_internal_1 (XBUFFER (w->buffer));
15468 }
15469
15470 if (NILP (format) || EQ (format, Qt))
15471 {
15472 face_id = NILP (format)
15473 ? CURRENT_MODE_LINE_FACE_ID (w) :
15474 HEADER_LINE_FACE_ID;
15475 format = NILP (format)
15476 ? current_buffer->mode_line_format
15477 : current_buffer->header_line_format;
15478 }
15479
15480 init_iterator (&it, w, -1, -1, NULL, face_id);
15481
15482 if (NILP (no_props))
15483 {
15484 mode_line_string_face =
15485 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15486 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15487 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15488
15489 mode_line_string_face_prop =
15490 NILP (mode_line_string_face) ? Qnil :
15491 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15492
15493 /* We need a dummy last element in mode_line_string_list to
15494 indicate we are building the propertized mode-line string.
15495 Using mode_line_string_face_prop here GC protects it. */
15496 mode_line_string_list =
15497 Fcons (mode_line_string_face_prop, Qnil);
15498 frame_title_ptr = NULL;
15499 }
15500 else
15501 {
15502 mode_line_string_face_prop = Qnil;
15503 mode_line_string_list = Qnil;
15504 frame_title_ptr = frame_title_buf;
15505 }
15506
15507 push_frame_kboard (it.f);
15508 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15509 pop_frame_kboard ();
15510
15511 if (old_buffer)
15512 set_buffer_internal_1 (old_buffer);
15513
15514 if (NILP (no_props))
15515 {
15516 Lisp_Object str;
15517 mode_line_string_list = Fnreverse (mode_line_string_list);
15518 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15519 make_string ("", 0));
15520 mode_line_string_face_prop = Qnil;
15521 mode_line_string_list = Qnil;
15522 return str;
15523 }
15524
15525 len = frame_title_ptr - frame_title_buf;
15526 if (len > 0 && frame_title_ptr[-1] == '-')
15527 {
15528 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15529 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15530 ;
15531 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15532 if (len > frame_title_ptr - frame_title_buf)
15533 len = frame_title_ptr - frame_title_buf;
15534 }
15535
15536 frame_title_ptr = NULL;
15537 return make_string (frame_title_buf, len);
15538 }
15539
15540 /* Write a null-terminated, right justified decimal representation of
15541 the positive integer D to BUF using a minimal field width WIDTH. */
15542
15543 static void
15544 pint2str (buf, width, d)
15545 register char *buf;
15546 register int width;
15547 register int d;
15548 {
15549 register char *p = buf;
15550
15551 if (d <= 0)
15552 *p++ = '0';
15553 else
15554 {
15555 while (d > 0)
15556 {
15557 *p++ = d % 10 + '0';
15558 d /= 10;
15559 }
15560 }
15561
15562 for (width -= (int) (p - buf); width > 0; --width)
15563 *p++ = ' ';
15564 *p-- = '\0';
15565 while (p > buf)
15566 {
15567 d = *buf;
15568 *buf++ = *p;
15569 *p-- = d;
15570 }
15571 }
15572
15573 /* Write a null-terminated, right justified decimal and "human
15574 readable" representation of the nonnegative integer D to BUF using
15575 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15576
15577 static const char power_letter[] =
15578 {
15579 0, /* not used */
15580 'k', /* kilo */
15581 'M', /* mega */
15582 'G', /* giga */
15583 'T', /* tera */
15584 'P', /* peta */
15585 'E', /* exa */
15586 'Z', /* zetta */
15587 'Y' /* yotta */
15588 };
15589
15590 static void
15591 pint2hrstr (buf, width, d)
15592 char *buf;
15593 int width;
15594 int d;
15595 {
15596 /* We aim to represent the nonnegative integer D as
15597 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15598 int quotient = d;
15599 int remainder = 0;
15600 /* -1 means: do not use TENTHS. */
15601 int tenths = -1;
15602 int exponent = 0;
15603
15604 /* Length of QUOTIENT.TENTHS as a string. */
15605 int length;
15606
15607 char * psuffix;
15608 char * p;
15609
15610 if (1000 <= quotient)
15611 {
15612 /* Scale to the appropriate EXPONENT. */
15613 do
15614 {
15615 remainder = quotient % 1000;
15616 quotient /= 1000;
15617 exponent++;
15618 }
15619 while (1000 <= quotient);
15620
15621 /* Round to nearest and decide whether to use TENTHS or not. */
15622 if (quotient <= 9)
15623 {
15624 tenths = remainder / 100;
15625 if (50 <= remainder % 100)
15626 if (tenths < 9)
15627 tenths++;
15628 else
15629 {
15630 quotient++;
15631 if (quotient == 10)
15632 tenths = -1;
15633 else
15634 tenths = 0;
15635 }
15636 }
15637 else
15638 if (500 <= remainder)
15639 if (quotient < 999)
15640 quotient++;
15641 else
15642 {
15643 quotient = 1;
15644 exponent++;
15645 tenths = 0;
15646 }
15647 }
15648
15649 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15650 if (tenths == -1 && quotient <= 99)
15651 if (quotient <= 9)
15652 length = 1;
15653 else
15654 length = 2;
15655 else
15656 length = 3;
15657 p = psuffix = buf + max (width, length);
15658
15659 /* Print EXPONENT. */
15660 if (exponent)
15661 *psuffix++ = power_letter[exponent];
15662 *psuffix = '\0';
15663
15664 /* Print TENTHS. */
15665 if (tenths >= 0)
15666 {
15667 *--p = '0' + tenths;
15668 *--p = '.';
15669 }
15670
15671 /* Print QUOTIENT. */
15672 do
15673 {
15674 int digit = quotient % 10;
15675 *--p = '0' + digit;
15676 }
15677 while ((quotient /= 10) != 0);
15678
15679 /* Print leading spaces. */
15680 while (buf < p)
15681 *--p = ' ';
15682 }
15683
15684 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15685 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15686 type of CODING_SYSTEM. Return updated pointer into BUF. */
15687
15688 static unsigned char invalid_eol_type[] = "(*invalid*)";
15689
15690 static char *
15691 decode_mode_spec_coding (coding_system, buf, eol_flag)
15692 Lisp_Object coding_system;
15693 register char *buf;
15694 int eol_flag;
15695 {
15696 Lisp_Object val;
15697 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15698 const unsigned char *eol_str;
15699 int eol_str_len;
15700 /* The EOL conversion we are using. */
15701 Lisp_Object eoltype;
15702
15703 val = Fget (coding_system, Qcoding_system);
15704 eoltype = Qnil;
15705
15706 if (!VECTORP (val)) /* Not yet decided. */
15707 {
15708 if (multibyte)
15709 *buf++ = '-';
15710 if (eol_flag)
15711 eoltype = eol_mnemonic_undecided;
15712 /* Don't mention EOL conversion if it isn't decided. */
15713 }
15714 else
15715 {
15716 Lisp_Object eolvalue;
15717
15718 eolvalue = Fget (coding_system, Qeol_type);
15719
15720 if (multibyte)
15721 *buf++ = XFASTINT (AREF (val, 1));
15722
15723 if (eol_flag)
15724 {
15725 /* The EOL conversion that is normal on this system. */
15726
15727 if (NILP (eolvalue)) /* Not yet decided. */
15728 eoltype = eol_mnemonic_undecided;
15729 else if (VECTORP (eolvalue)) /* Not yet decided. */
15730 eoltype = eol_mnemonic_undecided;
15731 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15732 eoltype = (XFASTINT (eolvalue) == 0
15733 ? eol_mnemonic_unix
15734 : (XFASTINT (eolvalue) == 1
15735 ? eol_mnemonic_dos : eol_mnemonic_mac));
15736 }
15737 }
15738
15739 if (eol_flag)
15740 {
15741 /* Mention the EOL conversion if it is not the usual one. */
15742 if (STRINGP (eoltype))
15743 {
15744 eol_str = SDATA (eoltype);
15745 eol_str_len = SBYTES (eoltype);
15746 }
15747 else if (INTEGERP (eoltype)
15748 && CHAR_VALID_P (XINT (eoltype), 0))
15749 {
15750 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15751 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15752 eol_str = tmp;
15753 }
15754 else
15755 {
15756 eol_str = invalid_eol_type;
15757 eol_str_len = sizeof (invalid_eol_type) - 1;
15758 }
15759 bcopy (eol_str, buf, eol_str_len);
15760 buf += eol_str_len;
15761 }
15762
15763 return buf;
15764 }
15765
15766 /* Return a string for the output of a mode line %-spec for window W,
15767 generated by character C. PRECISION >= 0 means don't return a
15768 string longer than that value. FIELD_WIDTH > 0 means pad the
15769 string returned with spaces to that value. Return 1 in *MULTIBYTE
15770 if the result is multibyte text. */
15771
15772 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15773
15774 static char *
15775 decode_mode_spec (w, c, field_width, precision, multibyte)
15776 struct window *w;
15777 register int c;
15778 int field_width, precision;
15779 int *multibyte;
15780 {
15781 Lisp_Object obj;
15782 struct frame *f = XFRAME (WINDOW_FRAME (w));
15783 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15784 struct buffer *b = XBUFFER (w->buffer);
15785
15786 obj = Qnil;
15787 *multibyte = 0;
15788
15789 switch (c)
15790 {
15791 case '*':
15792 if (!NILP (b->read_only))
15793 return "%";
15794 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15795 return "*";
15796 return "-";
15797
15798 case '+':
15799 /* This differs from %* only for a modified read-only buffer. */
15800 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15801 return "*";
15802 if (!NILP (b->read_only))
15803 return "%";
15804 return "-";
15805
15806 case '&':
15807 /* This differs from %* in ignoring read-only-ness. */
15808 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15809 return "*";
15810 return "-";
15811
15812 case '%':
15813 return "%";
15814
15815 case '[':
15816 {
15817 int i;
15818 char *p;
15819
15820 if (command_loop_level > 5)
15821 return "[[[... ";
15822 p = decode_mode_spec_buf;
15823 for (i = 0; i < command_loop_level; i++)
15824 *p++ = '[';
15825 *p = 0;
15826 return decode_mode_spec_buf;
15827 }
15828
15829 case ']':
15830 {
15831 int i;
15832 char *p;
15833
15834 if (command_loop_level > 5)
15835 return " ...]]]";
15836 p = decode_mode_spec_buf;
15837 for (i = 0; i < command_loop_level; i++)
15838 *p++ = ']';
15839 *p = 0;
15840 return decode_mode_spec_buf;
15841 }
15842
15843 case '-':
15844 {
15845 register int i;
15846
15847 /* Let lots_of_dashes be a string of infinite length. */
15848 if (!NILP (mode_line_string_list))
15849 return "--";
15850 if (field_width <= 0
15851 || field_width > sizeof (lots_of_dashes))
15852 {
15853 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
15854 decode_mode_spec_buf[i] = '-';
15855 decode_mode_spec_buf[i] = '\0';
15856 return decode_mode_spec_buf;
15857 }
15858 else
15859 return lots_of_dashes;
15860 }
15861
15862 case 'b':
15863 obj = b->name;
15864 break;
15865
15866 case 'c':
15867 {
15868 int col = (int) current_column (); /* iftc */
15869 w->column_number_displayed = make_number (col);
15870 pint2str (decode_mode_spec_buf, field_width, col);
15871 return decode_mode_spec_buf;
15872 }
15873
15874 case 'F':
15875 /* %F displays the frame name. */
15876 if (!NILP (f->title))
15877 return (char *) SDATA (f->title);
15878 if (f->explicit_name || ! FRAME_WINDOW_P (f))
15879 return (char *) SDATA (f->name);
15880 return "Emacs";
15881
15882 case 'f':
15883 obj = b->filename;
15884 break;
15885
15886 case 'i':
15887 {
15888 int size = ZV - BEGV;
15889 pint2str (decode_mode_spec_buf, field_width, size);
15890 return decode_mode_spec_buf;
15891 }
15892
15893 case 'I':
15894 {
15895 int size = ZV - BEGV;
15896 pint2hrstr (decode_mode_spec_buf, field_width, size);
15897 return decode_mode_spec_buf;
15898 }
15899
15900 case 'l':
15901 {
15902 int startpos = XMARKER (w->start)->charpos;
15903 int startpos_byte = marker_byte_position (w->start);
15904 int line, linepos, linepos_byte, topline;
15905 int nlines, junk;
15906 int height = WINDOW_TOTAL_LINES (w);
15907
15908 /* If we decided that this buffer isn't suitable for line numbers,
15909 don't forget that too fast. */
15910 if (EQ (w->base_line_pos, w->buffer))
15911 goto no_value;
15912 /* But do forget it, if the window shows a different buffer now. */
15913 else if (BUFFERP (w->base_line_pos))
15914 w->base_line_pos = Qnil;
15915
15916 /* If the buffer is very big, don't waste time. */
15917 if (INTEGERP (Vline_number_display_limit)
15918 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
15919 {
15920 w->base_line_pos = Qnil;
15921 w->base_line_number = Qnil;
15922 goto no_value;
15923 }
15924
15925 if (!NILP (w->base_line_number)
15926 && !NILP (w->base_line_pos)
15927 && XFASTINT (w->base_line_pos) <= startpos)
15928 {
15929 line = XFASTINT (w->base_line_number);
15930 linepos = XFASTINT (w->base_line_pos);
15931 linepos_byte = buf_charpos_to_bytepos (b, linepos);
15932 }
15933 else
15934 {
15935 line = 1;
15936 linepos = BUF_BEGV (b);
15937 linepos_byte = BUF_BEGV_BYTE (b);
15938 }
15939
15940 /* Count lines from base line to window start position. */
15941 nlines = display_count_lines (linepos, linepos_byte,
15942 startpos_byte,
15943 startpos, &junk);
15944
15945 topline = nlines + line;
15946
15947 /* Determine a new base line, if the old one is too close
15948 or too far away, or if we did not have one.
15949 "Too close" means it's plausible a scroll-down would
15950 go back past it. */
15951 if (startpos == BUF_BEGV (b))
15952 {
15953 w->base_line_number = make_number (topline);
15954 w->base_line_pos = make_number (BUF_BEGV (b));
15955 }
15956 else if (nlines < height + 25 || nlines > height * 3 + 50
15957 || linepos == BUF_BEGV (b))
15958 {
15959 int limit = BUF_BEGV (b);
15960 int limit_byte = BUF_BEGV_BYTE (b);
15961 int position;
15962 int distance = (height * 2 + 30) * line_number_display_limit_width;
15963
15964 if (startpos - distance > limit)
15965 {
15966 limit = startpos - distance;
15967 limit_byte = CHAR_TO_BYTE (limit);
15968 }
15969
15970 nlines = display_count_lines (startpos, startpos_byte,
15971 limit_byte,
15972 - (height * 2 + 30),
15973 &position);
15974 /* If we couldn't find the lines we wanted within
15975 line_number_display_limit_width chars per line,
15976 give up on line numbers for this window. */
15977 if (position == limit_byte && limit == startpos - distance)
15978 {
15979 w->base_line_pos = w->buffer;
15980 w->base_line_number = Qnil;
15981 goto no_value;
15982 }
15983
15984 w->base_line_number = make_number (topline - nlines);
15985 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
15986 }
15987
15988 /* Now count lines from the start pos to point. */
15989 nlines = display_count_lines (startpos, startpos_byte,
15990 PT_BYTE, PT, &junk);
15991
15992 /* Record that we did display the line number. */
15993 line_number_displayed = 1;
15994
15995 /* Make the string to show. */
15996 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
15997 return decode_mode_spec_buf;
15998 no_value:
15999 {
16000 char* p = decode_mode_spec_buf;
16001 int pad = field_width - 2;
16002 while (pad-- > 0)
16003 *p++ = ' ';
16004 *p++ = '?';
16005 *p++ = '?';
16006 *p = '\0';
16007 return decode_mode_spec_buf;
16008 }
16009 }
16010 break;
16011
16012 case 'm':
16013 obj = b->mode_name;
16014 break;
16015
16016 case 'n':
16017 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16018 return " Narrow";
16019 break;
16020
16021 case 'p':
16022 {
16023 int pos = marker_position (w->start);
16024 int total = BUF_ZV (b) - BUF_BEGV (b);
16025
16026 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16027 {
16028 if (pos <= BUF_BEGV (b))
16029 return "All";
16030 else
16031 return "Bottom";
16032 }
16033 else if (pos <= BUF_BEGV (b))
16034 return "Top";
16035 else
16036 {
16037 if (total > 1000000)
16038 /* Do it differently for a large value, to avoid overflow. */
16039 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16040 else
16041 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16042 /* We can't normally display a 3-digit number,
16043 so get us a 2-digit number that is close. */
16044 if (total == 100)
16045 total = 99;
16046 sprintf (decode_mode_spec_buf, "%2d%%", total);
16047 return decode_mode_spec_buf;
16048 }
16049 }
16050
16051 /* Display percentage of size above the bottom of the screen. */
16052 case 'P':
16053 {
16054 int toppos = marker_position (w->start);
16055 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16056 int total = BUF_ZV (b) - BUF_BEGV (b);
16057
16058 if (botpos >= BUF_ZV (b))
16059 {
16060 if (toppos <= BUF_BEGV (b))
16061 return "All";
16062 else
16063 return "Bottom";
16064 }
16065 else
16066 {
16067 if (total > 1000000)
16068 /* Do it differently for a large value, to avoid overflow. */
16069 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16070 else
16071 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16072 /* We can't normally display a 3-digit number,
16073 so get us a 2-digit number that is close. */
16074 if (total == 100)
16075 total = 99;
16076 if (toppos <= BUF_BEGV (b))
16077 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16078 else
16079 sprintf (decode_mode_spec_buf, "%2d%%", total);
16080 return decode_mode_spec_buf;
16081 }
16082 }
16083
16084 case 's':
16085 /* status of process */
16086 obj = Fget_buffer_process (w->buffer);
16087 if (NILP (obj))
16088 return "no process";
16089 #ifdef subprocesses
16090 obj = Fsymbol_name (Fprocess_status (obj));
16091 #endif
16092 break;
16093
16094 case 't': /* indicate TEXT or BINARY */
16095 #ifdef MODE_LINE_BINARY_TEXT
16096 return MODE_LINE_BINARY_TEXT (b);
16097 #else
16098 return "T";
16099 #endif
16100
16101 case 'z':
16102 /* coding-system (not including end-of-line format) */
16103 case 'Z':
16104 /* coding-system (including end-of-line type) */
16105 {
16106 int eol_flag = (c == 'Z');
16107 char *p = decode_mode_spec_buf;
16108
16109 if (! FRAME_WINDOW_P (f))
16110 {
16111 /* No need to mention EOL here--the terminal never needs
16112 to do EOL conversion. */
16113 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16114 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16115 }
16116 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16117 p, eol_flag);
16118
16119 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16120 #ifdef subprocesses
16121 obj = Fget_buffer_process (Fcurrent_buffer ());
16122 if (PROCESSP (obj))
16123 {
16124 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16125 p, eol_flag);
16126 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16127 p, eol_flag);
16128 }
16129 #endif /* subprocesses */
16130 #endif /* 0 */
16131 *p = 0;
16132 return decode_mode_spec_buf;
16133 }
16134 }
16135
16136 if (STRINGP (obj))
16137 {
16138 *multibyte = STRING_MULTIBYTE (obj);
16139 return (char *) SDATA (obj);
16140 }
16141 else
16142 return "";
16143 }
16144
16145
16146 /* Count up to COUNT lines starting from START / START_BYTE.
16147 But don't go beyond LIMIT_BYTE.
16148 Return the number of lines thus found (always nonnegative).
16149
16150 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16151
16152 static int
16153 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16154 int start, start_byte, limit_byte, count;
16155 int *byte_pos_ptr;
16156 {
16157 register unsigned char *cursor;
16158 unsigned char *base;
16159
16160 register int ceiling;
16161 register unsigned char *ceiling_addr;
16162 int orig_count = count;
16163
16164 /* If we are not in selective display mode,
16165 check only for newlines. */
16166 int selective_display = (!NILP (current_buffer->selective_display)
16167 && !INTEGERP (current_buffer->selective_display));
16168
16169 if (count > 0)
16170 {
16171 while (start_byte < limit_byte)
16172 {
16173 ceiling = BUFFER_CEILING_OF (start_byte);
16174 ceiling = min (limit_byte - 1, ceiling);
16175 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16176 base = (cursor = BYTE_POS_ADDR (start_byte));
16177 while (1)
16178 {
16179 if (selective_display)
16180 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16181 ;
16182 else
16183 while (*cursor != '\n' && ++cursor != ceiling_addr)
16184 ;
16185
16186 if (cursor != ceiling_addr)
16187 {
16188 if (--count == 0)
16189 {
16190 start_byte += cursor - base + 1;
16191 *byte_pos_ptr = start_byte;
16192 return orig_count;
16193 }
16194 else
16195 if (++cursor == ceiling_addr)
16196 break;
16197 }
16198 else
16199 break;
16200 }
16201 start_byte += cursor - base;
16202 }
16203 }
16204 else
16205 {
16206 while (start_byte > limit_byte)
16207 {
16208 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16209 ceiling = max (limit_byte, ceiling);
16210 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16211 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16212 while (1)
16213 {
16214 if (selective_display)
16215 while (--cursor != ceiling_addr
16216 && *cursor != '\n' && *cursor != 015)
16217 ;
16218 else
16219 while (--cursor != ceiling_addr && *cursor != '\n')
16220 ;
16221
16222 if (cursor != ceiling_addr)
16223 {
16224 if (++count == 0)
16225 {
16226 start_byte += cursor - base + 1;
16227 *byte_pos_ptr = start_byte;
16228 /* When scanning backwards, we should
16229 not count the newline posterior to which we stop. */
16230 return - orig_count - 1;
16231 }
16232 }
16233 else
16234 break;
16235 }
16236 /* Here we add 1 to compensate for the last decrement
16237 of CURSOR, which took it past the valid range. */
16238 start_byte += cursor - base + 1;
16239 }
16240 }
16241
16242 *byte_pos_ptr = limit_byte;
16243
16244 if (count < 0)
16245 return - orig_count + count;
16246 return orig_count - count;
16247
16248 }
16249
16250
16251 \f
16252 /***********************************************************************
16253 Displaying strings
16254 ***********************************************************************/
16255
16256 /* Display a NUL-terminated string, starting with index START.
16257
16258 If STRING is non-null, display that C string. Otherwise, the Lisp
16259 string LISP_STRING is displayed.
16260
16261 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16262 FACE_STRING. Display STRING or LISP_STRING with the face at
16263 FACE_STRING_POS in FACE_STRING:
16264
16265 Display the string in the environment given by IT, but use the
16266 standard display table, temporarily.
16267
16268 FIELD_WIDTH is the minimum number of output glyphs to produce.
16269 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16270 with spaces. If STRING has more characters, more than FIELD_WIDTH
16271 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16272
16273 PRECISION is the maximum number of characters to output from
16274 STRING. PRECISION < 0 means don't truncate the string.
16275
16276 This is roughly equivalent to printf format specifiers:
16277
16278 FIELD_WIDTH PRECISION PRINTF
16279 ----------------------------------------
16280 -1 -1 %s
16281 -1 10 %.10s
16282 10 -1 %10s
16283 20 10 %20.10s
16284
16285 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16286 display them, and < 0 means obey the current buffer's value of
16287 enable_multibyte_characters.
16288
16289 Value is the number of glyphs produced. */
16290
16291 static int
16292 display_string (string, lisp_string, face_string, face_string_pos,
16293 start, it, field_width, precision, max_x, multibyte)
16294 unsigned char *string;
16295 Lisp_Object lisp_string;
16296 Lisp_Object face_string;
16297 int face_string_pos;
16298 int start;
16299 struct it *it;
16300 int field_width, precision, max_x;
16301 int multibyte;
16302 {
16303 int hpos_at_start = it->hpos;
16304 int saved_face_id = it->face_id;
16305 struct glyph_row *row = it->glyph_row;
16306
16307 /* Initialize the iterator IT for iteration over STRING beginning
16308 with index START. */
16309 reseat_to_string (it, string, lisp_string, start,
16310 precision, field_width, multibyte);
16311
16312 /* If displaying STRING, set up the face of the iterator
16313 from LISP_STRING, if that's given. */
16314 if (STRINGP (face_string))
16315 {
16316 int endptr;
16317 struct face *face;
16318
16319 it->face_id
16320 = face_at_string_position (it->w, face_string, face_string_pos,
16321 0, it->region_beg_charpos,
16322 it->region_end_charpos,
16323 &endptr, it->base_face_id, 0);
16324 face = FACE_FROM_ID (it->f, it->face_id);
16325 it->face_box_p = face->box != FACE_NO_BOX;
16326 }
16327
16328 /* Set max_x to the maximum allowed X position. Don't let it go
16329 beyond the right edge of the window. */
16330 if (max_x <= 0)
16331 max_x = it->last_visible_x;
16332 else
16333 max_x = min (max_x, it->last_visible_x);
16334
16335 /* Skip over display elements that are not visible. because IT->w is
16336 hscrolled. */
16337 if (it->current_x < it->first_visible_x)
16338 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16339 MOVE_TO_POS | MOVE_TO_X);
16340
16341 row->ascent = it->max_ascent;
16342 row->height = it->max_ascent + it->max_descent;
16343 row->phys_ascent = it->max_phys_ascent;
16344 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16345
16346 /* This condition is for the case that we are called with current_x
16347 past last_visible_x. */
16348 while (it->current_x < max_x)
16349 {
16350 int x_before, x, n_glyphs_before, i, nglyphs;
16351
16352 /* Get the next display element. */
16353 if (!get_next_display_element (it))
16354 break;
16355
16356 /* Produce glyphs. */
16357 x_before = it->current_x;
16358 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16359 PRODUCE_GLYPHS (it);
16360
16361 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16362 i = 0;
16363 x = x_before;
16364 while (i < nglyphs)
16365 {
16366 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16367
16368 if (!it->truncate_lines_p
16369 && x + glyph->pixel_width > max_x)
16370 {
16371 /* End of continued line or max_x reached. */
16372 if (CHAR_GLYPH_PADDING_P (*glyph))
16373 {
16374 /* A wide character is unbreakable. */
16375 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16376 it->current_x = x_before;
16377 }
16378 else
16379 {
16380 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16381 it->current_x = x;
16382 }
16383 break;
16384 }
16385 else if (x + glyph->pixel_width > it->first_visible_x)
16386 {
16387 /* Glyph is at least partially visible. */
16388 ++it->hpos;
16389 if (x < it->first_visible_x)
16390 it->glyph_row->x = x - it->first_visible_x;
16391 }
16392 else
16393 {
16394 /* Glyph is off the left margin of the display area.
16395 Should not happen. */
16396 abort ();
16397 }
16398
16399 row->ascent = max (row->ascent, it->max_ascent);
16400 row->height = max (row->height, it->max_ascent + it->max_descent);
16401 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16402 row->phys_height = max (row->phys_height,
16403 it->max_phys_ascent + it->max_phys_descent);
16404 x += glyph->pixel_width;
16405 ++i;
16406 }
16407
16408 /* Stop if max_x reached. */
16409 if (i < nglyphs)
16410 break;
16411
16412 /* Stop at line ends. */
16413 if (ITERATOR_AT_END_OF_LINE_P (it))
16414 {
16415 it->continuation_lines_width = 0;
16416 break;
16417 }
16418
16419 set_iterator_to_next (it, 1);
16420
16421 /* Stop if truncating at the right edge. */
16422 if (it->truncate_lines_p
16423 && it->current_x >= it->last_visible_x)
16424 {
16425 /* Add truncation mark, but don't do it if the line is
16426 truncated at a padding space. */
16427 if (IT_CHARPOS (*it) < it->string_nchars)
16428 {
16429 if (!FRAME_WINDOW_P (it->f))
16430 {
16431 int i, n;
16432
16433 if (it->current_x > it->last_visible_x)
16434 {
16435 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16436 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16437 break;
16438 for (n = row->used[TEXT_AREA]; i < n; ++i)
16439 {
16440 row->used[TEXT_AREA] = i;
16441 produce_special_glyphs (it, IT_TRUNCATION);
16442 }
16443 }
16444 produce_special_glyphs (it, IT_TRUNCATION);
16445 }
16446 it->glyph_row->truncated_on_right_p = 1;
16447 }
16448 break;
16449 }
16450 }
16451
16452 /* Maybe insert a truncation at the left. */
16453 if (it->first_visible_x
16454 && IT_CHARPOS (*it) > 0)
16455 {
16456 if (!FRAME_WINDOW_P (it->f))
16457 insert_left_trunc_glyphs (it);
16458 it->glyph_row->truncated_on_left_p = 1;
16459 }
16460
16461 it->face_id = saved_face_id;
16462
16463 /* Value is number of columns displayed. */
16464 return it->hpos - hpos_at_start;
16465 }
16466
16467
16468 \f
16469 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16470 appears as an element of LIST or as the car of an element of LIST.
16471 If PROPVAL is a list, compare each element against LIST in that
16472 way, and return 1/2 if any element of PROPVAL is found in LIST.
16473 Otherwise return 0. This function cannot quit.
16474 The return value is 2 if the text is invisible but with an ellipsis
16475 and 1 if it's invisible and without an ellipsis. */
16476
16477 int
16478 invisible_p (propval, list)
16479 register Lisp_Object propval;
16480 Lisp_Object list;
16481 {
16482 register Lisp_Object tail, proptail;
16483
16484 for (tail = list; CONSP (tail); tail = XCDR (tail))
16485 {
16486 register Lisp_Object tem;
16487 tem = XCAR (tail);
16488 if (EQ (propval, tem))
16489 return 1;
16490 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16491 return NILP (XCDR (tem)) ? 1 : 2;
16492 }
16493
16494 if (CONSP (propval))
16495 {
16496 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16497 {
16498 Lisp_Object propelt;
16499 propelt = XCAR (proptail);
16500 for (tail = list; CONSP (tail); tail = XCDR (tail))
16501 {
16502 register Lisp_Object tem;
16503 tem = XCAR (tail);
16504 if (EQ (propelt, tem))
16505 return 1;
16506 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16507 return NILP (XCDR (tem)) ? 1 : 2;
16508 }
16509 }
16510 }
16511
16512 return 0;
16513 }
16514
16515 \f
16516 /***********************************************************************
16517 Glyph Display
16518 ***********************************************************************/
16519
16520 #ifdef HAVE_WINDOW_SYSTEM
16521
16522 #if GLYPH_DEBUG
16523
16524 void
16525 dump_glyph_string (s)
16526 struct glyph_string *s;
16527 {
16528 fprintf (stderr, "glyph string\n");
16529 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16530 s->x, s->y, s->width, s->height);
16531 fprintf (stderr, " ybase = %d\n", s->ybase);
16532 fprintf (stderr, " hl = %d\n", s->hl);
16533 fprintf (stderr, " left overhang = %d, right = %d\n",
16534 s->left_overhang, s->right_overhang);
16535 fprintf (stderr, " nchars = %d\n", s->nchars);
16536 fprintf (stderr, " extends to end of line = %d\n",
16537 s->extends_to_end_of_line_p);
16538 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16539 fprintf (stderr, " bg width = %d\n", s->background_width);
16540 }
16541
16542 #endif /* GLYPH_DEBUG */
16543
16544 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16545 of XChar2b structures for S; it can't be allocated in
16546 init_glyph_string because it must be allocated via `alloca'. W
16547 is the window on which S is drawn. ROW and AREA are the glyph row
16548 and area within the row from which S is constructed. START is the
16549 index of the first glyph structure covered by S. HL is a
16550 face-override for drawing S. */
16551
16552 #ifdef HAVE_NTGUI
16553 #define OPTIONAL_HDC(hdc) hdc,
16554 #define DECLARE_HDC(hdc) HDC hdc;
16555 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16556 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16557 #endif
16558
16559 #ifndef OPTIONAL_HDC
16560 #define OPTIONAL_HDC(hdc)
16561 #define DECLARE_HDC(hdc)
16562 #define ALLOCATE_HDC(hdc, f)
16563 #define RELEASE_HDC(hdc, f)
16564 #endif
16565
16566 static void
16567 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16568 struct glyph_string *s;
16569 DECLARE_HDC (hdc)
16570 XChar2b *char2b;
16571 struct window *w;
16572 struct glyph_row *row;
16573 enum glyph_row_area area;
16574 int start;
16575 enum draw_glyphs_face hl;
16576 {
16577 bzero (s, sizeof *s);
16578 s->w = w;
16579 s->f = XFRAME (w->frame);
16580 #ifdef HAVE_NTGUI
16581 s->hdc = hdc;
16582 #endif
16583 s->display = FRAME_X_DISPLAY (s->f);
16584 s->window = FRAME_X_WINDOW (s->f);
16585 s->char2b = char2b;
16586 s->hl = hl;
16587 s->row = row;
16588 s->area = area;
16589 s->first_glyph = row->glyphs[area] + start;
16590 s->height = row->height;
16591 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16592
16593 /* Display the internal border below the tool-bar window. */
16594 if (s->w == XWINDOW (s->f->tool_bar_window))
16595 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16596
16597 s->ybase = s->y + row->ascent;
16598 }
16599
16600
16601 /* Append the list of glyph strings with head H and tail T to the list
16602 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16603
16604 static INLINE void
16605 append_glyph_string_lists (head, tail, h, t)
16606 struct glyph_string **head, **tail;
16607 struct glyph_string *h, *t;
16608 {
16609 if (h)
16610 {
16611 if (*head)
16612 (*tail)->next = h;
16613 else
16614 *head = h;
16615 h->prev = *tail;
16616 *tail = t;
16617 }
16618 }
16619
16620
16621 /* Prepend the list of glyph strings with head H and tail T to the
16622 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16623 result. */
16624
16625 static INLINE void
16626 prepend_glyph_string_lists (head, tail, h, t)
16627 struct glyph_string **head, **tail;
16628 struct glyph_string *h, *t;
16629 {
16630 if (h)
16631 {
16632 if (*head)
16633 (*head)->prev = t;
16634 else
16635 *tail = t;
16636 t->next = *head;
16637 *head = h;
16638 }
16639 }
16640
16641
16642 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16643 Set *HEAD and *TAIL to the resulting list. */
16644
16645 static INLINE void
16646 append_glyph_string (head, tail, s)
16647 struct glyph_string **head, **tail;
16648 struct glyph_string *s;
16649 {
16650 s->next = s->prev = NULL;
16651 append_glyph_string_lists (head, tail, s, s);
16652 }
16653
16654
16655 /* Get face and two-byte form of character glyph GLYPH on frame F.
16656 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16657 a pointer to a realized face that is ready for display. */
16658
16659 static INLINE struct face *
16660 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16661 struct frame *f;
16662 struct glyph *glyph;
16663 XChar2b *char2b;
16664 int *two_byte_p;
16665 {
16666 struct face *face;
16667
16668 xassert (glyph->type == CHAR_GLYPH);
16669 face = FACE_FROM_ID (f, glyph->face_id);
16670
16671 if (two_byte_p)
16672 *two_byte_p = 0;
16673
16674 if (!glyph->multibyte_p)
16675 {
16676 /* Unibyte case. We don't have to encode, but we have to make
16677 sure to use a face suitable for unibyte. */
16678 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16679 }
16680 else if (glyph->u.ch < 128
16681 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16682 {
16683 /* Case of ASCII in a face known to fit ASCII. */
16684 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16685 }
16686 else
16687 {
16688 int c1, c2, charset;
16689
16690 /* Split characters into bytes. If c2 is -1 afterwards, C is
16691 really a one-byte character so that byte1 is zero. */
16692 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16693 if (c2 > 0)
16694 STORE_XCHAR2B (char2b, c1, c2);
16695 else
16696 STORE_XCHAR2B (char2b, 0, c1);
16697
16698 /* Maybe encode the character in *CHAR2B. */
16699 if (charset != CHARSET_ASCII)
16700 {
16701 struct font_info *font_info
16702 = FONT_INFO_FROM_ID (f, face->font_info_id);
16703 if (font_info)
16704 glyph->font_type
16705 = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16706 }
16707 }
16708
16709 /* Make sure X resources of the face are allocated. */
16710 xassert (face != NULL);
16711 PREPARE_FACE_FOR_DISPLAY (f, face);
16712 return face;
16713 }
16714
16715
16716 /* Fill glyph string S with composition components specified by S->cmp.
16717
16718 FACES is an array of faces for all components of this composition.
16719 S->gidx is the index of the first component for S.
16720 OVERLAPS_P non-zero means S should draw the foreground only, and
16721 use its physical height for clipping.
16722
16723 Value is the index of a component not in S. */
16724
16725 static int
16726 fill_composite_glyph_string (s, faces, overlaps_p)
16727 struct glyph_string *s;
16728 struct face **faces;
16729 int overlaps_p;
16730 {
16731 int i;
16732
16733 xassert (s);
16734
16735 s->for_overlaps_p = overlaps_p;
16736
16737 s->face = faces[s->gidx];
16738 s->font = s->face->font;
16739 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16740
16741 /* For all glyphs of this composition, starting at the offset
16742 S->gidx, until we reach the end of the definition or encounter a
16743 glyph that requires the different face, add it to S. */
16744 ++s->nchars;
16745 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16746 ++s->nchars;
16747
16748 /* All glyph strings for the same composition has the same width,
16749 i.e. the width set for the first component of the composition. */
16750
16751 s->width = s->first_glyph->pixel_width;
16752
16753 /* If the specified font could not be loaded, use the frame's
16754 default font, but record the fact that we couldn't load it in
16755 the glyph string so that we can draw rectangles for the
16756 characters of the glyph string. */
16757 if (s->font == NULL)
16758 {
16759 s->font_not_found_p = 1;
16760 s->font = FRAME_FONT (s->f);
16761 }
16762
16763 /* Adjust base line for subscript/superscript text. */
16764 s->ybase += s->first_glyph->voffset;
16765
16766 xassert (s->face && s->face->gc);
16767
16768 /* This glyph string must always be drawn with 16-bit functions. */
16769 s->two_byte_p = 1;
16770
16771 return s->gidx + s->nchars;
16772 }
16773
16774
16775 /* Fill glyph string S from a sequence of character glyphs.
16776
16777 FACE_ID is the face id of the string. START is the index of the
16778 first glyph to consider, END is the index of the last + 1.
16779 OVERLAPS_P non-zero means S should draw the foreground only, and
16780 use its physical height for clipping.
16781
16782 Value is the index of the first glyph not in S. */
16783
16784 static int
16785 fill_glyph_string (s, face_id, start, end, overlaps_p)
16786 struct glyph_string *s;
16787 int face_id;
16788 int start, end, overlaps_p;
16789 {
16790 struct glyph *glyph, *last;
16791 int voffset;
16792 int glyph_not_available_p;
16793
16794 xassert (s->f == XFRAME (s->w->frame));
16795 xassert (s->nchars == 0);
16796 xassert (start >= 0 && end > start);
16797
16798 s->for_overlaps_p = overlaps_p,
16799 glyph = s->row->glyphs[s->area] + start;
16800 last = s->row->glyphs[s->area] + end;
16801 voffset = glyph->voffset;
16802
16803 glyph_not_available_p = glyph->glyph_not_available_p;
16804
16805 while (glyph < last
16806 && glyph->type == CHAR_GLYPH
16807 && glyph->voffset == voffset
16808 /* Same face id implies same font, nowadays. */
16809 && glyph->face_id == face_id
16810 && glyph->glyph_not_available_p == glyph_not_available_p)
16811 {
16812 int two_byte_p;
16813
16814 s->face = get_glyph_face_and_encoding (s->f, glyph,
16815 s->char2b + s->nchars,
16816 &two_byte_p);
16817 s->two_byte_p = two_byte_p;
16818 ++s->nchars;
16819 xassert (s->nchars <= end - start);
16820 s->width += glyph->pixel_width;
16821 ++glyph;
16822 }
16823
16824 s->font = s->face->font;
16825 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16826
16827 /* If the specified font could not be loaded, use the frame's font,
16828 but record the fact that we couldn't load it in
16829 S->font_not_found_p so that we can draw rectangles for the
16830 characters of the glyph string. */
16831 if (s->font == NULL || glyph_not_available_p)
16832 {
16833 s->font_not_found_p = 1;
16834 s->font = FRAME_FONT (s->f);
16835 }
16836
16837 /* Adjust base line for subscript/superscript text. */
16838 s->ybase += voffset;
16839
16840 xassert (s->face && s->face->gc);
16841 return glyph - s->row->glyphs[s->area];
16842 }
16843
16844
16845 /* Fill glyph string S from image glyph S->first_glyph. */
16846
16847 static void
16848 fill_image_glyph_string (s)
16849 struct glyph_string *s;
16850 {
16851 xassert (s->first_glyph->type == IMAGE_GLYPH);
16852 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16853 xassert (s->img);
16854 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16855 s->font = s->face->font;
16856 s->width = s->first_glyph->pixel_width;
16857
16858 /* Adjust base line for subscript/superscript text. */
16859 s->ybase += s->first_glyph->voffset;
16860 }
16861
16862
16863 /* Fill glyph string S from a sequence of stretch glyphs.
16864
16865 ROW is the glyph row in which the glyphs are found, AREA is the
16866 area within the row. START is the index of the first glyph to
16867 consider, END is the index of the last + 1.
16868
16869 Value is the index of the first glyph not in S. */
16870
16871 static int
16872 fill_stretch_glyph_string (s, row, area, start, end)
16873 struct glyph_string *s;
16874 struct glyph_row *row;
16875 enum glyph_row_area area;
16876 int start, end;
16877 {
16878 struct glyph *glyph, *last;
16879 int voffset, face_id;
16880
16881 xassert (s->first_glyph->type == STRETCH_GLYPH);
16882
16883 glyph = s->row->glyphs[s->area] + start;
16884 last = s->row->glyphs[s->area] + end;
16885 face_id = glyph->face_id;
16886 s->face = FACE_FROM_ID (s->f, face_id);
16887 s->font = s->face->font;
16888 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16889 s->width = glyph->pixel_width;
16890 voffset = glyph->voffset;
16891
16892 for (++glyph;
16893 (glyph < last
16894 && glyph->type == STRETCH_GLYPH
16895 && glyph->voffset == voffset
16896 && glyph->face_id == face_id);
16897 ++glyph)
16898 s->width += glyph->pixel_width;
16899
16900 /* Adjust base line for subscript/superscript text. */
16901 s->ybase += voffset;
16902
16903 /* The case that face->gc == 0 is handled when drawing the glyph
16904 string by calling PREPARE_FACE_FOR_DISPLAY. */
16905 xassert (s->face);
16906 return glyph - s->row->glyphs[s->area];
16907 }
16908
16909
16910 /* EXPORT for RIF:
16911 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16912 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
16913 assumed to be zero. */
16914
16915 void
16916 x_get_glyph_overhangs (glyph, f, left, right)
16917 struct glyph *glyph;
16918 struct frame *f;
16919 int *left, *right;
16920 {
16921 *left = *right = 0;
16922
16923 if (glyph->type == CHAR_GLYPH)
16924 {
16925 XFontStruct *font;
16926 struct face *face;
16927 struct font_info *font_info;
16928 XChar2b char2b;
16929 XCharStruct *pcm;
16930
16931 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
16932 font = face->font;
16933 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
16934 if (font /* ++KFS: Should this be font_info ? */
16935 && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
16936 {
16937 if (pcm->rbearing > pcm->width)
16938 *right = pcm->rbearing - pcm->width;
16939 if (pcm->lbearing < 0)
16940 *left = -pcm->lbearing;
16941 }
16942 }
16943 }
16944
16945
16946 /* Return the index of the first glyph preceding glyph string S that
16947 is overwritten by S because of S's left overhang. Value is -1
16948 if no glyphs are overwritten. */
16949
16950 static int
16951 left_overwritten (s)
16952 struct glyph_string *s;
16953 {
16954 int k;
16955
16956 if (s->left_overhang)
16957 {
16958 int x = 0, i;
16959 struct glyph *glyphs = s->row->glyphs[s->area];
16960 int first = s->first_glyph - glyphs;
16961
16962 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
16963 x -= glyphs[i].pixel_width;
16964
16965 k = i + 1;
16966 }
16967 else
16968 k = -1;
16969
16970 return k;
16971 }
16972
16973
16974 /* Return the index of the first glyph preceding glyph string S that
16975 is overwriting S because of its right overhang. Value is -1 if no
16976 glyph in front of S overwrites S. */
16977
16978 static int
16979 left_overwriting (s)
16980 struct glyph_string *s;
16981 {
16982 int i, k, x;
16983 struct glyph *glyphs = s->row->glyphs[s->area];
16984 int first = s->first_glyph - glyphs;
16985
16986 k = -1;
16987 x = 0;
16988 for (i = first - 1; i >= 0; --i)
16989 {
16990 int left, right;
16991 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16992 if (x + right > 0)
16993 k = i;
16994 x -= glyphs[i].pixel_width;
16995 }
16996
16997 return k;
16998 }
16999
17000
17001 /* Return the index of the last glyph following glyph string S that is
17002 not overwritten by S because of S's right overhang. Value is -1 if
17003 no such glyph is found. */
17004
17005 static int
17006 right_overwritten (s)
17007 struct glyph_string *s;
17008 {
17009 int k = -1;
17010
17011 if (s->right_overhang)
17012 {
17013 int x = 0, i;
17014 struct glyph *glyphs = s->row->glyphs[s->area];
17015 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17016 int end = s->row->used[s->area];
17017
17018 for (i = first; i < end && s->right_overhang > x; ++i)
17019 x += glyphs[i].pixel_width;
17020
17021 k = i;
17022 }
17023
17024 return k;
17025 }
17026
17027
17028 /* Return the index of the last glyph following glyph string S that
17029 overwrites S because of its left overhang. Value is negative
17030 if no such glyph is found. */
17031
17032 static int
17033 right_overwriting (s)
17034 struct glyph_string *s;
17035 {
17036 int i, k, x;
17037 int end = s->row->used[s->area];
17038 struct glyph *glyphs = s->row->glyphs[s->area];
17039 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17040
17041 k = -1;
17042 x = 0;
17043 for (i = first; i < end; ++i)
17044 {
17045 int left, right;
17046 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17047 if (x - left < 0)
17048 k = i;
17049 x += glyphs[i].pixel_width;
17050 }
17051
17052 return k;
17053 }
17054
17055
17056 /* Get face and two-byte form of character C in face FACE_ID on frame
17057 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17058 means we want to display multibyte text. DISPLAY_P non-zero means
17059 make sure that X resources for the face returned are allocated.
17060 Value is a pointer to a realized face that is ready for display if
17061 DISPLAY_P is non-zero. */
17062
17063 static INLINE struct face *
17064 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17065 struct frame *f;
17066 int c, face_id;
17067 XChar2b *char2b;
17068 int multibyte_p, display_p;
17069 {
17070 struct face *face = FACE_FROM_ID (f, face_id);
17071
17072 if (!multibyte_p)
17073 {
17074 /* Unibyte case. We don't have to encode, but we have to make
17075 sure to use a face suitable for unibyte. */
17076 STORE_XCHAR2B (char2b, 0, c);
17077 face_id = FACE_FOR_CHAR (f, face, c);
17078 face = FACE_FROM_ID (f, face_id);
17079 }
17080 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17081 {
17082 /* Case of ASCII in a face known to fit ASCII. */
17083 STORE_XCHAR2B (char2b, 0, c);
17084 }
17085 else
17086 {
17087 int c1, c2, charset;
17088
17089 /* Split characters into bytes. If c2 is -1 afterwards, C is
17090 really a one-byte character so that byte1 is zero. */
17091 SPLIT_CHAR (c, charset, c1, c2);
17092 if (c2 > 0)
17093 STORE_XCHAR2B (char2b, c1, c2);
17094 else
17095 STORE_XCHAR2B (char2b, 0, c1);
17096
17097 /* Maybe encode the character in *CHAR2B. */
17098 if (face->font != NULL)
17099 {
17100 struct font_info *font_info
17101 = FONT_INFO_FROM_ID (f, face->font_info_id);
17102 if (font_info)
17103 FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
17104 }
17105 }
17106
17107 /* Make sure X resources of the face are allocated. */
17108 #ifdef HAVE_X_WINDOWS
17109 if (display_p)
17110 #endif
17111 {
17112 xassert (face != NULL);
17113 PREPARE_FACE_FOR_DISPLAY (f, face);
17114 }
17115
17116 return face;
17117 }
17118
17119
17120 /* Set background width of glyph string S. START is the index of the
17121 first glyph following S. LAST_X is the right-most x-position + 1
17122 in the drawing area. */
17123
17124 static INLINE void
17125 set_glyph_string_background_width (s, start, last_x)
17126 struct glyph_string *s;
17127 int start;
17128 int last_x;
17129 {
17130 /* If the face of this glyph string has to be drawn to the end of
17131 the drawing area, set S->extends_to_end_of_line_p. */
17132 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17133
17134 if (start == s->row->used[s->area]
17135 && s->area == TEXT_AREA
17136 && ((s->hl == DRAW_NORMAL_TEXT
17137 && (s->row->fill_line_p
17138 || s->face->background != default_face->background
17139 || s->face->stipple != default_face->stipple
17140 || s->row->mouse_face_p))
17141 || s->hl == DRAW_MOUSE_FACE
17142 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17143 && s->row->fill_line_p)))
17144 s->extends_to_end_of_line_p = 1;
17145
17146 /* If S extends its face to the end of the line, set its
17147 background_width to the distance to the right edge of the drawing
17148 area. */
17149 if (s->extends_to_end_of_line_p)
17150 s->background_width = last_x - s->x + 1;
17151 else
17152 s->background_width = s->width;
17153 }
17154
17155
17156 /* Compute overhangs and x-positions for glyph string S and its
17157 predecessors, or successors. X is the starting x-position for S.
17158 BACKWARD_P non-zero means process predecessors. */
17159
17160 static void
17161 compute_overhangs_and_x (s, x, backward_p)
17162 struct glyph_string *s;
17163 int x;
17164 int backward_p;
17165 {
17166 if (backward_p)
17167 {
17168 while (s)
17169 {
17170 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
17171 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
17172 x -= s->width;
17173 s->x = x;
17174 s = s->prev;
17175 }
17176 }
17177 else
17178 {
17179 while (s)
17180 {
17181 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
17182 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
17183 s->x = x;
17184 x += s->width;
17185 s = s->next;
17186 }
17187 }
17188 }
17189
17190
17191
17192 /* The following macros are only called from draw_glyphs below.
17193 They reference the following parameters of that function directly:
17194 `w', `row', `area', and `overlap_p'
17195 as well as the following local variables:
17196 `s', `f', and `hdc' (in W32) */
17197
17198 #ifdef HAVE_NTGUI
17199 /* On W32, silently add local `hdc' variable to argument list of
17200 init_glyph_string. */
17201 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17202 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17203 #else
17204 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17205 init_glyph_string (s, char2b, w, row, area, start, hl)
17206 #endif
17207
17208 /* Add a glyph string for a stretch glyph to the list of strings
17209 between HEAD and TAIL. START is the index of the stretch glyph in
17210 row area AREA of glyph row ROW. END is the index of the last glyph
17211 in that glyph row area. X is the current output position assigned
17212 to the new glyph string constructed. HL overrides that face of the
17213 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17214 is the right-most x-position of the drawing area. */
17215
17216 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17217 and below -- keep them on one line. */
17218 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17219 do \
17220 { \
17221 s = (struct glyph_string *) alloca (sizeof *s); \
17222 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17223 START = fill_stretch_glyph_string (s, row, area, START, END); \
17224 append_glyph_string (&HEAD, &TAIL, s); \
17225 s->x = (X); \
17226 } \
17227 while (0)
17228
17229
17230 /* Add a glyph string for an image glyph to the list of strings
17231 between HEAD and TAIL. START is the index of the image glyph in
17232 row area AREA of glyph row ROW. END is the index of the last glyph
17233 in that glyph row area. X is the current output position assigned
17234 to the new glyph string constructed. HL overrides that face of the
17235 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17236 is the right-most x-position of the drawing area. */
17237
17238 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17239 do \
17240 { \
17241 s = (struct glyph_string *) alloca (sizeof *s); \
17242 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17243 fill_image_glyph_string (s); \
17244 append_glyph_string (&HEAD, &TAIL, s); \
17245 ++START; \
17246 s->x = (X); \
17247 } \
17248 while (0)
17249
17250
17251 /* Add a glyph string for a sequence of character glyphs to the list
17252 of strings between HEAD and TAIL. START is the index of the first
17253 glyph in row area AREA of glyph row ROW that is part of the new
17254 glyph string. END is the index of the last glyph in that glyph row
17255 area. X is the current output position assigned to the new glyph
17256 string constructed. HL overrides that face of the glyph; e.g. it
17257 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17258 right-most x-position of the drawing area. */
17259
17260 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17261 do \
17262 { \
17263 int c, face_id; \
17264 XChar2b *char2b; \
17265 \
17266 c = (row)->glyphs[area][START].u.ch; \
17267 face_id = (row)->glyphs[area][START].face_id; \
17268 \
17269 s = (struct glyph_string *) alloca (sizeof *s); \
17270 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17271 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17272 append_glyph_string (&HEAD, &TAIL, s); \
17273 s->x = (X); \
17274 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17275 } \
17276 while (0)
17277
17278
17279 /* Add a glyph string for a composite sequence to the list of strings
17280 between HEAD and TAIL. START is the index of the first glyph in
17281 row area AREA of glyph row ROW that is part of the new glyph
17282 string. END is the index of the last glyph in that glyph row area.
17283 X is the current output position assigned to the new glyph string
17284 constructed. HL overrides that face of the glyph; e.g. it is
17285 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17286 x-position of the drawing area. */
17287
17288 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17289 do { \
17290 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17291 int face_id = (row)->glyphs[area][START].face_id; \
17292 struct face *base_face = FACE_FROM_ID (f, face_id); \
17293 struct composition *cmp = composition_table[cmp_id]; \
17294 int glyph_len = cmp->glyph_len; \
17295 XChar2b *char2b; \
17296 struct face **faces; \
17297 struct glyph_string *first_s = NULL; \
17298 int n; \
17299 \
17300 base_face = base_face->ascii_face; \
17301 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17302 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17303 /* At first, fill in `char2b' and `faces'. */ \
17304 for (n = 0; n < glyph_len; n++) \
17305 { \
17306 int c = COMPOSITION_GLYPH (cmp, n); \
17307 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17308 faces[n] = FACE_FROM_ID (f, this_face_id); \
17309 get_char_face_and_encoding (f, c, this_face_id, \
17310 char2b + n, 1, 1); \
17311 } \
17312 \
17313 /* Make glyph_strings for each glyph sequence that is drawable by \
17314 the same face, and append them to HEAD/TAIL. */ \
17315 for (n = 0; n < cmp->glyph_len;) \
17316 { \
17317 s = (struct glyph_string *) alloca (sizeof *s); \
17318 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17319 append_glyph_string (&(HEAD), &(TAIL), s); \
17320 s->cmp = cmp; \
17321 s->gidx = n; \
17322 s->x = (X); \
17323 \
17324 if (n == 0) \
17325 first_s = s; \
17326 \
17327 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17328 } \
17329 \
17330 ++START; \
17331 s = first_s; \
17332 } while (0)
17333
17334
17335 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17336 of AREA of glyph row ROW on window W between indices START and END.
17337 HL overrides the face for drawing glyph strings, e.g. it is
17338 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17339 x-positions of the drawing area.
17340
17341 This is an ugly monster macro construct because we must use alloca
17342 to allocate glyph strings (because draw_glyphs can be called
17343 asynchronously). */
17344
17345 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17346 do \
17347 { \
17348 HEAD = TAIL = NULL; \
17349 while (START < END) \
17350 { \
17351 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17352 switch (first_glyph->type) \
17353 { \
17354 case CHAR_GLYPH: \
17355 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17356 HL, X, LAST_X); \
17357 break; \
17358 \
17359 case COMPOSITE_GLYPH: \
17360 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17361 HL, X, LAST_X); \
17362 break; \
17363 \
17364 case STRETCH_GLYPH: \
17365 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17366 HL, X, LAST_X); \
17367 break; \
17368 \
17369 case IMAGE_GLYPH: \
17370 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17371 HL, X, LAST_X); \
17372 break; \
17373 \
17374 default: \
17375 abort (); \
17376 } \
17377 \
17378 set_glyph_string_background_width (s, START, LAST_X); \
17379 (X) += s->width; \
17380 } \
17381 } \
17382 while (0)
17383
17384
17385 /* Draw glyphs between START and END in AREA of ROW on window W,
17386 starting at x-position X. X is relative to AREA in W. HL is a
17387 face-override with the following meaning:
17388
17389 DRAW_NORMAL_TEXT draw normally
17390 DRAW_CURSOR draw in cursor face
17391 DRAW_MOUSE_FACE draw in mouse face.
17392 DRAW_INVERSE_VIDEO draw in mode line face
17393 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17394 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17395
17396 If OVERLAPS_P is non-zero, draw only the foreground of characters
17397 and clip to the physical height of ROW.
17398
17399 Value is the x-position reached, relative to AREA of W. */
17400
17401 static int
17402 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17403 struct window *w;
17404 int x;
17405 struct glyph_row *row;
17406 enum glyph_row_area area;
17407 int start, end;
17408 enum draw_glyphs_face hl;
17409 int overlaps_p;
17410 {
17411 struct glyph_string *head, *tail;
17412 struct glyph_string *s;
17413 int last_x, area_width;
17414 int x_reached;
17415 int i, j;
17416 struct frame *f = XFRAME (WINDOW_FRAME (w));
17417 DECLARE_HDC (hdc);
17418
17419 ALLOCATE_HDC (hdc, f);
17420
17421 /* Let's rather be paranoid than getting a SEGV. */
17422 end = min (end, row->used[area]);
17423 start = max (0, start);
17424 start = min (end, start);
17425
17426 /* Translate X to frame coordinates. Set last_x to the right
17427 end of the drawing area. */
17428 if (row->full_width_p)
17429 {
17430 /* X is relative to the left edge of W, without scroll bars
17431 or fringes. */
17432 x += WINDOW_LEFT_EDGE_X (w);
17433 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17434 }
17435 else
17436 {
17437 int area_left = window_box_left (w, area);
17438 x += area_left;
17439 area_width = window_box_width (w, area);
17440 last_x = area_left + area_width;
17441 }
17442
17443 /* Build a doubly-linked list of glyph_string structures between
17444 head and tail from what we have to draw. Note that the macro
17445 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17446 the reason we use a separate variable `i'. */
17447 i = start;
17448 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17449 if (tail)
17450 x_reached = tail->x + tail->background_width;
17451 else
17452 x_reached = x;
17453
17454 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17455 the row, redraw some glyphs in front or following the glyph
17456 strings built above. */
17457 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17458 {
17459 int dummy_x = 0;
17460 struct glyph_string *h, *t;
17461
17462 /* Compute overhangs for all glyph strings. */
17463 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
17464 for (s = head; s; s = s->next)
17465 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
17466
17467 /* Prepend glyph strings for glyphs in front of the first glyph
17468 string that are overwritten because of the first glyph
17469 string's left overhang. The background of all strings
17470 prepended must be drawn because the first glyph string
17471 draws over it. */
17472 i = left_overwritten (head);
17473 if (i >= 0)
17474 {
17475 j = i;
17476 BUILD_GLYPH_STRINGS (j, start, h, t,
17477 DRAW_NORMAL_TEXT, dummy_x, last_x);
17478 start = i;
17479 compute_overhangs_and_x (t, head->x, 1);
17480 prepend_glyph_string_lists (&head, &tail, h, t);
17481 }
17482
17483 /* Prepend glyph strings for glyphs in front of the first glyph
17484 string that overwrite that glyph string because of their
17485 right overhang. For these strings, only the foreground must
17486 be drawn, because it draws over the glyph string at `head'.
17487 The background must not be drawn because this would overwrite
17488 right overhangs of preceding glyphs for which no glyph
17489 strings exist. */
17490 i = left_overwriting (head);
17491 if (i >= 0)
17492 {
17493 BUILD_GLYPH_STRINGS (i, start, h, t,
17494 DRAW_NORMAL_TEXT, dummy_x, last_x);
17495 for (s = h; s; s = s->next)
17496 s->background_filled_p = 1;
17497 compute_overhangs_and_x (t, head->x, 1);
17498 prepend_glyph_string_lists (&head, &tail, h, t);
17499 }
17500
17501 /* Append glyphs strings for glyphs following the last glyph
17502 string tail that are overwritten by tail. The background of
17503 these strings has to be drawn because tail's foreground draws
17504 over it. */
17505 i = right_overwritten (tail);
17506 if (i >= 0)
17507 {
17508 BUILD_GLYPH_STRINGS (end, i, h, t,
17509 DRAW_NORMAL_TEXT, x, last_x);
17510 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17511 append_glyph_string_lists (&head, &tail, h, t);
17512 }
17513
17514 /* Append glyph strings for glyphs following the last glyph
17515 string tail that overwrite tail. The foreground of such
17516 glyphs has to be drawn because it writes into the background
17517 of tail. The background must not be drawn because it could
17518 paint over the foreground of following glyphs. */
17519 i = right_overwriting (tail);
17520 if (i >= 0)
17521 {
17522 BUILD_GLYPH_STRINGS (end, i, h, t,
17523 DRAW_NORMAL_TEXT, x, last_x);
17524 for (s = h; s; s = s->next)
17525 s->background_filled_p = 1;
17526 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17527 append_glyph_string_lists (&head, &tail, h, t);
17528 }
17529 }
17530
17531 /* Draw all strings. */
17532 for (s = head; s; s = s->next)
17533 FRAME_RIF (f)->draw_glyph_string (s);
17534
17535 if (area == TEXT_AREA
17536 && !row->full_width_p
17537 /* When drawing overlapping rows, only the glyph strings'
17538 foreground is drawn, which doesn't erase a cursor
17539 completely. */
17540 && !overlaps_p)
17541 {
17542 int x0 = head ? head->x : x;
17543 int x1 = tail ? tail->x + tail->background_width : x;
17544
17545 int text_left = window_box_left (w, TEXT_AREA);
17546 x0 -= text_left;
17547 x1 -= text_left;
17548
17549 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
17550 row->y, MATRIX_ROW_BOTTOM_Y (row));
17551 }
17552
17553 /* Value is the x-position up to which drawn, relative to AREA of W.
17554 This doesn't include parts drawn because of overhangs. */
17555 if (row->full_width_p)
17556 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17557 else
17558 x_reached -= window_box_left (w, area);
17559
17560 RELEASE_HDC (hdc, f);
17561
17562 return x_reached;
17563 }
17564
17565
17566 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17567 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17568
17569 static INLINE void
17570 append_glyph (it)
17571 struct it *it;
17572 {
17573 struct glyph *glyph;
17574 enum glyph_row_area area = it->area;
17575
17576 xassert (it->glyph_row);
17577 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17578
17579 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17580 if (glyph < it->glyph_row->glyphs[area + 1])
17581 {
17582 glyph->charpos = CHARPOS (it->position);
17583 glyph->object = it->object;
17584 glyph->pixel_width = it->pixel_width;
17585 glyph->ascent = it->ascent;
17586 glyph->descent = it->descent;
17587 glyph->voffset = it->voffset;
17588 glyph->type = CHAR_GLYPH;
17589 glyph->multibyte_p = it->multibyte_p;
17590 glyph->left_box_line_p = it->start_of_box_run_p;
17591 glyph->right_box_line_p = it->end_of_box_run_p;
17592 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17593 || it->phys_descent > it->descent);
17594 glyph->padding_p = 0;
17595 glyph->glyph_not_available_p = it->glyph_not_available_p;
17596 glyph->face_id = it->face_id;
17597 glyph->u.ch = it->char_to_display;
17598 glyph->font_type = FONT_TYPE_UNKNOWN;
17599 ++it->glyph_row->used[area];
17600 }
17601 }
17602
17603 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17604 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17605
17606 static INLINE void
17607 append_composite_glyph (it)
17608 struct it *it;
17609 {
17610 struct glyph *glyph;
17611 enum glyph_row_area area = it->area;
17612
17613 xassert (it->glyph_row);
17614
17615 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17616 if (glyph < it->glyph_row->glyphs[area + 1])
17617 {
17618 glyph->charpos = CHARPOS (it->position);
17619 glyph->object = it->object;
17620 glyph->pixel_width = it->pixel_width;
17621 glyph->ascent = it->ascent;
17622 glyph->descent = it->descent;
17623 glyph->voffset = it->voffset;
17624 glyph->type = COMPOSITE_GLYPH;
17625 glyph->multibyte_p = it->multibyte_p;
17626 glyph->left_box_line_p = it->start_of_box_run_p;
17627 glyph->right_box_line_p = it->end_of_box_run_p;
17628 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17629 || it->phys_descent > it->descent);
17630 glyph->padding_p = 0;
17631 glyph->glyph_not_available_p = 0;
17632 glyph->face_id = it->face_id;
17633 glyph->u.cmp_id = it->cmp_id;
17634 glyph->font_type = FONT_TYPE_UNKNOWN;
17635 ++it->glyph_row->used[area];
17636 }
17637 }
17638
17639
17640 /* Change IT->ascent and IT->height according to the setting of
17641 IT->voffset. */
17642
17643 static INLINE void
17644 take_vertical_position_into_account (it)
17645 struct it *it;
17646 {
17647 if (it->voffset)
17648 {
17649 if (it->voffset < 0)
17650 /* Increase the ascent so that we can display the text higher
17651 in the line. */
17652 it->ascent += abs (it->voffset);
17653 else
17654 /* Increase the descent so that we can display the text lower
17655 in the line. */
17656 it->descent += it->voffset;
17657 }
17658 }
17659
17660
17661 /* Produce glyphs/get display metrics for the image IT is loaded with.
17662 See the description of struct display_iterator in dispextern.h for
17663 an overview of struct display_iterator. */
17664
17665 static void
17666 produce_image_glyph (it)
17667 struct it *it;
17668 {
17669 struct image *img;
17670 struct face *face;
17671 int face_ascent, glyph_ascent;
17672
17673 xassert (it->what == IT_IMAGE);
17674
17675 face = FACE_FROM_ID (it->f, it->face_id);
17676 img = IMAGE_FROM_ID (it->f, it->image_id);
17677 xassert (img);
17678
17679 /* Make sure X resources of the face and image are loaded. */
17680 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17681 prepare_image_for_display (it->f, img);
17682
17683 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
17684 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17685 it->pixel_width = img->width + 2 * img->hmargin;
17686
17687 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
17688 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
17689 if (face_ascent > it->ascent)
17690 it->ascent = it->phys_ascent = face_ascent;
17691
17692 it->nglyphs = 1;
17693
17694 if (face->box != FACE_NO_BOX)
17695 {
17696 if (face->box_line_width > 0)
17697 {
17698 it->ascent += face->box_line_width;
17699 it->descent += face->box_line_width;
17700 }
17701
17702 if (it->start_of_box_run_p)
17703 it->pixel_width += abs (face->box_line_width);
17704 if (it->end_of_box_run_p)
17705 it->pixel_width += abs (face->box_line_width);
17706 }
17707
17708 take_vertical_position_into_account (it);
17709
17710 if (it->glyph_row)
17711 {
17712 struct glyph *glyph;
17713 enum glyph_row_area area = it->area;
17714
17715 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17716 if (glyph < it->glyph_row->glyphs[area + 1])
17717 {
17718 glyph->charpos = CHARPOS (it->position);
17719 glyph->object = it->object;
17720 glyph->pixel_width = it->pixel_width;
17721 glyph->ascent = glyph_ascent;
17722 glyph->descent = it->descent;
17723 glyph->voffset = it->voffset;
17724 glyph->type = IMAGE_GLYPH;
17725 glyph->multibyte_p = it->multibyte_p;
17726 glyph->left_box_line_p = it->start_of_box_run_p;
17727 glyph->right_box_line_p = it->end_of_box_run_p;
17728 glyph->overlaps_vertically_p = 0;
17729 glyph->padding_p = 0;
17730 glyph->glyph_not_available_p = 0;
17731 glyph->face_id = it->face_id;
17732 glyph->u.img_id = img->id;
17733 glyph->font_type = FONT_TYPE_UNKNOWN;
17734 ++it->glyph_row->used[area];
17735 }
17736 }
17737 }
17738
17739
17740 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17741 of the glyph, WIDTH and HEIGHT are the width and height of the
17742 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17743
17744 static void
17745 append_stretch_glyph (it, object, width, height, ascent)
17746 struct it *it;
17747 Lisp_Object object;
17748 int width, height;
17749 int ascent;
17750 {
17751 struct glyph *glyph;
17752 enum glyph_row_area area = it->area;
17753
17754 xassert (ascent >= 0 && ascent <= height);
17755
17756 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17757 if (glyph < it->glyph_row->glyphs[area + 1])
17758 {
17759 glyph->charpos = CHARPOS (it->position);
17760 glyph->object = object;
17761 glyph->pixel_width = width;
17762 glyph->ascent = ascent;
17763 glyph->descent = height - ascent;
17764 glyph->voffset = it->voffset;
17765 glyph->type = STRETCH_GLYPH;
17766 glyph->multibyte_p = it->multibyte_p;
17767 glyph->left_box_line_p = it->start_of_box_run_p;
17768 glyph->right_box_line_p = it->end_of_box_run_p;
17769 glyph->overlaps_vertically_p = 0;
17770 glyph->padding_p = 0;
17771 glyph->glyph_not_available_p = 0;
17772 glyph->face_id = it->face_id;
17773 glyph->u.stretch.ascent = ascent;
17774 glyph->u.stretch.height = height;
17775 glyph->font_type = FONT_TYPE_UNKNOWN;
17776 ++it->glyph_row->used[area];
17777 }
17778 }
17779
17780
17781 /* Calculate a width or height in pixels from a specification using
17782 the following elements:
17783
17784 SPEC ::=
17785 NUM - a (fractional) multiple of the default font width/height
17786 (NUM) - specifies exactly NUM pixels
17787 UNIT - a fixed number of pixels, see below.
17788 ELEMENT - size of a display element in pixels, see below.
17789 (NUM . SPEC) - equals NUM * SPEC
17790 (+ SPEC SPEC ...) - add pixel values
17791 (- SPEC SPEC ...) - subtract pixel values
17792 (- SPEC) - negate pixel value
17793
17794 NUM ::=
17795 INT or FLOAT - a number constant
17796 SYMBOL - use symbol's (buffer local) variable binding.
17797
17798 UNIT ::=
17799 in - pixels per inch *)
17800 mm - pixels per 1/1000 meter *)
17801 cm - pixels per 1/100 meter *)
17802 width - width of current font in pixels.
17803 height - height of current font in pixels.
17804
17805 *) using the ratio(s) defined in display-pixels-per-inch.
17806
17807 ELEMENT ::=
17808
17809 left-fringe - left fringe width in pixels
17810 (left-fringe . nil) - left fringe width if inside margins, else 0
17811 (left-fringe . t) - left fringe width if outside margins, else 0
17812
17813 right-fringe - right fringe width in pixels
17814 (right-fringe . nil) - right fringe width if inside margins, else 0
17815 (right-fringe . t) - right fringe width if outside margins, else 0
17816
17817 left-margin - left margin width in pixels
17818 right-margin - right margin width in pixels
17819
17820 scroll-bar - scroll-bar area width in pixels
17821 (scroll-bar . left) - scroll-bar width if on left, else 0
17822 (scroll-bar . right) - scroll-bar width if on right, else 0
17823
17824 Examples:
17825
17826 Pixels corresponding to 5 inches:
17827 (5 . in)
17828
17829 Total width of non-text areas on left side of window:
17830 (+ left-fringe left-margin (scroll-bar . left))
17831
17832 Total width of fringes if inside display margins:
17833 (+ (left-fringe) (right-fringe))
17834
17835 Width of left margin minus width of 1 character in the default font:
17836 (- left-margin 1)
17837
17838 Width of left margin minus width of 2 characters in the current font:
17839 (- left-margin (2 . width))
17840
17841 Width of left fringe plus left margin minus one pixel:
17842 (- (+ left-fringe left-margin) (1))
17843 (+ left-fringe left-margin (- (1)))
17844 (+ left-fringe left-margin (-1))
17845
17846 */
17847
17848 #define NUMVAL(X) \
17849 ((INTEGERP (X) || FLOATP (X)) \
17850 ? XFLOATINT (X) \
17851 : - 1)
17852
17853 static int
17854 calc_pixel_width_or_height (res, it, prop, font, width_p)
17855 double *res;
17856 struct it *it;
17857 Lisp_Object prop;
17858 XFontStruct *font;
17859 int width_p;
17860 {
17861 double pixels;
17862
17863 #define OK_PIXELS(val) ((*res = (val)), 1)
17864
17865 if (SYMBOLP (prop))
17866 {
17867 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17868 {
17869 char *unit = SDATA (SYMBOL_NAME (prop));
17870
17871 if (unit[0] == 'i' && unit[1] == 'n')
17872 pixels = 1.0;
17873 else if (unit[0] == 'm' && unit[1] == 'm')
17874 pixels = 25.4;
17875 else if (unit[0] == 'c' && unit[1] == 'm')
17876 pixels = 2.54;
17877 else
17878 pixels = 0;
17879 if (pixels > 0)
17880 {
17881 double ppi;
17882 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17883 || (CONSP (Vdisplay_pixels_per_inch)
17884 && (ppi = (width_p
17885 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17886 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17887 ppi > 0)))
17888 return OK_PIXELS (ppi / pixels);
17889
17890 return 0;
17891 }
17892 }
17893
17894 if (EQ (prop, Qheight))
17895 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
17896 if (EQ (prop, Qwidth))
17897 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
17898 if (EQ (prop, Qleft_fringe))
17899 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17900 if (EQ (prop, Qright_fringe))
17901 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17902 if (EQ (prop, Qleft_margin))
17903 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17904 if (EQ (prop, Qright_margin))
17905 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17906 if (EQ (prop, Qscroll_bar))
17907 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17908
17909 prop = Fbuffer_local_value (prop, it->w->buffer);
17910 }
17911
17912 if (INTEGERP (prop) || FLOATP (prop))
17913 {
17914 int base_unit = (width_p
17915 ? FRAME_COLUMN_WIDTH (it->f)
17916 : FRAME_LINE_HEIGHT (it->f));
17917 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17918 }
17919
17920 if (CONSP (prop))
17921 {
17922 Lisp_Object car = XCAR (prop);
17923 Lisp_Object cdr = XCDR (prop);
17924
17925 if (SYMBOLP (car))
17926 {
17927 if (EQ (car, Qplus) || EQ (car, Qminus))
17928 {
17929 int first = 1;
17930 double px;
17931
17932 pixels = 0;
17933 while (CONSP (cdr))
17934 {
17935 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), font, width_p))
17936 return 0;
17937 if (first)
17938 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17939 else
17940 pixels += px;
17941 cdr = XCDR (cdr);
17942 }
17943 if (EQ (car, Qminus))
17944 pixels = -pixels;
17945 return OK_PIXELS (pixels);
17946 }
17947
17948 if (EQ (car, Qleft_fringe))
17949 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17950 == !NILP (cdr))
17951 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
17952 : 0);
17953 if (EQ (car, Qright_fringe))
17954 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17955 == !NILP (cdr))
17956 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17957 : 0);
17958 if (EQ (car, Qscroll_bar))
17959 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17960 == EQ (cdr, Qleft))
17961 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)
17962 : 0);
17963
17964 car = Fbuffer_local_value (car, it->w->buffer);
17965 }
17966
17967 if (INTEGERP (car) || FLOATP (car))
17968 {
17969 double fact;
17970 pixels = XFLOATINT (car);
17971 if (NILP (cdr))
17972 return OK_PIXELS (pixels);
17973 if (calc_pixel_width_or_height (&fact, it, cdr, font, width_p))
17974 return OK_PIXELS (pixels * fact);
17975 return 0;
17976 }
17977
17978 return 0;
17979 }
17980
17981 return 0;
17982 }
17983
17984 /* Produce a stretch glyph for iterator IT. IT->object is the value
17985 of the glyph property displayed. The value must be a list
17986 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17987 being recognized:
17988
17989 1. `:width WIDTH' specifies that the space should be WIDTH *
17990 canonical char width wide. WIDTH may be an integer or floating
17991 point number.
17992
17993 2. `:relative-width FACTOR' specifies that the width of the stretch
17994 should be computed from the width of the first character having the
17995 `glyph' property, and should be FACTOR times that width.
17996
17997 3. `:align-to HPOS' specifies that the space should be wide enough
17998 to reach HPOS, a value in canonical character units.
17999
18000 Exactly one of the above pairs must be present.
18001
18002 4. `:height HEIGHT' specifies that the height of the stretch produced
18003 should be HEIGHT, measured in canonical character units.
18004
18005 5. `:relative-height FACTOR' specifies that the height of the
18006 stretch should be FACTOR times the height of the characters having
18007 the glyph property.
18008
18009 Either none or exactly one of 4 or 5 must be present.
18010
18011 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18012 of the stretch should be used for the ascent of the stretch.
18013 ASCENT must be in the range 0 <= ASCENT <= 100. */
18014
18015 static void
18016 produce_stretch_glyph (it)
18017 struct it *it;
18018 {
18019 /* (space :width WIDTH :height HEIGHT ...) */
18020 Lisp_Object prop, plist;
18021 int width = 0, height = 0;
18022 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18023 int ascent = 0;
18024 double tem;
18025 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18026 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18027
18028 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18029
18030 /* List should start with `space'. */
18031 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18032 plist = XCDR (it->object);
18033
18034 /* Compute the width of the stretch. */
18035 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18036 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18037 {
18038 /* Absolute width `:width WIDTH' specified and valid. */
18039 zero_width_ok_p = 1;
18040 width = (int)tem;
18041 }
18042 else if (prop = Fplist_get (plist, QCrelative_width),
18043 NUMVAL (prop) > 0)
18044 {
18045 /* Relative width `:relative-width FACTOR' specified and valid.
18046 Compute the width of the characters having the `glyph'
18047 property. */
18048 struct it it2;
18049 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18050
18051 it2 = *it;
18052 if (it->multibyte_p)
18053 {
18054 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18055 - IT_BYTEPOS (*it));
18056 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18057 }
18058 else
18059 it2.c = *p, it2.len = 1;
18060
18061 it2.glyph_row = NULL;
18062 it2.what = IT_CHARACTER;
18063 x_produce_glyphs (&it2);
18064 width = NUMVAL (prop) * it2.pixel_width;
18065 }
18066 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18067 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18068 {
18069 width = max (0, (int)tem - it->current_x);
18070 zero_width_ok_p = 1;
18071 }
18072 else
18073 /* Nothing specified -> width defaults to canonical char width. */
18074 width = FRAME_COLUMN_WIDTH (it->f);
18075
18076 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18077 width = 1;
18078
18079 /* Compute height. */
18080 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18081 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18082 {
18083 height = (int)tem;
18084 zero_height_ok_p = 1;
18085 }
18086 else if (prop = Fplist_get (plist, QCrelative_height),
18087 NUMVAL (prop) > 0)
18088 height = FONT_HEIGHT (font) * NUMVAL (prop);
18089 else
18090 height = FONT_HEIGHT (font);
18091
18092 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18093 height = 1;
18094
18095 /* Compute percentage of height used for ascent. If
18096 `:ascent ASCENT' is present and valid, use that. Otherwise,
18097 derive the ascent from the font in use. */
18098 if (prop = Fplist_get (plist, QCascent),
18099 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18100 ascent = height * NUMVAL (prop) / 100.0;
18101 else if (!NILP (prop)
18102 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18103 ascent = min (max (0, (int)tem), height);
18104 else
18105 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18106
18107 if (width > 0 && height > 0 && it->glyph_row)
18108 {
18109 Lisp_Object object = it->stack[it->sp - 1].string;
18110 if (!STRINGP (object))
18111 object = it->w->buffer;
18112 append_stretch_glyph (it, object, width, height, ascent);
18113 }
18114
18115 it->pixel_width = width;
18116 it->ascent = it->phys_ascent = ascent;
18117 it->descent = it->phys_descent = height - it->ascent;
18118 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18119
18120 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18121 {
18122 if (face->box_line_width > 0)
18123 {
18124 it->ascent += face->box_line_width;
18125 it->descent += face->box_line_width;
18126 }
18127
18128 if (it->start_of_box_run_p)
18129 it->pixel_width += abs (face->box_line_width);
18130 if (it->end_of_box_run_p)
18131 it->pixel_width += abs (face->box_line_width);
18132 }
18133
18134 take_vertical_position_into_account (it);
18135 }
18136
18137 /* RIF:
18138 Produce glyphs/get display metrics for the display element IT is
18139 loaded with. See the description of struct display_iterator in
18140 dispextern.h for an overview of struct display_iterator. */
18141
18142 void
18143 x_produce_glyphs (it)
18144 struct it *it;
18145 {
18146 it->glyph_not_available_p = 0;
18147
18148 if (it->what == IT_CHARACTER)
18149 {
18150 XChar2b char2b;
18151 XFontStruct *font;
18152 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18153 XCharStruct *pcm;
18154 int font_not_found_p;
18155 struct font_info *font_info;
18156 int boff; /* baseline offset */
18157 /* We may change it->multibyte_p upon unibyte<->multibyte
18158 conversion. So, save the current value now and restore it
18159 later.
18160
18161 Note: It seems that we don't have to record multibyte_p in
18162 struct glyph because the character code itself tells if or
18163 not the character is multibyte. Thus, in the future, we must
18164 consider eliminating the field `multibyte_p' in the struct
18165 glyph. */
18166 int saved_multibyte_p = it->multibyte_p;
18167
18168 /* Maybe translate single-byte characters to multibyte, or the
18169 other way. */
18170 it->char_to_display = it->c;
18171 if (!ASCII_BYTE_P (it->c))
18172 {
18173 if (unibyte_display_via_language_environment
18174 && SINGLE_BYTE_CHAR_P (it->c)
18175 && (it->c >= 0240
18176 || !NILP (Vnonascii_translation_table)))
18177 {
18178 it->char_to_display = unibyte_char_to_multibyte (it->c);
18179 it->multibyte_p = 1;
18180 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18181 face = FACE_FROM_ID (it->f, it->face_id);
18182 }
18183 else if (!SINGLE_BYTE_CHAR_P (it->c)
18184 && !it->multibyte_p)
18185 {
18186 it->multibyte_p = 1;
18187 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18188 face = FACE_FROM_ID (it->f, it->face_id);
18189 }
18190 }
18191
18192 /* Get font to use. Encode IT->char_to_display. */
18193 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18194 &char2b, it->multibyte_p, 0);
18195 font = face->font;
18196
18197 /* When no suitable font found, use the default font. */
18198 font_not_found_p = font == NULL;
18199 if (font_not_found_p)
18200 {
18201 font = FRAME_FONT (it->f);
18202 boff = FRAME_BASELINE_OFFSET (it->f);
18203 font_info = NULL;
18204 }
18205 else
18206 {
18207 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18208 boff = font_info->baseline_offset;
18209 if (font_info->vertical_centering)
18210 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18211 }
18212
18213 if (it->char_to_display >= ' '
18214 && (!it->multibyte_p || it->char_to_display < 128))
18215 {
18216 /* Either unibyte or ASCII. */
18217 int stretched_p;
18218
18219 it->nglyphs = 1;
18220
18221 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18222 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18223 it->ascent = FONT_BASE (font) + boff;
18224 it->descent = FONT_DESCENT (font) - boff;
18225
18226 if (pcm)
18227 {
18228 it->phys_ascent = pcm->ascent + boff;
18229 it->phys_descent = pcm->descent - boff;
18230 it->pixel_width = pcm->width;
18231 }
18232 else
18233 {
18234 it->glyph_not_available_p = 1;
18235 it->phys_ascent = FONT_BASE (font) + boff;
18236 it->phys_descent = FONT_DESCENT (font) - boff;
18237 it->pixel_width = FONT_WIDTH (font);
18238 }
18239
18240 /* If this is a space inside a region of text with
18241 `space-width' property, change its width. */
18242 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18243 if (stretched_p)
18244 it->pixel_width *= XFLOATINT (it->space_width);
18245
18246 /* If face has a box, add the box thickness to the character
18247 height. If character has a box line to the left and/or
18248 right, add the box line width to the character's width. */
18249 if (face->box != FACE_NO_BOX)
18250 {
18251 int thick = face->box_line_width;
18252
18253 if (thick > 0)
18254 {
18255 it->ascent += thick;
18256 it->descent += thick;
18257 }
18258 else
18259 thick = -thick;
18260
18261 if (it->start_of_box_run_p)
18262 it->pixel_width += thick;
18263 if (it->end_of_box_run_p)
18264 it->pixel_width += thick;
18265 }
18266
18267 /* If face has an overline, add the height of the overline
18268 (1 pixel) and a 1 pixel margin to the character height. */
18269 if (face->overline_p)
18270 it->ascent += 2;
18271
18272 take_vertical_position_into_account (it);
18273
18274 /* If we have to actually produce glyphs, do it. */
18275 if (it->glyph_row)
18276 {
18277 if (stretched_p)
18278 {
18279 /* Translate a space with a `space-width' property
18280 into a stretch glyph. */
18281 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18282 / FONT_HEIGHT (font));
18283 append_stretch_glyph (it, it->object, it->pixel_width,
18284 it->ascent + it->descent, ascent);
18285 }
18286 else
18287 append_glyph (it);
18288
18289 /* If characters with lbearing or rbearing are displayed
18290 in this line, record that fact in a flag of the
18291 glyph row. This is used to optimize X output code. */
18292 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18293 it->glyph_row->contains_overlapping_glyphs_p = 1;
18294 }
18295 }
18296 else if (it->char_to_display == '\n')
18297 {
18298 /* A newline has no width but we need the height of the line. */
18299 it->pixel_width = 0;
18300 it->nglyphs = 0;
18301 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18302 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18303
18304 if (face->box != FACE_NO_BOX
18305 && face->box_line_width > 0)
18306 {
18307 it->ascent += face->box_line_width;
18308 it->descent += face->box_line_width;
18309 }
18310 }
18311 else if (it->char_to_display == '\t')
18312 {
18313 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18314 int x = it->current_x + it->continuation_lines_width;
18315 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18316
18317 /* If the distance from the current position to the next tab
18318 stop is less than a canonical character width, use the
18319 tab stop after that. */
18320 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18321 next_tab_x += tab_width;
18322
18323 it->pixel_width = next_tab_x - x;
18324 it->nglyphs = 1;
18325 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18326 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18327
18328 if (it->glyph_row)
18329 {
18330 append_stretch_glyph (it, it->object, it->pixel_width,
18331 it->ascent + it->descent, it->ascent);
18332 }
18333 }
18334 else
18335 {
18336 /* A multi-byte character. Assume that the display width of the
18337 character is the width of the character multiplied by the
18338 width of the font. */
18339
18340 /* If we found a font, this font should give us the right
18341 metrics. If we didn't find a font, use the frame's
18342 default font and calculate the width of the character
18343 from the charset width; this is what old redisplay code
18344 did. */
18345
18346 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18347 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18348
18349 if (font_not_found_p || !pcm)
18350 {
18351 int charset = CHAR_CHARSET (it->char_to_display);
18352
18353 it->glyph_not_available_p = 1;
18354 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18355 * CHARSET_WIDTH (charset));
18356 it->phys_ascent = FONT_BASE (font) + boff;
18357 it->phys_descent = FONT_DESCENT (font) - boff;
18358 }
18359 else
18360 {
18361 it->pixel_width = pcm->width;
18362 it->phys_ascent = pcm->ascent + boff;
18363 it->phys_descent = pcm->descent - boff;
18364 if (it->glyph_row
18365 && (pcm->lbearing < 0
18366 || pcm->rbearing > pcm->width))
18367 it->glyph_row->contains_overlapping_glyphs_p = 1;
18368 }
18369 it->nglyphs = 1;
18370 it->ascent = FONT_BASE (font) + boff;
18371 it->descent = FONT_DESCENT (font) - boff;
18372 if (face->box != FACE_NO_BOX)
18373 {
18374 int thick = face->box_line_width;
18375
18376 if (thick > 0)
18377 {
18378 it->ascent += thick;
18379 it->descent += thick;
18380 }
18381 else
18382 thick = - thick;
18383
18384 if (it->start_of_box_run_p)
18385 it->pixel_width += thick;
18386 if (it->end_of_box_run_p)
18387 it->pixel_width += thick;
18388 }
18389
18390 /* If face has an overline, add the height of the overline
18391 (1 pixel) and a 1 pixel margin to the character height. */
18392 if (face->overline_p)
18393 it->ascent += 2;
18394
18395 take_vertical_position_into_account (it);
18396
18397 if (it->glyph_row)
18398 append_glyph (it);
18399 }
18400 it->multibyte_p = saved_multibyte_p;
18401 }
18402 else if (it->what == IT_COMPOSITION)
18403 {
18404 /* Note: A composition is represented as one glyph in the
18405 glyph matrix. There are no padding glyphs. */
18406 XChar2b char2b;
18407 XFontStruct *font;
18408 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18409 XCharStruct *pcm;
18410 int font_not_found_p;
18411 struct font_info *font_info;
18412 int boff; /* baseline offset */
18413 struct composition *cmp = composition_table[it->cmp_id];
18414
18415 /* Maybe translate single-byte characters to multibyte. */
18416 it->char_to_display = it->c;
18417 if (unibyte_display_via_language_environment
18418 && SINGLE_BYTE_CHAR_P (it->c)
18419 && (it->c >= 0240
18420 || (it->c >= 0200
18421 && !NILP (Vnonascii_translation_table))))
18422 {
18423 it->char_to_display = unibyte_char_to_multibyte (it->c);
18424 }
18425
18426 /* Get face and font to use. Encode IT->char_to_display. */
18427 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18428 face = FACE_FROM_ID (it->f, it->face_id);
18429 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18430 &char2b, it->multibyte_p, 0);
18431 font = face->font;
18432
18433 /* When no suitable font found, use the default font. */
18434 font_not_found_p = font == NULL;
18435 if (font_not_found_p)
18436 {
18437 font = FRAME_FONT (it->f);
18438 boff = FRAME_BASELINE_OFFSET (it->f);
18439 font_info = NULL;
18440 }
18441 else
18442 {
18443 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18444 boff = font_info->baseline_offset;
18445 if (font_info->vertical_centering)
18446 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18447 }
18448
18449 /* There are no padding glyphs, so there is only one glyph to
18450 produce for the composition. Important is that pixel_width,
18451 ascent and descent are the values of what is drawn by
18452 draw_glyphs (i.e. the values of the overall glyphs composed). */
18453 it->nglyphs = 1;
18454
18455 /* If we have not yet calculated pixel size data of glyphs of
18456 the composition for the current face font, calculate them
18457 now. Theoretically, we have to check all fonts for the
18458 glyphs, but that requires much time and memory space. So,
18459 here we check only the font of the first glyph. This leads
18460 to incorrect display very rarely, and C-l (recenter) can
18461 correct the display anyway. */
18462 if (cmp->font != (void *) font)
18463 {
18464 /* Ascent and descent of the font of the first character of
18465 this composition (adjusted by baseline offset). Ascent
18466 and descent of overall glyphs should not be less than
18467 them respectively. */
18468 int font_ascent = FONT_BASE (font) + boff;
18469 int font_descent = FONT_DESCENT (font) - boff;
18470 /* Bounding box of the overall glyphs. */
18471 int leftmost, rightmost, lowest, highest;
18472 int i, width, ascent, descent;
18473
18474 cmp->font = (void *) font;
18475
18476 /* Initialize the bounding box. */
18477 if (font_info
18478 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18479 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18480 {
18481 width = pcm->width;
18482 ascent = pcm->ascent;
18483 descent = pcm->descent;
18484 }
18485 else
18486 {
18487 width = FONT_WIDTH (font);
18488 ascent = FONT_BASE (font);
18489 descent = FONT_DESCENT (font);
18490 }
18491
18492 rightmost = width;
18493 lowest = - descent + boff;
18494 highest = ascent + boff;
18495 leftmost = 0;
18496
18497 if (font_info
18498 && font_info->default_ascent
18499 && CHAR_TABLE_P (Vuse_default_ascent)
18500 && !NILP (Faref (Vuse_default_ascent,
18501 make_number (it->char_to_display))))
18502 highest = font_info->default_ascent + boff;
18503
18504 /* Draw the first glyph at the normal position. It may be
18505 shifted to right later if some other glyphs are drawn at
18506 the left. */
18507 cmp->offsets[0] = 0;
18508 cmp->offsets[1] = boff;
18509
18510 /* Set cmp->offsets for the remaining glyphs. */
18511 for (i = 1; i < cmp->glyph_len; i++)
18512 {
18513 int left, right, btm, top;
18514 int ch = COMPOSITION_GLYPH (cmp, i);
18515 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18516
18517 face = FACE_FROM_ID (it->f, face_id);
18518 get_char_face_and_encoding (it->f, ch, face->id,
18519 &char2b, it->multibyte_p, 0);
18520 font = face->font;
18521 if (font == NULL)
18522 {
18523 font = FRAME_FONT (it->f);
18524 boff = FRAME_BASELINE_OFFSET (it->f);
18525 font_info = NULL;
18526 }
18527 else
18528 {
18529 font_info
18530 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18531 boff = font_info->baseline_offset;
18532 if (font_info->vertical_centering)
18533 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18534 }
18535
18536 if (font_info
18537 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18538 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18539 {
18540 width = pcm->width;
18541 ascent = pcm->ascent;
18542 descent = pcm->descent;
18543 }
18544 else
18545 {
18546 width = FONT_WIDTH (font);
18547 ascent = 1;
18548 descent = 0;
18549 }
18550
18551 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18552 {
18553 /* Relative composition with or without
18554 alternate chars. */
18555 left = (leftmost + rightmost - width) / 2;
18556 btm = - descent + boff;
18557 if (font_info && font_info->relative_compose
18558 && (! CHAR_TABLE_P (Vignore_relative_composition)
18559 || NILP (Faref (Vignore_relative_composition,
18560 make_number (ch)))))
18561 {
18562
18563 if (- descent >= font_info->relative_compose)
18564 /* One extra pixel between two glyphs. */
18565 btm = highest + 1;
18566 else if (ascent <= 0)
18567 /* One extra pixel between two glyphs. */
18568 btm = lowest - 1 - ascent - descent;
18569 }
18570 }
18571 else
18572 {
18573 /* A composition rule is specified by an integer
18574 value that encodes global and new reference
18575 points (GREF and NREF). GREF and NREF are
18576 specified by numbers as below:
18577
18578 0---1---2 -- ascent
18579 | |
18580 | |
18581 | |
18582 9--10--11 -- center
18583 | |
18584 ---3---4---5--- baseline
18585 | |
18586 6---7---8 -- descent
18587 */
18588 int rule = COMPOSITION_RULE (cmp, i);
18589 int gref, nref, grefx, grefy, nrefx, nrefy;
18590
18591 COMPOSITION_DECODE_RULE (rule, gref, nref);
18592 grefx = gref % 3, nrefx = nref % 3;
18593 grefy = gref / 3, nrefy = nref / 3;
18594
18595 left = (leftmost
18596 + grefx * (rightmost - leftmost) / 2
18597 - nrefx * width / 2);
18598 btm = ((grefy == 0 ? highest
18599 : grefy == 1 ? 0
18600 : grefy == 2 ? lowest
18601 : (highest + lowest) / 2)
18602 - (nrefy == 0 ? ascent + descent
18603 : nrefy == 1 ? descent - boff
18604 : nrefy == 2 ? 0
18605 : (ascent + descent) / 2));
18606 }
18607
18608 cmp->offsets[i * 2] = left;
18609 cmp->offsets[i * 2 + 1] = btm + descent;
18610
18611 /* Update the bounding box of the overall glyphs. */
18612 right = left + width;
18613 top = btm + descent + ascent;
18614 if (left < leftmost)
18615 leftmost = left;
18616 if (right > rightmost)
18617 rightmost = right;
18618 if (top > highest)
18619 highest = top;
18620 if (btm < lowest)
18621 lowest = btm;
18622 }
18623
18624 /* If there are glyphs whose x-offsets are negative,
18625 shift all glyphs to the right and make all x-offsets
18626 non-negative. */
18627 if (leftmost < 0)
18628 {
18629 for (i = 0; i < cmp->glyph_len; i++)
18630 cmp->offsets[i * 2] -= leftmost;
18631 rightmost -= leftmost;
18632 }
18633
18634 cmp->pixel_width = rightmost;
18635 cmp->ascent = highest;
18636 cmp->descent = - lowest;
18637 if (cmp->ascent < font_ascent)
18638 cmp->ascent = font_ascent;
18639 if (cmp->descent < font_descent)
18640 cmp->descent = font_descent;
18641 }
18642
18643 it->pixel_width = cmp->pixel_width;
18644 it->ascent = it->phys_ascent = cmp->ascent;
18645 it->descent = it->phys_descent = cmp->descent;
18646
18647 if (face->box != FACE_NO_BOX)
18648 {
18649 int thick = face->box_line_width;
18650
18651 if (thick > 0)
18652 {
18653 it->ascent += thick;
18654 it->descent += thick;
18655 }
18656 else
18657 thick = - thick;
18658
18659 if (it->start_of_box_run_p)
18660 it->pixel_width += thick;
18661 if (it->end_of_box_run_p)
18662 it->pixel_width += thick;
18663 }
18664
18665 /* If face has an overline, add the height of the overline
18666 (1 pixel) and a 1 pixel margin to the character height. */
18667 if (face->overline_p)
18668 it->ascent += 2;
18669
18670 take_vertical_position_into_account (it);
18671
18672 if (it->glyph_row)
18673 append_composite_glyph (it);
18674 }
18675 else if (it->what == IT_IMAGE)
18676 produce_image_glyph (it);
18677 else if (it->what == IT_STRETCH)
18678 produce_stretch_glyph (it);
18679
18680 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18681 because this isn't true for images with `:ascent 100'. */
18682 xassert (it->ascent >= 0 && it->descent >= 0);
18683 if (it->area == TEXT_AREA)
18684 it->current_x += it->pixel_width;
18685
18686 it->descent += it->extra_line_spacing;
18687
18688 it->max_ascent = max (it->max_ascent, it->ascent);
18689 it->max_descent = max (it->max_descent, it->descent);
18690 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18691 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18692 }
18693
18694 /* EXPORT for RIF:
18695 Output LEN glyphs starting at START at the nominal cursor position.
18696 Advance the nominal cursor over the text. The global variable
18697 updated_window contains the window being updated, updated_row is
18698 the glyph row being updated, and updated_area is the area of that
18699 row being updated. */
18700
18701 void
18702 x_write_glyphs (start, len)
18703 struct glyph *start;
18704 int len;
18705 {
18706 int x, hpos;
18707
18708 xassert (updated_window && updated_row);
18709 BLOCK_INPUT;
18710
18711 /* Write glyphs. */
18712
18713 hpos = start - updated_row->glyphs[updated_area];
18714 x = draw_glyphs (updated_window, output_cursor.x,
18715 updated_row, updated_area,
18716 hpos, hpos + len,
18717 DRAW_NORMAL_TEXT, 0);
18718
18719 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18720 if (updated_area == TEXT_AREA
18721 && updated_window->phys_cursor_on_p
18722 && updated_window->phys_cursor.vpos == output_cursor.vpos
18723 && updated_window->phys_cursor.hpos >= hpos
18724 && updated_window->phys_cursor.hpos < hpos + len)
18725 updated_window->phys_cursor_on_p = 0;
18726
18727 UNBLOCK_INPUT;
18728
18729 /* Advance the output cursor. */
18730 output_cursor.hpos += len;
18731 output_cursor.x = x;
18732 }
18733
18734
18735 /* EXPORT for RIF:
18736 Insert LEN glyphs from START at the nominal cursor position. */
18737
18738 void
18739 x_insert_glyphs (start, len)
18740 struct glyph *start;
18741 int len;
18742 {
18743 struct frame *f;
18744 struct window *w;
18745 int line_height, shift_by_width, shifted_region_width;
18746 struct glyph_row *row;
18747 struct glyph *glyph;
18748 int frame_x, frame_y, hpos;
18749
18750 xassert (updated_window && updated_row);
18751 BLOCK_INPUT;
18752 w = updated_window;
18753 f = XFRAME (WINDOW_FRAME (w));
18754
18755 /* Get the height of the line we are in. */
18756 row = updated_row;
18757 line_height = row->height;
18758
18759 /* Get the width of the glyphs to insert. */
18760 shift_by_width = 0;
18761 for (glyph = start; glyph < start + len; ++glyph)
18762 shift_by_width += glyph->pixel_width;
18763
18764 /* Get the width of the region to shift right. */
18765 shifted_region_width = (window_box_width (w, updated_area)
18766 - output_cursor.x
18767 - shift_by_width);
18768
18769 /* Shift right. */
18770 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18771 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18772
18773 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18774 line_height, shift_by_width);
18775
18776 /* Write the glyphs. */
18777 hpos = start - row->glyphs[updated_area];
18778 draw_glyphs (w, output_cursor.x, row, updated_area,
18779 hpos, hpos + len,
18780 DRAW_NORMAL_TEXT, 0);
18781
18782 /* Advance the output cursor. */
18783 output_cursor.hpos += len;
18784 output_cursor.x += shift_by_width;
18785 UNBLOCK_INPUT;
18786 }
18787
18788
18789 /* EXPORT for RIF:
18790 Erase the current text line from the nominal cursor position
18791 (inclusive) to pixel column TO_X (exclusive). The idea is that
18792 everything from TO_X onward is already erased.
18793
18794 TO_X is a pixel position relative to updated_area of
18795 updated_window. TO_X == -1 means clear to the end of this area. */
18796
18797 void
18798 x_clear_end_of_line (to_x)
18799 int to_x;
18800 {
18801 struct frame *f;
18802 struct window *w = updated_window;
18803 int max_x, min_y, max_y;
18804 int from_x, from_y, to_y;
18805
18806 xassert (updated_window && updated_row);
18807 f = XFRAME (w->frame);
18808
18809 if (updated_row->full_width_p)
18810 max_x = WINDOW_TOTAL_WIDTH (w);
18811 else
18812 max_x = window_box_width (w, updated_area);
18813 max_y = window_text_bottom_y (w);
18814
18815 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18816 of window. For TO_X > 0, truncate to end of drawing area. */
18817 if (to_x == 0)
18818 return;
18819 else if (to_x < 0)
18820 to_x = max_x;
18821 else
18822 to_x = min (to_x, max_x);
18823
18824 to_y = min (max_y, output_cursor.y + updated_row->height);
18825
18826 /* Notice if the cursor will be cleared by this operation. */
18827 if (!updated_row->full_width_p)
18828 notice_overwritten_cursor (w, updated_area,
18829 output_cursor.x, -1,
18830 updated_row->y,
18831 MATRIX_ROW_BOTTOM_Y (updated_row));
18832
18833 from_x = output_cursor.x;
18834
18835 /* Translate to frame coordinates. */
18836 if (updated_row->full_width_p)
18837 {
18838 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18839 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18840 }
18841 else
18842 {
18843 int area_left = window_box_left (w, updated_area);
18844 from_x += area_left;
18845 to_x += area_left;
18846 }
18847
18848 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18849 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18850 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18851
18852 /* Prevent inadvertently clearing to end of the X window. */
18853 if (to_x > from_x && to_y > from_y)
18854 {
18855 BLOCK_INPUT;
18856 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
18857 to_x - from_x, to_y - from_y);
18858 UNBLOCK_INPUT;
18859 }
18860 }
18861
18862 #endif /* HAVE_WINDOW_SYSTEM */
18863
18864
18865 \f
18866 /***********************************************************************
18867 Cursor types
18868 ***********************************************************************/
18869
18870 /* Value is the internal representation of the specified cursor type
18871 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18872 of the bar cursor. */
18873
18874 static enum text_cursor_kinds
18875 get_specified_cursor_type (arg, width)
18876 Lisp_Object arg;
18877 int *width;
18878 {
18879 enum text_cursor_kinds type;
18880
18881 if (NILP (arg))
18882 return NO_CURSOR;
18883
18884 if (EQ (arg, Qbox))
18885 return FILLED_BOX_CURSOR;
18886
18887 if (EQ (arg, Qhollow))
18888 return HOLLOW_BOX_CURSOR;
18889
18890 if (EQ (arg, Qbar))
18891 {
18892 *width = 2;
18893 return BAR_CURSOR;
18894 }
18895
18896 if (CONSP (arg)
18897 && EQ (XCAR (arg), Qbar)
18898 && INTEGERP (XCDR (arg))
18899 && XINT (XCDR (arg)) >= 0)
18900 {
18901 *width = XINT (XCDR (arg));
18902 return BAR_CURSOR;
18903 }
18904
18905 if (EQ (arg, Qhbar))
18906 {
18907 *width = 2;
18908 return HBAR_CURSOR;
18909 }
18910
18911 if (CONSP (arg)
18912 && EQ (XCAR (arg), Qhbar)
18913 && INTEGERP (XCDR (arg))
18914 && XINT (XCDR (arg)) >= 0)
18915 {
18916 *width = XINT (XCDR (arg));
18917 return HBAR_CURSOR;
18918 }
18919
18920 /* Treat anything unknown as "hollow box cursor".
18921 It was bad to signal an error; people have trouble fixing
18922 .Xdefaults with Emacs, when it has something bad in it. */
18923 type = HOLLOW_BOX_CURSOR;
18924
18925 return type;
18926 }
18927
18928 /* Set the default cursor types for specified frame. */
18929 void
18930 set_frame_cursor_types (f, arg)
18931 struct frame *f;
18932 Lisp_Object arg;
18933 {
18934 int width;
18935 Lisp_Object tem;
18936
18937 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
18938 FRAME_CURSOR_WIDTH (f) = width;
18939
18940 /* By default, set up the blink-off state depending on the on-state. */
18941
18942 tem = Fassoc (arg, Vblink_cursor_alist);
18943 if (!NILP (tem))
18944 {
18945 FRAME_BLINK_OFF_CURSOR (f)
18946 = get_specified_cursor_type (XCDR (tem), &width);
18947 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
18948 }
18949 else
18950 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
18951 }
18952
18953
18954 /* Return the cursor we want to be displayed in window W. Return
18955 width of bar/hbar cursor through WIDTH arg. Return with
18956 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18957 (i.e. if the `system caret' should track this cursor).
18958
18959 In a mini-buffer window, we want the cursor only to appear if we
18960 are reading input from this window. For the selected window, we
18961 want the cursor type given by the frame parameter or buffer local
18962 setting of cursor-type. If explicitly marked off, draw no cursor.
18963 In all other cases, we want a hollow box cursor. */
18964
18965 static enum text_cursor_kinds
18966 get_window_cursor_type (w, glyph, width, active_cursor)
18967 struct window *w;
18968 struct glyph *glyph;
18969 int *width;
18970 int *active_cursor;
18971 {
18972 struct frame *f = XFRAME (w->frame);
18973 struct buffer *b = XBUFFER (w->buffer);
18974 int cursor_type = DEFAULT_CURSOR;
18975 Lisp_Object alt_cursor;
18976 int non_selected = 0;
18977
18978 *active_cursor = 1;
18979
18980 /* Echo area */
18981 if (cursor_in_echo_area
18982 && FRAME_HAS_MINIBUF_P (f)
18983 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
18984 {
18985 if (w == XWINDOW (echo_area_window))
18986 {
18987 *width = FRAME_CURSOR_WIDTH (f);
18988 return FRAME_DESIRED_CURSOR (f);
18989 }
18990
18991 *active_cursor = 0;
18992 non_selected = 1;
18993 }
18994
18995 /* Nonselected window or nonselected frame. */
18996 else if (w != XWINDOW (f->selected_window)
18997 #ifdef HAVE_WINDOW_SYSTEM
18998 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
18999 #endif
19000 )
19001 {
19002 *active_cursor = 0;
19003
19004 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19005 return NO_CURSOR;
19006
19007 non_selected = 1;
19008 }
19009
19010 /* Never display a cursor in a window in which cursor-type is nil. */
19011 if (NILP (b->cursor_type))
19012 return NO_CURSOR;
19013
19014 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19015 if (non_selected)
19016 {
19017 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19018 return get_specified_cursor_type (alt_cursor, width);
19019 }
19020
19021 /* Get the normal cursor type for this window. */
19022 if (EQ (b->cursor_type, Qt))
19023 {
19024 cursor_type = FRAME_DESIRED_CURSOR (f);
19025 *width = FRAME_CURSOR_WIDTH (f);
19026 }
19027 else
19028 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19029
19030 /* Use normal cursor if not blinked off. */
19031 if (!w->cursor_off_p && glyph != NULL)
19032 {
19033 if (glyph->type == IMAGE_GLYPH) {
19034 if (cursor_type == FILLED_BOX_CURSOR)
19035 cursor_type = HOLLOW_BOX_CURSOR;
19036 }
19037 return cursor_type;
19038 }
19039
19040 /* Cursor is blinked off, so determine how to "toggle" it. */
19041
19042 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19043 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19044 return get_specified_cursor_type (XCDR (alt_cursor), width);
19045
19046 /* Then see if frame has specified a specific blink off cursor type. */
19047 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19048 {
19049 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19050 return FRAME_BLINK_OFF_CURSOR (f);
19051 }
19052
19053 #if 0
19054 /* Some people liked having a permanently visible blinking cursor,
19055 while others had very strong opinions against it. So it was
19056 decided to remove it. KFS 2003-09-03 */
19057
19058 /* Finally perform built-in cursor blinking:
19059 filled box <-> hollow box
19060 wide [h]bar <-> narrow [h]bar
19061 narrow [h]bar <-> no cursor
19062 other type <-> no cursor */
19063
19064 if (cursor_type == FILLED_BOX_CURSOR)
19065 return HOLLOW_BOX_CURSOR;
19066
19067 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19068 {
19069 *width = 1;
19070 return cursor_type;
19071 }
19072 #endif
19073
19074 return NO_CURSOR;
19075 }
19076
19077
19078 #ifdef HAVE_WINDOW_SYSTEM
19079
19080 /* Notice when the text cursor of window W has been completely
19081 overwritten by a drawing operation that outputs glyphs in AREA
19082 starting at X0 and ending at X1 in the line starting at Y0 and
19083 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19084 the rest of the line after X0 has been written. Y coordinates
19085 are window-relative. */
19086
19087 static void
19088 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19089 struct window *w;
19090 enum glyph_row_area area;
19091 int x0, y0, x1, y1;
19092 {
19093 int cx0, cx1, cy0, cy1;
19094 struct glyph_row *row;
19095
19096 if (!w->phys_cursor_on_p)
19097 return;
19098 if (area != TEXT_AREA)
19099 return;
19100
19101 row = w->current_matrix->rows + w->phys_cursor.vpos;
19102 if (!row->displays_text_p)
19103 return;
19104
19105 if (row->cursor_in_fringe_p)
19106 {
19107 row->cursor_in_fringe_p = 0;
19108 draw_fringe_bitmap (w, row, 0);
19109 w->phys_cursor_on_p = 0;
19110 return;
19111 }
19112
19113 cx0 = w->phys_cursor.x;
19114 cx1 = cx0 + w->phys_cursor_width;
19115 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19116 return;
19117
19118 /* The cursor image will be completely removed from the
19119 screen if the output area intersects the cursor area in
19120 y-direction. When we draw in [y0 y1[, and some part of
19121 the cursor is at y < y0, that part must have been drawn
19122 before. When scrolling, the cursor is erased before
19123 actually scrolling, so we don't come here. When not
19124 scrolling, the rows above the old cursor row must have
19125 changed, and in this case these rows must have written
19126 over the cursor image.
19127
19128 Likewise if part of the cursor is below y1, with the
19129 exception of the cursor being in the first blank row at
19130 the buffer and window end because update_text_area
19131 doesn't draw that row. (Except when it does, but
19132 that's handled in update_text_area.) */
19133
19134 cy0 = w->phys_cursor.y;
19135 cy1 = cy0 + w->phys_cursor_height;
19136 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19137 return;
19138
19139 w->phys_cursor_on_p = 0;
19140 }
19141
19142 #endif /* HAVE_WINDOW_SYSTEM */
19143
19144 \f
19145 /************************************************************************
19146 Mouse Face
19147 ************************************************************************/
19148
19149 #ifdef HAVE_WINDOW_SYSTEM
19150
19151 /* EXPORT for RIF:
19152 Fix the display of area AREA of overlapping row ROW in window W. */
19153
19154 void
19155 x_fix_overlapping_area (w, row, area)
19156 struct window *w;
19157 struct glyph_row *row;
19158 enum glyph_row_area area;
19159 {
19160 int i, x;
19161
19162 BLOCK_INPUT;
19163
19164 x = 0;
19165 for (i = 0; i < row->used[area];)
19166 {
19167 if (row->glyphs[area][i].overlaps_vertically_p)
19168 {
19169 int start = i, start_x = x;
19170
19171 do
19172 {
19173 x += row->glyphs[area][i].pixel_width;
19174 ++i;
19175 }
19176 while (i < row->used[area]
19177 && row->glyphs[area][i].overlaps_vertically_p);
19178
19179 draw_glyphs (w, start_x, row, area,
19180 start, i,
19181 DRAW_NORMAL_TEXT, 1);
19182 }
19183 else
19184 {
19185 x += row->glyphs[area][i].pixel_width;
19186 ++i;
19187 }
19188 }
19189
19190 UNBLOCK_INPUT;
19191 }
19192
19193
19194 /* EXPORT:
19195 Draw the cursor glyph of window W in glyph row ROW. See the
19196 comment of draw_glyphs for the meaning of HL. */
19197
19198 void
19199 draw_phys_cursor_glyph (w, row, hl)
19200 struct window *w;
19201 struct glyph_row *row;
19202 enum draw_glyphs_face hl;
19203 {
19204 /* If cursor hpos is out of bounds, don't draw garbage. This can
19205 happen in mini-buffer windows when switching between echo area
19206 glyphs and mini-buffer. */
19207 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19208 {
19209 int on_p = w->phys_cursor_on_p;
19210 int x1;
19211 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19212 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19213 hl, 0);
19214 w->phys_cursor_on_p = on_p;
19215
19216 if (hl == DRAW_CURSOR)
19217 w->phys_cursor_width = x1 - w->phys_cursor.x;
19218 /* When we erase the cursor, and ROW is overlapped by other
19219 rows, make sure that these overlapping parts of other rows
19220 are redrawn. */
19221 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19222 {
19223 if (row > w->current_matrix->rows
19224 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19225 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19226
19227 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19228 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19229 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19230 }
19231 }
19232 }
19233
19234
19235 /* EXPORT:
19236 Erase the image of a cursor of window W from the screen. */
19237
19238 void
19239 erase_phys_cursor (w)
19240 struct window *w;
19241 {
19242 struct frame *f = XFRAME (w->frame);
19243 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19244 int hpos = w->phys_cursor.hpos;
19245 int vpos = w->phys_cursor.vpos;
19246 int mouse_face_here_p = 0;
19247 struct glyph_matrix *active_glyphs = w->current_matrix;
19248 struct glyph_row *cursor_row;
19249 struct glyph *cursor_glyph;
19250 enum draw_glyphs_face hl;
19251
19252 /* No cursor displayed or row invalidated => nothing to do on the
19253 screen. */
19254 if (w->phys_cursor_type == NO_CURSOR)
19255 goto mark_cursor_off;
19256
19257 /* VPOS >= active_glyphs->nrows means that window has been resized.
19258 Don't bother to erase the cursor. */
19259 if (vpos >= active_glyphs->nrows)
19260 goto mark_cursor_off;
19261
19262 /* If row containing cursor is marked invalid, there is nothing we
19263 can do. */
19264 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19265 if (!cursor_row->enabled_p)
19266 goto mark_cursor_off;
19267
19268 /* If row is completely invisible, don't attempt to delete a cursor which
19269 isn't there. This can happen if cursor is at top of a window, and
19270 we switch to a buffer with a header line in that window. */
19271 if (cursor_row->visible_height <= 0)
19272 goto mark_cursor_off;
19273
19274 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19275 if (cursor_row->cursor_in_fringe_p)
19276 {
19277 cursor_row->cursor_in_fringe_p = 0;
19278 draw_fringe_bitmap (w, cursor_row, 0);
19279 goto mark_cursor_off;
19280 }
19281
19282 /* This can happen when the new row is shorter than the old one.
19283 In this case, either draw_glyphs or clear_end_of_line
19284 should have cleared the cursor. Note that we wouldn't be
19285 able to erase the cursor in this case because we don't have a
19286 cursor glyph at hand. */
19287 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19288 goto mark_cursor_off;
19289
19290 /* If the cursor is in the mouse face area, redisplay that when
19291 we clear the cursor. */
19292 if (! NILP (dpyinfo->mouse_face_window)
19293 && w == XWINDOW (dpyinfo->mouse_face_window)
19294 && (vpos > dpyinfo->mouse_face_beg_row
19295 || (vpos == dpyinfo->mouse_face_beg_row
19296 && hpos >= dpyinfo->mouse_face_beg_col))
19297 && (vpos < dpyinfo->mouse_face_end_row
19298 || (vpos == dpyinfo->mouse_face_end_row
19299 && hpos < dpyinfo->mouse_face_end_col))
19300 /* Don't redraw the cursor's spot in mouse face if it is at the
19301 end of a line (on a newline). The cursor appears there, but
19302 mouse highlighting does not. */
19303 && cursor_row->used[TEXT_AREA] > hpos)
19304 mouse_face_here_p = 1;
19305
19306 /* Maybe clear the display under the cursor. */
19307 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19308 {
19309 int x, y;
19310 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19311
19312 cursor_glyph = get_phys_cursor_glyph (w);
19313 if (cursor_glyph == NULL)
19314 goto mark_cursor_off;
19315
19316 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19317 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19318
19319 FRAME_RIF (f)->clear_frame_area (f, x, y,
19320 cursor_glyph->pixel_width, cursor_row->visible_height);
19321 }
19322
19323 /* Erase the cursor by redrawing the character underneath it. */
19324 if (mouse_face_here_p)
19325 hl = DRAW_MOUSE_FACE;
19326 else
19327 hl = DRAW_NORMAL_TEXT;
19328 draw_phys_cursor_glyph (w, cursor_row, hl);
19329
19330 mark_cursor_off:
19331 w->phys_cursor_on_p = 0;
19332 w->phys_cursor_type = NO_CURSOR;
19333 }
19334
19335
19336 /* EXPORT:
19337 Display or clear cursor of window W. If ON is zero, clear the
19338 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19339 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19340
19341 void
19342 display_and_set_cursor (w, on, hpos, vpos, x, y)
19343 struct window *w;
19344 int on, hpos, vpos, x, y;
19345 {
19346 struct frame *f = XFRAME (w->frame);
19347 int new_cursor_type;
19348 int new_cursor_width;
19349 int active_cursor;
19350 struct glyph_matrix *current_glyphs;
19351 struct glyph_row *glyph_row;
19352 struct glyph *glyph;
19353
19354 /* This is pointless on invisible frames, and dangerous on garbaged
19355 windows and frames; in the latter case, the frame or window may
19356 be in the midst of changing its size, and x and y may be off the
19357 window. */
19358 if (! FRAME_VISIBLE_P (f)
19359 || FRAME_GARBAGED_P (f)
19360 || vpos >= w->current_matrix->nrows
19361 || hpos >= w->current_matrix->matrix_w)
19362 return;
19363
19364 /* If cursor is off and we want it off, return quickly. */
19365 if (!on && !w->phys_cursor_on_p)
19366 return;
19367
19368 current_glyphs = w->current_matrix;
19369 glyph_row = MATRIX_ROW (current_glyphs, vpos);
19370 glyph = (glyph_row->cursor_in_fringe_p ? NULL
19371 : glyph_row->glyphs[TEXT_AREA] + hpos);
19372
19373 /* If cursor row is not enabled, we don't really know where to
19374 display the cursor. */
19375 if (!glyph_row->enabled_p)
19376 {
19377 w->phys_cursor_on_p = 0;
19378 return;
19379 }
19380
19381 xassert (interrupt_input_blocked);
19382
19383 /* Set new_cursor_type to the cursor we want to be displayed. */
19384 new_cursor_type = get_window_cursor_type (w, glyph,
19385 &new_cursor_width, &active_cursor);
19386
19387 /* If cursor is currently being shown and we don't want it to be or
19388 it is in the wrong place, or the cursor type is not what we want,
19389 erase it. */
19390 if (w->phys_cursor_on_p
19391 && (!on
19392 || w->phys_cursor.x != x
19393 || w->phys_cursor.y != y
19394 || new_cursor_type != w->phys_cursor_type
19395 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19396 && new_cursor_width != w->phys_cursor_width)))
19397 erase_phys_cursor (w);
19398
19399 /* Don't check phys_cursor_on_p here because that flag is only set
19400 to zero in some cases where we know that the cursor has been
19401 completely erased, to avoid the extra work of erasing the cursor
19402 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19403 still not be visible, or it has only been partly erased. */
19404 if (on)
19405 {
19406 w->phys_cursor_ascent = glyph_row->ascent;
19407 w->phys_cursor_height = glyph_row->height;
19408
19409 /* Set phys_cursor_.* before x_draw_.* is called because some
19410 of them may need the information. */
19411 w->phys_cursor.x = x;
19412 w->phys_cursor.y = glyph_row->y;
19413 w->phys_cursor.hpos = hpos;
19414 w->phys_cursor.vpos = vpos;
19415 }
19416
19417 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
19418 new_cursor_type, new_cursor_width,
19419 on, active_cursor);
19420 }
19421
19422
19423 /* Switch the display of W's cursor on or off, according to the value
19424 of ON. */
19425
19426 static void
19427 update_window_cursor (w, on)
19428 struct window *w;
19429 int on;
19430 {
19431 /* Don't update cursor in windows whose frame is in the process
19432 of being deleted. */
19433 if (w->current_matrix)
19434 {
19435 BLOCK_INPUT;
19436 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19437 w->phys_cursor.x, w->phys_cursor.y);
19438 UNBLOCK_INPUT;
19439 }
19440 }
19441
19442
19443 /* Call update_window_cursor with parameter ON_P on all leaf windows
19444 in the window tree rooted at W. */
19445
19446 static void
19447 update_cursor_in_window_tree (w, on_p)
19448 struct window *w;
19449 int on_p;
19450 {
19451 while (w)
19452 {
19453 if (!NILP (w->hchild))
19454 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19455 else if (!NILP (w->vchild))
19456 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19457 else
19458 update_window_cursor (w, on_p);
19459
19460 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19461 }
19462 }
19463
19464
19465 /* EXPORT:
19466 Display the cursor on window W, or clear it, according to ON_P.
19467 Don't change the cursor's position. */
19468
19469 void
19470 x_update_cursor (f, on_p)
19471 struct frame *f;
19472 int on_p;
19473 {
19474 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19475 }
19476
19477
19478 /* EXPORT:
19479 Clear the cursor of window W to background color, and mark the
19480 cursor as not shown. This is used when the text where the cursor
19481 is is about to be rewritten. */
19482
19483 void
19484 x_clear_cursor (w)
19485 struct window *w;
19486 {
19487 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19488 update_window_cursor (w, 0);
19489 }
19490
19491
19492 /* EXPORT:
19493 Display the active region described by mouse_face_* according to DRAW. */
19494
19495 void
19496 show_mouse_face (dpyinfo, draw)
19497 Display_Info *dpyinfo;
19498 enum draw_glyphs_face draw;
19499 {
19500 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19501 struct frame *f = XFRAME (WINDOW_FRAME (w));
19502
19503 if (/* If window is in the process of being destroyed, don't bother
19504 to do anything. */
19505 w->current_matrix != NULL
19506 /* Don't update mouse highlight if hidden */
19507 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19508 /* Recognize when we are called to operate on rows that don't exist
19509 anymore. This can happen when a window is split. */
19510 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19511 {
19512 int phys_cursor_on_p = w->phys_cursor_on_p;
19513 struct glyph_row *row, *first, *last;
19514
19515 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19516 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19517
19518 for (row = first; row <= last && row->enabled_p; ++row)
19519 {
19520 int start_hpos, end_hpos, start_x;
19521
19522 /* For all but the first row, the highlight starts at column 0. */
19523 if (row == first)
19524 {
19525 start_hpos = dpyinfo->mouse_face_beg_col;
19526 start_x = dpyinfo->mouse_face_beg_x;
19527 }
19528 else
19529 {
19530 start_hpos = 0;
19531 start_x = 0;
19532 }
19533
19534 if (row == last)
19535 end_hpos = dpyinfo->mouse_face_end_col;
19536 else
19537 end_hpos = row->used[TEXT_AREA];
19538
19539 if (end_hpos > start_hpos)
19540 {
19541 draw_glyphs (w, start_x, row, TEXT_AREA,
19542 start_hpos, end_hpos,
19543 draw, 0);
19544
19545 row->mouse_face_p
19546 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19547 }
19548 }
19549
19550 /* When we've written over the cursor, arrange for it to
19551 be displayed again. */
19552 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19553 {
19554 BLOCK_INPUT;
19555 display_and_set_cursor (w, 1,
19556 w->phys_cursor.hpos, w->phys_cursor.vpos,
19557 w->phys_cursor.x, w->phys_cursor.y);
19558 UNBLOCK_INPUT;
19559 }
19560 }
19561
19562 /* Change the mouse cursor. */
19563 if (draw == DRAW_NORMAL_TEXT)
19564 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19565 else if (draw == DRAW_MOUSE_FACE)
19566 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19567 else
19568 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19569 }
19570
19571 /* EXPORT:
19572 Clear out the mouse-highlighted active region.
19573 Redraw it un-highlighted first. Value is non-zero if mouse
19574 face was actually drawn unhighlighted. */
19575
19576 int
19577 clear_mouse_face (dpyinfo)
19578 Display_Info *dpyinfo;
19579 {
19580 int cleared = 0;
19581
19582 if (!NILP (dpyinfo->mouse_face_window))
19583 {
19584 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19585 cleared = 1;
19586 }
19587
19588 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19589 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19590 dpyinfo->mouse_face_window = Qnil;
19591 dpyinfo->mouse_face_overlay = Qnil;
19592 return cleared;
19593 }
19594
19595
19596 /* EXPORT:
19597 Non-zero if physical cursor of window W is within mouse face. */
19598
19599 int
19600 cursor_in_mouse_face_p (w)
19601 struct window *w;
19602 {
19603 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19604 int in_mouse_face = 0;
19605
19606 if (WINDOWP (dpyinfo->mouse_face_window)
19607 && XWINDOW (dpyinfo->mouse_face_window) == w)
19608 {
19609 int hpos = w->phys_cursor.hpos;
19610 int vpos = w->phys_cursor.vpos;
19611
19612 if (vpos >= dpyinfo->mouse_face_beg_row
19613 && vpos <= dpyinfo->mouse_face_end_row
19614 && (vpos > dpyinfo->mouse_face_beg_row
19615 || hpos >= dpyinfo->mouse_face_beg_col)
19616 && (vpos < dpyinfo->mouse_face_end_row
19617 || hpos < dpyinfo->mouse_face_end_col
19618 || dpyinfo->mouse_face_past_end))
19619 in_mouse_face = 1;
19620 }
19621
19622 return in_mouse_face;
19623 }
19624
19625
19626
19627 \f
19628 /* Find the glyph matrix position of buffer position CHARPOS in window
19629 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19630 current glyphs must be up to date. If CHARPOS is above window
19631 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19632 of last line in W. In the row containing CHARPOS, stop before glyphs
19633 having STOP as object. */
19634
19635 #if 1 /* This is a version of fast_find_position that's more correct
19636 in the presence of hscrolling, for example. I didn't install
19637 it right away because the problem fixed is minor, it failed
19638 in 20.x as well, and I think it's too risky to install
19639 so near the release of 21.1. 2001-09-25 gerd. */
19640
19641 static int
19642 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19643 struct window *w;
19644 int charpos;
19645 int *hpos, *vpos, *x, *y;
19646 Lisp_Object stop;
19647 {
19648 struct glyph_row *row, *first;
19649 struct glyph *glyph, *end;
19650 int past_end = 0;
19651
19652 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19653 row = row_containing_pos (w, charpos, first, NULL, 0);
19654 if (row == NULL)
19655 {
19656 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19657 {
19658 *x = *y = *hpos = *vpos = 0;
19659 return 1;
19660 }
19661 else
19662 {
19663 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19664 past_end = 1;
19665 }
19666 }
19667
19668 *x = row->x;
19669 *y = row->y;
19670 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19671
19672 glyph = row->glyphs[TEXT_AREA];
19673 end = glyph + row->used[TEXT_AREA];
19674
19675 /* Skip over glyphs not having an object at the start of the row.
19676 These are special glyphs like truncation marks on terminal
19677 frames. */
19678 if (row->displays_text_p)
19679 while (glyph < end
19680 && INTEGERP (glyph->object)
19681 && !EQ (stop, glyph->object)
19682 && glyph->charpos < 0)
19683 {
19684 *x += glyph->pixel_width;
19685 ++glyph;
19686 }
19687
19688 while (glyph < end
19689 && !INTEGERP (glyph->object)
19690 && !EQ (stop, glyph->object)
19691 && (!BUFFERP (glyph->object)
19692 || glyph->charpos < charpos))
19693 {
19694 *x += glyph->pixel_width;
19695 ++glyph;
19696 }
19697
19698 *hpos = glyph - row->glyphs[TEXT_AREA];
19699 return !past_end;
19700 }
19701
19702 #else /* not 1 */
19703
19704 static int
19705 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19706 struct window *w;
19707 int pos;
19708 int *hpos, *vpos, *x, *y;
19709 Lisp_Object stop;
19710 {
19711 int i;
19712 int lastcol;
19713 int maybe_next_line_p = 0;
19714 int line_start_position;
19715 int yb = window_text_bottom_y (w);
19716 struct glyph_row *row, *best_row;
19717 int row_vpos, best_row_vpos;
19718 int current_x;
19719
19720 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19721 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19722
19723 while (row->y < yb)
19724 {
19725 if (row->used[TEXT_AREA])
19726 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19727 else
19728 line_start_position = 0;
19729
19730 if (line_start_position > pos)
19731 break;
19732 /* If the position sought is the end of the buffer,
19733 don't include the blank lines at the bottom of the window. */
19734 else if (line_start_position == pos
19735 && pos == BUF_ZV (XBUFFER (w->buffer)))
19736 {
19737 maybe_next_line_p = 1;
19738 break;
19739 }
19740 else if (line_start_position > 0)
19741 {
19742 best_row = row;
19743 best_row_vpos = row_vpos;
19744 }
19745
19746 if (row->y + row->height >= yb)
19747 break;
19748
19749 ++row;
19750 ++row_vpos;
19751 }
19752
19753 /* Find the right column within BEST_ROW. */
19754 lastcol = 0;
19755 current_x = best_row->x;
19756 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19757 {
19758 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19759 int charpos = glyph->charpos;
19760
19761 if (BUFFERP (glyph->object))
19762 {
19763 if (charpos == pos)
19764 {
19765 *hpos = i;
19766 *vpos = best_row_vpos;
19767 *x = current_x;
19768 *y = best_row->y;
19769 return 1;
19770 }
19771 else if (charpos > pos)
19772 break;
19773 }
19774 else if (EQ (glyph->object, stop))
19775 break;
19776
19777 if (charpos > 0)
19778 lastcol = i;
19779 current_x += glyph->pixel_width;
19780 }
19781
19782 /* If we're looking for the end of the buffer,
19783 and we didn't find it in the line we scanned,
19784 use the start of the following line. */
19785 if (maybe_next_line_p)
19786 {
19787 ++best_row;
19788 ++best_row_vpos;
19789 lastcol = 0;
19790 current_x = best_row->x;
19791 }
19792
19793 *vpos = best_row_vpos;
19794 *hpos = lastcol + 1;
19795 *x = current_x;
19796 *y = best_row->y;
19797 return 0;
19798 }
19799
19800 #endif /* not 1 */
19801
19802
19803 /* Find the position of the glyph for position POS in OBJECT in
19804 window W's current matrix, and return in *X, *Y the pixel
19805 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19806
19807 RIGHT_P non-zero means return the position of the right edge of the
19808 glyph, RIGHT_P zero means return the left edge position.
19809
19810 If no glyph for POS exists in the matrix, return the position of
19811 the glyph with the next smaller position that is in the matrix, if
19812 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19813 exists in the matrix, return the position of the glyph with the
19814 next larger position in OBJECT.
19815
19816 Value is non-zero if a glyph was found. */
19817
19818 static int
19819 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19820 struct window *w;
19821 int pos;
19822 Lisp_Object object;
19823 int *hpos, *vpos, *x, *y;
19824 int right_p;
19825 {
19826 int yb = window_text_bottom_y (w);
19827 struct glyph_row *r;
19828 struct glyph *best_glyph = NULL;
19829 struct glyph_row *best_row = NULL;
19830 int best_x = 0;
19831
19832 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19833 r->enabled_p && r->y < yb;
19834 ++r)
19835 {
19836 struct glyph *g = r->glyphs[TEXT_AREA];
19837 struct glyph *e = g + r->used[TEXT_AREA];
19838 int gx;
19839
19840 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19841 if (EQ (g->object, object))
19842 {
19843 if (g->charpos == pos)
19844 {
19845 best_glyph = g;
19846 best_x = gx;
19847 best_row = r;
19848 goto found;
19849 }
19850 else if (best_glyph == NULL
19851 || ((abs (g->charpos - pos)
19852 < abs (best_glyph->charpos - pos))
19853 && (right_p
19854 ? g->charpos < pos
19855 : g->charpos > pos)))
19856 {
19857 best_glyph = g;
19858 best_x = gx;
19859 best_row = r;
19860 }
19861 }
19862 }
19863
19864 found:
19865
19866 if (best_glyph)
19867 {
19868 *x = best_x;
19869 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19870
19871 if (right_p)
19872 {
19873 *x += best_glyph->pixel_width;
19874 ++*hpos;
19875 }
19876
19877 *y = best_row->y;
19878 *vpos = best_row - w->current_matrix->rows;
19879 }
19880
19881 return best_glyph != NULL;
19882 }
19883
19884
19885 /* See if position X, Y is within a hot-spot of an image. */
19886
19887 static int
19888 on_hot_spot_p (hot_spot, x, y)
19889 Lisp_Object hot_spot;
19890 int x, y;
19891 {
19892 if (!CONSP (hot_spot))
19893 return 0;
19894
19895 if (EQ (XCAR (hot_spot), Qrect))
19896 {
19897 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
19898 Lisp_Object rect = XCDR (hot_spot);
19899 Lisp_Object tem;
19900 if (!CONSP (rect))
19901 return 0;
19902 if (!CONSP (XCAR (rect)))
19903 return 0;
19904 if (!CONSP (XCDR (rect)))
19905 return 0;
19906 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
19907 return 0;
19908 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
19909 return 0;
19910 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
19911 return 0;
19912 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
19913 return 0;
19914 return 1;
19915 }
19916 else if (EQ (XCAR (hot_spot), Qcircle))
19917 {
19918 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
19919 Lisp_Object circ = XCDR (hot_spot);
19920 Lisp_Object lr, lx0, ly0;
19921 if (CONSP (circ)
19922 && CONSP (XCAR (circ))
19923 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
19924 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
19925 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
19926 {
19927 double r = XFLOATINT (lr);
19928 double dx = XINT (lx0) - x;
19929 double dy = XINT (ly0) - y;
19930 return (dx * dx + dy * dy <= r * r);
19931 }
19932 }
19933 else if (EQ (XCAR (hot_spot), Qpoly))
19934 {
19935 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
19936 if (VECTORP (XCDR (hot_spot)))
19937 {
19938 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
19939 Lisp_Object *poly = v->contents;
19940 int n = v->size;
19941 int i;
19942 int inside = 0;
19943 Lisp_Object lx, ly;
19944 int x0, y0;
19945
19946 /* Need an even number of coordinates, and at least 3 edges. */
19947 if (n < 6 || n & 1)
19948 return 0;
19949
19950 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
19951 If count is odd, we are inside polygon. Pixels on edges
19952 may or may not be included depending on actual geometry of the
19953 polygon. */
19954 if ((lx = poly[n-2], !INTEGERP (lx))
19955 || (ly = poly[n-1], !INTEGERP (lx)))
19956 return 0;
19957 x0 = XINT (lx), y0 = XINT (ly);
19958 for (i = 0; i < n; i += 2)
19959 {
19960 int x1 = x0, y1 = y0;
19961 if ((lx = poly[i], !INTEGERP (lx))
19962 || (ly = poly[i+1], !INTEGERP (ly)))
19963 return 0;
19964 x0 = XINT (lx), y0 = XINT (ly);
19965
19966 /* Does this segment cross the X line? */
19967 if (x0 >= x)
19968 {
19969 if (x1 >= x)
19970 continue;
19971 }
19972 else if (x1 < x)
19973 continue;
19974 if (y > y0 && y > y1)
19975 continue;
19976 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
19977 inside = !inside;
19978 }
19979 return inside;
19980 }
19981 }
19982 return 0;
19983 }
19984
19985 Lisp_Object
19986 find_hot_spot (map, x, y)
19987 Lisp_Object map;
19988 int x, y;
19989 {
19990 while (CONSP (map))
19991 {
19992 if (CONSP (XCAR (map))
19993 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
19994 return XCAR (map);
19995 map = XCDR (map);
19996 }
19997
19998 return Qnil;
19999 }
20000
20001 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20002 3, 3, 0,
20003 doc: /* Lookup in image map MAP coordinates X and Y.
20004 An image map is an alist where each element has the format (AREA ID PLIST).
20005 An AREA is specified as either a rectangle, a circle, or a polygon:
20006 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20007 pixel coordinates of the upper left and bottom right corners.
20008 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20009 and the radius of the circle; r may be a float or integer.
20010 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20011 vector describes one corner in the polygon.
20012 Returns the alist element for the first matching AREA in MAP. */)
20013 (map, x, y)
20014 Lisp_Object map;
20015 Lisp_Object x, y;
20016 {
20017 int ix, iy;
20018 if (NILP (map))
20019 return Qnil;
20020
20021 CHECK_NUMBER (x);
20022 CHECK_NUMBER (y);
20023
20024 return find_hot_spot (map, XINT (x), XINT (y));
20025 }
20026
20027
20028 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20029 static void
20030 define_frame_cursor1 (f, cursor, pointer)
20031 struct frame *f;
20032 Cursor cursor;
20033 Lisp_Object pointer;
20034 {
20035 if (!NILP (pointer))
20036 {
20037 if (EQ (pointer, Qarrow))
20038 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20039 else if (EQ (pointer, Qhand))
20040 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20041 else if (EQ (pointer, Qtext))
20042 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20043 else if (EQ (pointer, intern ("hdrag")))
20044 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20045 #ifdef HAVE_X_WINDOWS
20046 else if (EQ (pointer, intern ("vdrag")))
20047 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20048 #endif
20049 else if (EQ (pointer, intern ("hourglass")))
20050 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20051 else if (EQ (pointer, Qmodeline))
20052 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20053 else
20054 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20055 }
20056
20057 #ifndef HAVE_CARBON
20058 if (cursor != No_Cursor)
20059 #else
20060 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20061 #endif
20062 FRAME_RIF (f)->define_frame_cursor (f, cursor);
20063 }
20064
20065 /* Take proper action when mouse has moved to the mode or header line
20066 or marginal area AREA of window W, x-position X and y-position Y.
20067 X is relative to the start of the text display area of W, so the
20068 width of bitmap areas and scroll bars must be subtracted to get a
20069 position relative to the start of the mode line. */
20070
20071 static void
20072 note_mode_line_or_margin_highlight (w, x, y, area)
20073 struct window *w;
20074 int x, y;
20075 enum window_part area;
20076 {
20077 struct frame *f = XFRAME (w->frame);
20078 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20079 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20080 Lisp_Object pointer = Qnil;
20081 int charpos, dx, dy, width, height;
20082 Lisp_Object string, object = Qnil;
20083 Lisp_Object pos, help, image;
20084
20085 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20086 string = mode_line_string (w, area, &x, &y, &charpos,
20087 &object, &dx, &dy, &width, &height);
20088 else
20089 {
20090 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20091 string = marginal_area_string (w, area, &x, &y, &charpos,
20092 &object, &dx, &dy, &width, &height);
20093 }
20094
20095 help = Qnil;
20096
20097 if (IMAGEP (object))
20098 {
20099 Lisp_Object image_map, hotspot;
20100 if ((image_map = Fplist_get (XCDR (object), QCmap),
20101 !NILP (image_map))
20102 && (hotspot = find_hot_spot (image_map, dx, dy),
20103 CONSP (hotspot))
20104 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20105 {
20106 Lisp_Object area_id, plist;
20107
20108 area_id = XCAR (hotspot);
20109 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20110 If so, we could look for mouse-enter, mouse-leave
20111 properties in PLIST (and do something...). */
20112 if ((plist = XCDR (hotspot), CONSP (plist)))
20113 {
20114 pointer = Fplist_get (plist, Qpointer);
20115 if (NILP (pointer))
20116 pointer = Qhand;
20117 help = Fplist_get (plist, Qhelp_echo);
20118 if (!NILP (help))
20119 {
20120 help_echo_string = help;
20121 /* Is this correct? ++kfs */
20122 XSETWINDOW (help_echo_window, w);
20123 help_echo_object = w->buffer;
20124 help_echo_pos = charpos;
20125 }
20126 }
20127 if (NILP (pointer))
20128 pointer = Fplist_get (XCDR (object), QCpointer);
20129 }
20130 }
20131
20132 if (STRINGP (string))
20133 {
20134 pos = make_number (charpos);
20135 /* If we're on a string with `help-echo' text property, arrange
20136 for the help to be displayed. This is done by setting the
20137 global variable help_echo_string to the help string. */
20138 help = Fget_text_property (pos, Qhelp_echo, string);
20139 if (!NILP (help))
20140 {
20141 help_echo_string = help;
20142 XSETWINDOW (help_echo_window, w);
20143 help_echo_object = string;
20144 help_echo_pos = charpos;
20145 }
20146
20147 if (NILP (pointer))
20148 pointer = Fget_text_property (pos, Qpointer, string);
20149
20150 /* Change the mouse pointer according to what is under X/Y. */
20151 if (NILP (pointer) && area == ON_MODE_LINE)
20152 {
20153 Lisp_Object map;
20154 map = Fget_text_property (pos, Qlocal_map, string);
20155 if (!KEYMAPP (map))
20156 map = Fget_text_property (pos, Qkeymap, string);
20157 if (!KEYMAPP (map))
20158 cursor = dpyinfo->vertical_scroll_bar_cursor;
20159 }
20160 }
20161
20162 define_frame_cursor1 (f, cursor, pointer);
20163 }
20164
20165
20166 /* EXPORT:
20167 Take proper action when the mouse has moved to position X, Y on
20168 frame F as regards highlighting characters that have mouse-face
20169 properties. Also de-highlighting chars where the mouse was before.
20170 X and Y can be negative or out of range. */
20171
20172 void
20173 note_mouse_highlight (f, x, y)
20174 struct frame *f;
20175 int x, y;
20176 {
20177 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20178 enum window_part part;
20179 Lisp_Object window;
20180 struct window *w;
20181 Cursor cursor = No_Cursor;
20182 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20183 struct buffer *b;
20184
20185 /* When a menu is active, don't highlight because this looks odd. */
20186 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20187 if (popup_activated ())
20188 return;
20189 #endif
20190
20191 if (NILP (Vmouse_highlight)
20192 || !f->glyphs_initialized_p)
20193 return;
20194
20195 dpyinfo->mouse_face_mouse_x = x;
20196 dpyinfo->mouse_face_mouse_y = y;
20197 dpyinfo->mouse_face_mouse_frame = f;
20198
20199 if (dpyinfo->mouse_face_defer)
20200 return;
20201
20202 if (gc_in_progress)
20203 {
20204 dpyinfo->mouse_face_deferred_gc = 1;
20205 return;
20206 }
20207
20208 /* Which window is that in? */
20209 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20210
20211 /* If we were displaying active text in another window, clear that. */
20212 if (! EQ (window, dpyinfo->mouse_face_window))
20213 clear_mouse_face (dpyinfo);
20214
20215 /* Not on a window -> return. */
20216 if (!WINDOWP (window))
20217 return;
20218
20219 /* Reset help_echo_string. It will get recomputed below. */
20220 help_echo_string = Qnil;
20221
20222 /* Convert to window-relative pixel coordinates. */
20223 w = XWINDOW (window);
20224 frame_to_window_pixel_xy (w, &x, &y);
20225
20226 /* Handle tool-bar window differently since it doesn't display a
20227 buffer. */
20228 if (EQ (window, f->tool_bar_window))
20229 {
20230 note_tool_bar_highlight (f, x, y);
20231 return;
20232 }
20233
20234 /* Mouse is on the mode, header line or margin? */
20235 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20236 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20237 {
20238 note_mode_line_or_margin_highlight (w, x, y, part);
20239 return;
20240 }
20241
20242 if (part == ON_VERTICAL_BORDER)
20243 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20244 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20245 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20246 else
20247 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20248
20249 /* Are we in a window whose display is up to date?
20250 And verify the buffer's text has not changed. */
20251 b = XBUFFER (w->buffer);
20252 if (part == ON_TEXT
20253 && EQ (w->window_end_valid, w->buffer)
20254 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20255 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20256 {
20257 int hpos, vpos, pos, i, dx, dy, area;
20258 struct glyph *glyph;
20259 Lisp_Object object;
20260 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20261 Lisp_Object *overlay_vec = NULL;
20262 int len, noverlays;
20263 struct buffer *obuf;
20264 int obegv, ozv, same_region;
20265
20266 /* Find the glyph under X/Y. */
20267 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20268
20269 /* Look for :pointer property on image. */
20270 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20271 {
20272 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20273 if (img != NULL && IMAGEP (img->spec))
20274 {
20275 Lisp_Object image_map, hotspot;
20276 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20277 !NILP (image_map))
20278 && (hotspot = find_hot_spot (image_map, dx, dy),
20279 CONSP (hotspot))
20280 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20281 {
20282 Lisp_Object area_id, plist;
20283
20284 area_id = XCAR (hotspot);
20285 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20286 If so, we could look for mouse-enter, mouse-leave
20287 properties in PLIST (and do something...). */
20288 if ((plist = XCDR (hotspot), CONSP (plist)))
20289 {
20290 pointer = Fplist_get (plist, Qpointer);
20291 if (NILP (pointer))
20292 pointer = Qhand;
20293 help_echo_string = Fplist_get (plist, Qhelp_echo);
20294 if (!NILP (help_echo_string))
20295 {
20296 help_echo_window = window;
20297 help_echo_object = glyph->object;
20298 help_echo_pos = glyph->charpos;
20299 }
20300 }
20301 }
20302 if (NILP (pointer))
20303 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20304 }
20305 }
20306
20307 /* Clear mouse face if X/Y not over text. */
20308 if (glyph == NULL
20309 || area != TEXT_AREA
20310 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20311 {
20312 if (clear_mouse_face (dpyinfo))
20313 cursor = No_Cursor;
20314 if (NILP (pointer))
20315 {
20316 if (area != TEXT_AREA)
20317 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20318 else
20319 pointer = Vvoid_text_area_pointer;
20320 }
20321 goto set_cursor;
20322 }
20323
20324 pos = glyph->charpos;
20325 object = glyph->object;
20326 if (!STRINGP (object) && !BUFFERP (object))
20327 goto set_cursor;
20328
20329 /* If we get an out-of-range value, return now; avoid an error. */
20330 if (BUFFERP (object) && pos > BUF_Z (b))
20331 goto set_cursor;
20332
20333 /* Make the window's buffer temporarily current for
20334 overlays_at and compute_char_face. */
20335 obuf = current_buffer;
20336 current_buffer = b;
20337 obegv = BEGV;
20338 ozv = ZV;
20339 BEGV = BEG;
20340 ZV = Z;
20341
20342 /* Is this char mouse-active or does it have help-echo? */
20343 position = make_number (pos);
20344
20345 if (BUFFERP (object))
20346 {
20347 /* Put all the overlays we want in a vector in overlay_vec.
20348 Store the length in len. If there are more than 10, make
20349 enough space for all, and try again. */
20350 len = 10;
20351 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20352 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20353 if (noverlays > len)
20354 {
20355 len = noverlays;
20356 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20357 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20358 }
20359
20360 /* Sort overlays into increasing priority order. */
20361 noverlays = sort_overlays (overlay_vec, noverlays, w);
20362 }
20363 else
20364 noverlays = 0;
20365
20366 same_region = (EQ (window, dpyinfo->mouse_face_window)
20367 && vpos >= dpyinfo->mouse_face_beg_row
20368 && vpos <= dpyinfo->mouse_face_end_row
20369 && (vpos > dpyinfo->mouse_face_beg_row
20370 || hpos >= dpyinfo->mouse_face_beg_col)
20371 && (vpos < dpyinfo->mouse_face_end_row
20372 || hpos < dpyinfo->mouse_face_end_col
20373 || dpyinfo->mouse_face_past_end));
20374
20375 if (same_region)
20376 cursor = No_Cursor;
20377
20378 /* Check mouse-face highlighting. */
20379 if (! same_region
20380 /* If there exists an overlay with mouse-face overlapping
20381 the one we are currently highlighting, we have to
20382 check if we enter the overlapping overlay, and then
20383 highlight only that. */
20384 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20385 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20386 {
20387 /* Find the highest priority overlay that has a mouse-face
20388 property. */
20389 overlay = Qnil;
20390 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20391 {
20392 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20393 if (!NILP (mouse_face))
20394 overlay = overlay_vec[i];
20395 }
20396
20397 /* If we're actually highlighting the same overlay as
20398 before, there's no need to do that again. */
20399 if (!NILP (overlay)
20400 && EQ (overlay, dpyinfo->mouse_face_overlay))
20401 goto check_help_echo;
20402
20403 dpyinfo->mouse_face_overlay = overlay;
20404
20405 /* Clear the display of the old active region, if any. */
20406 if (clear_mouse_face (dpyinfo))
20407 cursor = No_Cursor;
20408
20409 /* If no overlay applies, get a text property. */
20410 if (NILP (overlay))
20411 mouse_face = Fget_text_property (position, Qmouse_face, object);
20412
20413 /* Handle the overlay case. */
20414 if (!NILP (overlay))
20415 {
20416 /* Find the range of text around this char that
20417 should be active. */
20418 Lisp_Object before, after;
20419 int ignore;
20420
20421 before = Foverlay_start (overlay);
20422 after = Foverlay_end (overlay);
20423 /* Record this as the current active region. */
20424 fast_find_position (w, XFASTINT (before),
20425 &dpyinfo->mouse_face_beg_col,
20426 &dpyinfo->mouse_face_beg_row,
20427 &dpyinfo->mouse_face_beg_x,
20428 &dpyinfo->mouse_face_beg_y, Qnil);
20429
20430 dpyinfo->mouse_face_past_end
20431 = !fast_find_position (w, XFASTINT (after),
20432 &dpyinfo->mouse_face_end_col,
20433 &dpyinfo->mouse_face_end_row,
20434 &dpyinfo->mouse_face_end_x,
20435 &dpyinfo->mouse_face_end_y, Qnil);
20436 dpyinfo->mouse_face_window = window;
20437
20438 dpyinfo->mouse_face_face_id
20439 = face_at_buffer_position (w, pos, 0, 0,
20440 &ignore, pos + 1,
20441 !dpyinfo->mouse_face_hidden);
20442
20443 /* Display it as active. */
20444 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20445 cursor = No_Cursor;
20446 }
20447 /* Handle the text property case. */
20448 else if (!NILP (mouse_face) && BUFFERP (object))
20449 {
20450 /* Find the range of text around this char that
20451 should be active. */
20452 Lisp_Object before, after, beginning, end;
20453 int ignore;
20454
20455 beginning = Fmarker_position (w->start);
20456 end = make_number (BUF_Z (XBUFFER (object))
20457 - XFASTINT (w->window_end_pos));
20458 before
20459 = Fprevious_single_property_change (make_number (pos + 1),
20460 Qmouse_face,
20461 object, beginning);
20462 after
20463 = Fnext_single_property_change (position, Qmouse_face,
20464 object, end);
20465
20466 /* Record this as the current active region. */
20467 fast_find_position (w, XFASTINT (before),
20468 &dpyinfo->mouse_face_beg_col,
20469 &dpyinfo->mouse_face_beg_row,
20470 &dpyinfo->mouse_face_beg_x,
20471 &dpyinfo->mouse_face_beg_y, Qnil);
20472 dpyinfo->mouse_face_past_end
20473 = !fast_find_position (w, XFASTINT (after),
20474 &dpyinfo->mouse_face_end_col,
20475 &dpyinfo->mouse_face_end_row,
20476 &dpyinfo->mouse_face_end_x,
20477 &dpyinfo->mouse_face_end_y, Qnil);
20478 dpyinfo->mouse_face_window = window;
20479
20480 if (BUFFERP (object))
20481 dpyinfo->mouse_face_face_id
20482 = face_at_buffer_position (w, pos, 0, 0,
20483 &ignore, pos + 1,
20484 !dpyinfo->mouse_face_hidden);
20485
20486 /* Display it as active. */
20487 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20488 cursor = No_Cursor;
20489 }
20490 else if (!NILP (mouse_face) && STRINGP (object))
20491 {
20492 Lisp_Object b, e;
20493 int ignore;
20494
20495 b = Fprevious_single_property_change (make_number (pos + 1),
20496 Qmouse_face,
20497 object, Qnil);
20498 e = Fnext_single_property_change (position, Qmouse_face,
20499 object, Qnil);
20500 if (NILP (b))
20501 b = make_number (0);
20502 if (NILP (e))
20503 e = make_number (SCHARS (object) - 1);
20504 fast_find_string_pos (w, XINT (b), object,
20505 &dpyinfo->mouse_face_beg_col,
20506 &dpyinfo->mouse_face_beg_row,
20507 &dpyinfo->mouse_face_beg_x,
20508 &dpyinfo->mouse_face_beg_y, 0);
20509 fast_find_string_pos (w, XINT (e), object,
20510 &dpyinfo->mouse_face_end_col,
20511 &dpyinfo->mouse_face_end_row,
20512 &dpyinfo->mouse_face_end_x,
20513 &dpyinfo->mouse_face_end_y, 1);
20514 dpyinfo->mouse_face_past_end = 0;
20515 dpyinfo->mouse_face_window = window;
20516 dpyinfo->mouse_face_face_id
20517 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20518 glyph->face_id, 1);
20519 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20520 cursor = No_Cursor;
20521 }
20522 else if (STRINGP (object) && NILP (mouse_face))
20523 {
20524 /* A string which doesn't have mouse-face, but
20525 the text ``under'' it might have. */
20526 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20527 int start = MATRIX_ROW_START_CHARPOS (r);
20528
20529 pos = string_buffer_position (w, object, start);
20530 if (pos > 0)
20531 mouse_face = get_char_property_and_overlay (make_number (pos),
20532 Qmouse_face,
20533 w->buffer,
20534 &overlay);
20535 if (!NILP (mouse_face) && !NILP (overlay))
20536 {
20537 Lisp_Object before = Foverlay_start (overlay);
20538 Lisp_Object after = Foverlay_end (overlay);
20539 int ignore;
20540
20541 /* Note that we might not be able to find position
20542 BEFORE in the glyph matrix if the overlay is
20543 entirely covered by a `display' property. In
20544 this case, we overshoot. So let's stop in
20545 the glyph matrix before glyphs for OBJECT. */
20546 fast_find_position (w, XFASTINT (before),
20547 &dpyinfo->mouse_face_beg_col,
20548 &dpyinfo->mouse_face_beg_row,
20549 &dpyinfo->mouse_face_beg_x,
20550 &dpyinfo->mouse_face_beg_y,
20551 object);
20552
20553 dpyinfo->mouse_face_past_end
20554 = !fast_find_position (w, XFASTINT (after),
20555 &dpyinfo->mouse_face_end_col,
20556 &dpyinfo->mouse_face_end_row,
20557 &dpyinfo->mouse_face_end_x,
20558 &dpyinfo->mouse_face_end_y,
20559 Qnil);
20560 dpyinfo->mouse_face_window = window;
20561 dpyinfo->mouse_face_face_id
20562 = face_at_buffer_position (w, pos, 0, 0,
20563 &ignore, pos + 1,
20564 !dpyinfo->mouse_face_hidden);
20565
20566 /* Display it as active. */
20567 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20568 cursor = No_Cursor;
20569 }
20570 }
20571 }
20572
20573 check_help_echo:
20574
20575 /* Look for a `help-echo' property. */
20576 if (NILP (help_echo_string)) {
20577 Lisp_Object help, overlay;
20578
20579 /* Check overlays first. */
20580 help = overlay = Qnil;
20581 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20582 {
20583 overlay = overlay_vec[i];
20584 help = Foverlay_get (overlay, Qhelp_echo);
20585 }
20586
20587 if (!NILP (help))
20588 {
20589 help_echo_string = help;
20590 help_echo_window = window;
20591 help_echo_object = overlay;
20592 help_echo_pos = pos;
20593 }
20594 else
20595 {
20596 Lisp_Object object = glyph->object;
20597 int charpos = glyph->charpos;
20598
20599 /* Try text properties. */
20600 if (STRINGP (object)
20601 && charpos >= 0
20602 && charpos < SCHARS (object))
20603 {
20604 help = Fget_text_property (make_number (charpos),
20605 Qhelp_echo, object);
20606 if (NILP (help))
20607 {
20608 /* If the string itself doesn't specify a help-echo,
20609 see if the buffer text ``under'' it does. */
20610 struct glyph_row *r
20611 = MATRIX_ROW (w->current_matrix, vpos);
20612 int start = MATRIX_ROW_START_CHARPOS (r);
20613 int pos = string_buffer_position (w, object, start);
20614 if (pos > 0)
20615 {
20616 help = Fget_char_property (make_number (pos),
20617 Qhelp_echo, w->buffer);
20618 if (!NILP (help))
20619 {
20620 charpos = pos;
20621 object = w->buffer;
20622 }
20623 }
20624 }
20625 }
20626 else if (BUFFERP (object)
20627 && charpos >= BEGV
20628 && charpos < ZV)
20629 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20630 object);
20631
20632 if (!NILP (help))
20633 {
20634 help_echo_string = help;
20635 help_echo_window = window;
20636 help_echo_object = object;
20637 help_echo_pos = charpos;
20638 }
20639 }
20640 }
20641
20642 /* Look for a `pointer' property. */
20643 if (NILP (pointer))
20644 {
20645 /* Check overlays first. */
20646 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
20647 pointer = Foverlay_get (overlay_vec[i], Qpointer);
20648
20649 if (NILP (pointer))
20650 {
20651 Lisp_Object object = glyph->object;
20652 int charpos = glyph->charpos;
20653
20654 /* Try text properties. */
20655 if (STRINGP (object)
20656 && charpos >= 0
20657 && charpos < SCHARS (object))
20658 {
20659 pointer = Fget_text_property (make_number (charpos),
20660 Qpointer, object);
20661 if (NILP (pointer))
20662 {
20663 /* If the string itself doesn't specify a pointer,
20664 see if the buffer text ``under'' it does. */
20665 struct glyph_row *r
20666 = MATRIX_ROW (w->current_matrix, vpos);
20667 int start = MATRIX_ROW_START_CHARPOS (r);
20668 int pos = string_buffer_position (w, object, start);
20669 if (pos > 0)
20670 pointer = Fget_char_property (make_number (pos),
20671 Qpointer, w->buffer);
20672 }
20673 }
20674 else if (BUFFERP (object)
20675 && charpos >= BEGV
20676 && charpos < ZV)
20677 pointer = Fget_text_property (make_number (charpos),
20678 Qpointer, object);
20679 }
20680 }
20681
20682 BEGV = obegv;
20683 ZV = ozv;
20684 current_buffer = obuf;
20685 }
20686
20687 set_cursor:
20688
20689 define_frame_cursor1 (f, cursor, pointer);
20690 }
20691
20692
20693 /* EXPORT for RIF:
20694 Clear any mouse-face on window W. This function is part of the
20695 redisplay interface, and is called from try_window_id and similar
20696 functions to ensure the mouse-highlight is off. */
20697
20698 void
20699 x_clear_window_mouse_face (w)
20700 struct window *w;
20701 {
20702 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20703 Lisp_Object window;
20704
20705 BLOCK_INPUT;
20706 XSETWINDOW (window, w);
20707 if (EQ (window, dpyinfo->mouse_face_window))
20708 clear_mouse_face (dpyinfo);
20709 UNBLOCK_INPUT;
20710 }
20711
20712
20713 /* EXPORT:
20714 Just discard the mouse face information for frame F, if any.
20715 This is used when the size of F is changed. */
20716
20717 void
20718 cancel_mouse_face (f)
20719 struct frame *f;
20720 {
20721 Lisp_Object window;
20722 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20723
20724 window = dpyinfo->mouse_face_window;
20725 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20726 {
20727 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20728 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20729 dpyinfo->mouse_face_window = Qnil;
20730 }
20731 }
20732
20733
20734 #endif /* HAVE_WINDOW_SYSTEM */
20735
20736 \f
20737 /***********************************************************************
20738 Exposure Events
20739 ***********************************************************************/
20740
20741 #ifdef HAVE_WINDOW_SYSTEM
20742
20743 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20744 which intersects rectangle R. R is in window-relative coordinates. */
20745
20746 static void
20747 expose_area (w, row, r, area)
20748 struct window *w;
20749 struct glyph_row *row;
20750 XRectangle *r;
20751 enum glyph_row_area area;
20752 {
20753 struct glyph *first = row->glyphs[area];
20754 struct glyph *end = row->glyphs[area] + row->used[area];
20755 struct glyph *last;
20756 int first_x, start_x, x;
20757
20758 if (area == TEXT_AREA && row->fill_line_p)
20759 /* If row extends face to end of line write the whole line. */
20760 draw_glyphs (w, 0, row, area,
20761 0, row->used[area],
20762 DRAW_NORMAL_TEXT, 0);
20763 else
20764 {
20765 /* Set START_X to the window-relative start position for drawing glyphs of
20766 AREA. The first glyph of the text area can be partially visible.
20767 The first glyphs of other areas cannot. */
20768 start_x = window_box_left_offset (w, area);
20769 x = start_x;
20770 if (area == TEXT_AREA)
20771 x += row->x;
20772
20773 /* Find the first glyph that must be redrawn. */
20774 while (first < end
20775 && x + first->pixel_width < r->x)
20776 {
20777 x += first->pixel_width;
20778 ++first;
20779 }
20780
20781 /* Find the last one. */
20782 last = first;
20783 first_x = x;
20784 while (last < end
20785 && x < r->x + r->width)
20786 {
20787 x += last->pixel_width;
20788 ++last;
20789 }
20790
20791 /* Repaint. */
20792 if (last > first)
20793 draw_glyphs (w, first_x - start_x, row, area,
20794 first - row->glyphs[area], last - row->glyphs[area],
20795 DRAW_NORMAL_TEXT, 0);
20796 }
20797 }
20798
20799
20800 /* Redraw the parts of the glyph row ROW on window W intersecting
20801 rectangle R. R is in window-relative coordinates. Value is
20802 non-zero if mouse-face was overwritten. */
20803
20804 static int
20805 expose_line (w, row, r)
20806 struct window *w;
20807 struct glyph_row *row;
20808 XRectangle *r;
20809 {
20810 xassert (row->enabled_p);
20811
20812 if (row->mode_line_p || w->pseudo_window_p)
20813 draw_glyphs (w, 0, row, TEXT_AREA,
20814 0, row->used[TEXT_AREA],
20815 DRAW_NORMAL_TEXT, 0);
20816 else
20817 {
20818 if (row->used[LEFT_MARGIN_AREA])
20819 expose_area (w, row, r, LEFT_MARGIN_AREA);
20820 if (row->used[TEXT_AREA])
20821 expose_area (w, row, r, TEXT_AREA);
20822 if (row->used[RIGHT_MARGIN_AREA])
20823 expose_area (w, row, r, RIGHT_MARGIN_AREA);
20824 draw_row_fringe_bitmaps (w, row);
20825 }
20826
20827 return row->mouse_face_p;
20828 }
20829
20830
20831 /* Redraw those parts of glyphs rows during expose event handling that
20832 overlap other rows. Redrawing of an exposed line writes over parts
20833 of lines overlapping that exposed line; this function fixes that.
20834
20835 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20836 row in W's current matrix that is exposed and overlaps other rows.
20837 LAST_OVERLAPPING_ROW is the last such row. */
20838
20839 static void
20840 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20841 struct window *w;
20842 struct glyph_row *first_overlapping_row;
20843 struct glyph_row *last_overlapping_row;
20844 {
20845 struct glyph_row *row;
20846
20847 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20848 if (row->overlapping_p)
20849 {
20850 xassert (row->enabled_p && !row->mode_line_p);
20851
20852 if (row->used[LEFT_MARGIN_AREA])
20853 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20854
20855 if (row->used[TEXT_AREA])
20856 x_fix_overlapping_area (w, row, TEXT_AREA);
20857
20858 if (row->used[RIGHT_MARGIN_AREA])
20859 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20860 }
20861 }
20862
20863
20864 /* Return non-zero if W's cursor intersects rectangle R. */
20865
20866 static int
20867 phys_cursor_in_rect_p (w, r)
20868 struct window *w;
20869 XRectangle *r;
20870 {
20871 XRectangle cr, result;
20872 struct glyph *cursor_glyph;
20873
20874 cursor_glyph = get_phys_cursor_glyph (w);
20875 if (cursor_glyph)
20876 {
20877 /* r is relative to W's box, but w->phys_cursor.x is relative
20878 to left edge of W's TEXT area. Adjust it. */
20879 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
20880 cr.y = w->phys_cursor.y;
20881 cr.width = cursor_glyph->pixel_width;
20882 cr.height = w->phys_cursor_height;
20883 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20884 I assume the effect is the same -- and this is portable. */
20885 return x_intersect_rectangles (&cr, r, &result);
20886 }
20887 else
20888 return 0;
20889 }
20890
20891
20892 /* EXPORT:
20893 Draw a vertical window border to the right of window W if W doesn't
20894 have vertical scroll bars. */
20895
20896 void
20897 x_draw_vertical_border (w)
20898 struct window *w;
20899 {
20900 struct frame *f = XFRAME (WINDOW_FRAME (w));
20901
20902 /* We could do better, if we knew what type of scroll-bar the adjacent
20903 windows (on either side) have... But we don't :-(
20904 However, I think this works ok. ++KFS 2003-04-25 */
20905
20906 /* Redraw borders between horizontally adjacent windows. Don't
20907 do it for frames with vertical scroll bars because either the
20908 right scroll bar of a window, or the left scroll bar of its
20909 neighbor will suffice as a border. */
20910 if (!WINDOW_RIGHTMOST_P (w)
20911 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
20912 {
20913 int x0, x1, y0, y1;
20914
20915 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20916 y1 -= 1;
20917
20918 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
20919 }
20920 else if (!WINDOW_LEFTMOST_P (w)
20921 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
20922 {
20923 int x0, x1, y0, y1;
20924
20925 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20926 y1 -= 1;
20927
20928 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
20929 }
20930 }
20931
20932
20933 /* Redraw the part of window W intersection rectangle FR. Pixel
20934 coordinates in FR are frame-relative. Call this function with
20935 input blocked. Value is non-zero if the exposure overwrites
20936 mouse-face. */
20937
20938 static int
20939 expose_window (w, fr)
20940 struct window *w;
20941 XRectangle *fr;
20942 {
20943 struct frame *f = XFRAME (w->frame);
20944 XRectangle wr, r;
20945 int mouse_face_overwritten_p = 0;
20946
20947 /* If window is not yet fully initialized, do nothing. This can
20948 happen when toolkit scroll bars are used and a window is split.
20949 Reconfiguring the scroll bar will generate an expose for a newly
20950 created window. */
20951 if (w->current_matrix == NULL)
20952 return 0;
20953
20954 /* When we're currently updating the window, display and current
20955 matrix usually don't agree. Arrange for a thorough display
20956 later. */
20957 if (w == updated_window)
20958 {
20959 SET_FRAME_GARBAGED (f);
20960 return 0;
20961 }
20962
20963 /* Frame-relative pixel rectangle of W. */
20964 wr.x = WINDOW_LEFT_EDGE_X (w);
20965 wr.y = WINDOW_TOP_EDGE_Y (w);
20966 wr.width = WINDOW_TOTAL_WIDTH (w);
20967 wr.height = WINDOW_TOTAL_HEIGHT (w);
20968
20969 if (x_intersect_rectangles (fr, &wr, &r))
20970 {
20971 int yb = window_text_bottom_y (w);
20972 struct glyph_row *row;
20973 int cursor_cleared_p;
20974 struct glyph_row *first_overlapping_row, *last_overlapping_row;
20975
20976 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
20977 r.x, r.y, r.width, r.height));
20978
20979 /* Convert to window coordinates. */
20980 r.x -= WINDOW_LEFT_EDGE_X (w);
20981 r.y -= WINDOW_TOP_EDGE_Y (w);
20982
20983 /* Turn off the cursor. */
20984 if (!w->pseudo_window_p
20985 && phys_cursor_in_rect_p (w, &r))
20986 {
20987 x_clear_cursor (w);
20988 cursor_cleared_p = 1;
20989 }
20990 else
20991 cursor_cleared_p = 0;
20992
20993 /* Update lines intersecting rectangle R. */
20994 first_overlapping_row = last_overlapping_row = NULL;
20995 for (row = w->current_matrix->rows;
20996 row->enabled_p;
20997 ++row)
20998 {
20999 int y0 = row->y;
21000 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21001
21002 if ((y0 >= r.y && y0 < r.y + r.height)
21003 || (y1 > r.y && y1 < r.y + r.height)
21004 || (r.y >= y0 && r.y < y1)
21005 || (r.y + r.height > y0 && r.y + r.height < y1))
21006 {
21007 if (row->overlapping_p)
21008 {
21009 if (first_overlapping_row == NULL)
21010 first_overlapping_row = row;
21011 last_overlapping_row = row;
21012 }
21013
21014 if (expose_line (w, row, &r))
21015 mouse_face_overwritten_p = 1;
21016 }
21017
21018 if (y1 >= yb)
21019 break;
21020 }
21021
21022 /* Display the mode line if there is one. */
21023 if (WINDOW_WANTS_MODELINE_P (w)
21024 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21025 row->enabled_p)
21026 && row->y < r.y + r.height)
21027 {
21028 if (expose_line (w, row, &r))
21029 mouse_face_overwritten_p = 1;
21030 }
21031
21032 if (!w->pseudo_window_p)
21033 {
21034 /* Fix the display of overlapping rows. */
21035 if (first_overlapping_row)
21036 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21037
21038 /* Draw border between windows. */
21039 x_draw_vertical_border (w);
21040
21041 /* Turn the cursor on again. */
21042 if (cursor_cleared_p)
21043 update_window_cursor (w, 1);
21044 }
21045 }
21046
21047 #ifdef HAVE_CARBON
21048 /* Display scroll bar for this window. */
21049 if (!NILP (w->vertical_scroll_bar))
21050 {
21051 /* ++KFS:
21052 If this doesn't work here (maybe some header files are missing),
21053 make a function in macterm.c and call it to do the job! */
21054 ControlHandle ch
21055 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21056
21057 Draw1Control (ch);
21058 }
21059 #endif
21060
21061 return mouse_face_overwritten_p;
21062 }
21063
21064
21065
21066 /* Redraw (parts) of all windows in the window tree rooted at W that
21067 intersect R. R contains frame pixel coordinates. Value is
21068 non-zero if the exposure overwrites mouse-face. */
21069
21070 static int
21071 expose_window_tree (w, r)
21072 struct window *w;
21073 XRectangle *r;
21074 {
21075 struct frame *f = XFRAME (w->frame);
21076 int mouse_face_overwritten_p = 0;
21077
21078 while (w && !FRAME_GARBAGED_P (f))
21079 {
21080 if (!NILP (w->hchild))
21081 mouse_face_overwritten_p
21082 |= expose_window_tree (XWINDOW (w->hchild), r);
21083 else if (!NILP (w->vchild))
21084 mouse_face_overwritten_p
21085 |= expose_window_tree (XWINDOW (w->vchild), r);
21086 else
21087 mouse_face_overwritten_p |= expose_window (w, r);
21088
21089 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21090 }
21091
21092 return mouse_face_overwritten_p;
21093 }
21094
21095
21096 /* EXPORT:
21097 Redisplay an exposed area of frame F. X and Y are the upper-left
21098 corner of the exposed rectangle. W and H are width and height of
21099 the exposed area. All are pixel values. W or H zero means redraw
21100 the entire frame. */
21101
21102 void
21103 expose_frame (f, x, y, w, h)
21104 struct frame *f;
21105 int x, y, w, h;
21106 {
21107 XRectangle r;
21108 int mouse_face_overwritten_p = 0;
21109
21110 TRACE ((stderr, "expose_frame "));
21111
21112 /* No need to redraw if frame will be redrawn soon. */
21113 if (FRAME_GARBAGED_P (f))
21114 {
21115 TRACE ((stderr, " garbaged\n"));
21116 return;
21117 }
21118
21119 #ifdef HAVE_CARBON
21120 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21121 or deactivated here, for unknown reasons, activated scroll bars
21122 are shown in deactivated frames in some instances. */
21123 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21124 activate_scroll_bars (f);
21125 else
21126 deactivate_scroll_bars (f);
21127 #endif
21128
21129 /* If basic faces haven't been realized yet, there is no point in
21130 trying to redraw anything. This can happen when we get an expose
21131 event while Emacs is starting, e.g. by moving another window. */
21132 if (FRAME_FACE_CACHE (f) == NULL
21133 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21134 {
21135 TRACE ((stderr, " no faces\n"));
21136 return;
21137 }
21138
21139 if (w == 0 || h == 0)
21140 {
21141 r.x = r.y = 0;
21142 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21143 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21144 }
21145 else
21146 {
21147 r.x = x;
21148 r.y = y;
21149 r.width = w;
21150 r.height = h;
21151 }
21152
21153 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21154 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21155
21156 if (WINDOWP (f->tool_bar_window))
21157 mouse_face_overwritten_p
21158 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21159
21160 #ifdef HAVE_X_WINDOWS
21161 #ifndef MSDOS
21162 #ifndef USE_X_TOOLKIT
21163 if (WINDOWP (f->menu_bar_window))
21164 mouse_face_overwritten_p
21165 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21166 #endif /* not USE_X_TOOLKIT */
21167 #endif
21168 #endif
21169
21170 /* Some window managers support a focus-follows-mouse style with
21171 delayed raising of frames. Imagine a partially obscured frame,
21172 and moving the mouse into partially obscured mouse-face on that
21173 frame. The visible part of the mouse-face will be highlighted,
21174 then the WM raises the obscured frame. With at least one WM, KDE
21175 2.1, Emacs is not getting any event for the raising of the frame
21176 (even tried with SubstructureRedirectMask), only Expose events.
21177 These expose events will draw text normally, i.e. not
21178 highlighted. Which means we must redo the highlight here.
21179 Subsume it under ``we love X''. --gerd 2001-08-15 */
21180 /* Included in Windows version because Windows most likely does not
21181 do the right thing if any third party tool offers
21182 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21183 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21184 {
21185 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21186 if (f == dpyinfo->mouse_face_mouse_frame)
21187 {
21188 int x = dpyinfo->mouse_face_mouse_x;
21189 int y = dpyinfo->mouse_face_mouse_y;
21190 clear_mouse_face (dpyinfo);
21191 note_mouse_highlight (f, x, y);
21192 }
21193 }
21194 }
21195
21196
21197 /* EXPORT:
21198 Determine the intersection of two rectangles R1 and R2. Return
21199 the intersection in *RESULT. Value is non-zero if RESULT is not
21200 empty. */
21201
21202 int
21203 x_intersect_rectangles (r1, r2, result)
21204 XRectangle *r1, *r2, *result;
21205 {
21206 XRectangle *left, *right;
21207 XRectangle *upper, *lower;
21208 int intersection_p = 0;
21209
21210 /* Rearrange so that R1 is the left-most rectangle. */
21211 if (r1->x < r2->x)
21212 left = r1, right = r2;
21213 else
21214 left = r2, right = r1;
21215
21216 /* X0 of the intersection is right.x0, if this is inside R1,
21217 otherwise there is no intersection. */
21218 if (right->x <= left->x + left->width)
21219 {
21220 result->x = right->x;
21221
21222 /* The right end of the intersection is the minimum of the
21223 the right ends of left and right. */
21224 result->width = (min (left->x + left->width, right->x + right->width)
21225 - result->x);
21226
21227 /* Same game for Y. */
21228 if (r1->y < r2->y)
21229 upper = r1, lower = r2;
21230 else
21231 upper = r2, lower = r1;
21232
21233 /* The upper end of the intersection is lower.y0, if this is inside
21234 of upper. Otherwise, there is no intersection. */
21235 if (lower->y <= upper->y + upper->height)
21236 {
21237 result->y = lower->y;
21238
21239 /* The lower end of the intersection is the minimum of the lower
21240 ends of upper and lower. */
21241 result->height = (min (lower->y + lower->height,
21242 upper->y + upper->height)
21243 - result->y);
21244 intersection_p = 1;
21245 }
21246 }
21247
21248 return intersection_p;
21249 }
21250
21251 #endif /* HAVE_WINDOW_SYSTEM */
21252
21253 \f
21254 /***********************************************************************
21255 Initialization
21256 ***********************************************************************/
21257
21258 void
21259 syms_of_xdisp ()
21260 {
21261 Vwith_echo_area_save_vector = Qnil;
21262 staticpro (&Vwith_echo_area_save_vector);
21263
21264 Vmessage_stack = Qnil;
21265 staticpro (&Vmessage_stack);
21266
21267 Qinhibit_redisplay = intern ("inhibit-redisplay");
21268 staticpro (&Qinhibit_redisplay);
21269
21270 message_dolog_marker1 = Fmake_marker ();
21271 staticpro (&message_dolog_marker1);
21272 message_dolog_marker2 = Fmake_marker ();
21273 staticpro (&message_dolog_marker2);
21274 message_dolog_marker3 = Fmake_marker ();
21275 staticpro (&message_dolog_marker3);
21276
21277 #if GLYPH_DEBUG
21278 defsubr (&Sdump_frame_glyph_matrix);
21279 defsubr (&Sdump_glyph_matrix);
21280 defsubr (&Sdump_glyph_row);
21281 defsubr (&Sdump_tool_bar_row);
21282 defsubr (&Strace_redisplay);
21283 defsubr (&Strace_to_stderr);
21284 #endif
21285 #ifdef HAVE_WINDOW_SYSTEM
21286 defsubr (&Stool_bar_lines_needed);
21287 defsubr (&Slookup_image_map);
21288 #endif
21289 defsubr (&Sformat_mode_line);
21290
21291 staticpro (&Qmenu_bar_update_hook);
21292 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21293
21294 staticpro (&Qoverriding_terminal_local_map);
21295 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21296
21297 staticpro (&Qoverriding_local_map);
21298 Qoverriding_local_map = intern ("overriding-local-map");
21299
21300 staticpro (&Qwindow_scroll_functions);
21301 Qwindow_scroll_functions = intern ("window-scroll-functions");
21302
21303 staticpro (&Qredisplay_end_trigger_functions);
21304 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21305
21306 staticpro (&Qinhibit_point_motion_hooks);
21307 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21308
21309 QCdata = intern (":data");
21310 staticpro (&QCdata);
21311 Qdisplay = intern ("display");
21312 staticpro (&Qdisplay);
21313 Qspace_width = intern ("space-width");
21314 staticpro (&Qspace_width);
21315 Qraise = intern ("raise");
21316 staticpro (&Qraise);
21317 Qspace = intern ("space");
21318 staticpro (&Qspace);
21319 Qmargin = intern ("margin");
21320 staticpro (&Qmargin);
21321 Qpointer = intern ("pointer");
21322 staticpro (&Qpointer);
21323 Qleft_margin = intern ("left-margin");
21324 staticpro (&Qleft_margin);
21325 Qright_margin = intern ("right-margin");
21326 staticpro (&Qright_margin);
21327 QCalign_to = intern (":align-to");
21328 staticpro (&QCalign_to);
21329 QCrelative_width = intern (":relative-width");
21330 staticpro (&QCrelative_width);
21331 QCrelative_height = intern (":relative-height");
21332 staticpro (&QCrelative_height);
21333 QCeval = intern (":eval");
21334 staticpro (&QCeval);
21335 QCpropertize = intern (":propertize");
21336 staticpro (&QCpropertize);
21337 QCfile = intern (":file");
21338 staticpro (&QCfile);
21339 Qfontified = intern ("fontified");
21340 staticpro (&Qfontified);
21341 Qfontification_functions = intern ("fontification-functions");
21342 staticpro (&Qfontification_functions);
21343 Qtrailing_whitespace = intern ("trailing-whitespace");
21344 staticpro (&Qtrailing_whitespace);
21345 Qimage = intern ("image");
21346 staticpro (&Qimage);
21347 QCmap = intern (":map");
21348 staticpro (&QCmap);
21349 QCpointer = intern (":pointer");
21350 staticpro (&QCpointer);
21351 Qrect = intern ("rect");
21352 staticpro (&Qrect);
21353 Qcircle = intern ("circle");
21354 staticpro (&Qcircle);
21355 Qpoly = intern ("poly");
21356 staticpro (&Qpoly);
21357 Qmessage_truncate_lines = intern ("message-truncate-lines");
21358 staticpro (&Qmessage_truncate_lines);
21359 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21360 staticpro (&Qcursor_in_non_selected_windows);
21361 Qgrow_only = intern ("grow-only");
21362 staticpro (&Qgrow_only);
21363 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21364 staticpro (&Qinhibit_menubar_update);
21365 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21366 staticpro (&Qinhibit_eval_during_redisplay);
21367 Qposition = intern ("position");
21368 staticpro (&Qposition);
21369 Qbuffer_position = intern ("buffer-position");
21370 staticpro (&Qbuffer_position);
21371 Qobject = intern ("object");
21372 staticpro (&Qobject);
21373 Qbar = intern ("bar");
21374 staticpro (&Qbar);
21375 Qhbar = intern ("hbar");
21376 staticpro (&Qhbar);
21377 Qbox = intern ("box");
21378 staticpro (&Qbox);
21379 Qhollow = intern ("hollow");
21380 staticpro (&Qhollow);
21381 Qhand = intern ("hand");
21382 staticpro (&Qhand);
21383 Qarrow = intern ("arrow");
21384 staticpro (&Qarrow);
21385 Qtext = intern ("text");
21386 staticpro (&Qtext);
21387 Qrisky_local_variable = intern ("risky-local-variable");
21388 staticpro (&Qrisky_local_variable);
21389 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21390 staticpro (&Qinhibit_free_realized_faces);
21391
21392 list_of_error = Fcons (intern ("error"), Qnil);
21393 staticpro (&list_of_error);
21394
21395 last_arrow_position = Qnil;
21396 last_arrow_string = Qnil;
21397 staticpro (&last_arrow_position);
21398 staticpro (&last_arrow_string);
21399
21400 echo_buffer[0] = echo_buffer[1] = Qnil;
21401 staticpro (&echo_buffer[0]);
21402 staticpro (&echo_buffer[1]);
21403
21404 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21405 staticpro (&echo_area_buffer[0]);
21406 staticpro (&echo_area_buffer[1]);
21407
21408 Vmessages_buffer_name = build_string ("*Messages*");
21409 staticpro (&Vmessages_buffer_name);
21410
21411 mode_line_proptrans_alist = Qnil;
21412 staticpro (&mode_line_proptrans_alist);
21413
21414 mode_line_string_list = Qnil;
21415 staticpro (&mode_line_string_list);
21416
21417 help_echo_string = Qnil;
21418 staticpro (&help_echo_string);
21419 help_echo_object = Qnil;
21420 staticpro (&help_echo_object);
21421 help_echo_window = Qnil;
21422 staticpro (&help_echo_window);
21423 previous_help_echo_string = Qnil;
21424 staticpro (&previous_help_echo_string);
21425 help_echo_pos = -1;
21426
21427 #ifdef HAVE_WINDOW_SYSTEM
21428 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
21429 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
21430 For example, if a block cursor is over a tab, it will be drawn as
21431 wide as that tab on the display. */);
21432 x_stretch_cursor_p = 0;
21433 #endif
21434
21435 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
21436 doc: /* *Non-nil means highlight trailing whitespace.
21437 The face used for trailing whitespace is `trailing-whitespace'. */);
21438 Vshow_trailing_whitespace = Qnil;
21439
21440 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
21441 doc: /* *The pointer shape to show in void text areas.
21442 Nil means to show the text pointer. Other options are `arrow', `text',
21443 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21444 Vvoid_text_area_pointer = Qarrow;
21445
21446 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
21447 doc: /* Non-nil means don't actually do any redisplay.
21448 This is used for internal purposes. */);
21449 Vinhibit_redisplay = Qnil;
21450
21451 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
21452 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21453 Vglobal_mode_string = Qnil;
21454
21455 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
21456 doc: /* Marker for where to display an arrow on top of the buffer text.
21457 This must be the beginning of a line in order to work.
21458 See also `overlay-arrow-string'. */);
21459 Voverlay_arrow_position = Qnil;
21460
21461 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
21462 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
21463 Voverlay_arrow_string = Qnil;
21464
21465 DEFVAR_INT ("scroll-step", &scroll_step,
21466 doc: /* *The number of lines to try scrolling a window by when point moves out.
21467 If that fails to bring point back on frame, point is centered instead.
21468 If this is zero, point is always centered after it moves off frame.
21469 If you want scrolling to always be a line at a time, you should set
21470 `scroll-conservatively' to a large value rather than set this to 1. */);
21471
21472 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
21473 doc: /* *Scroll up to this many lines, to bring point back on screen.
21474 A value of zero means to scroll the text to center point vertically
21475 in the window. */);
21476 scroll_conservatively = 0;
21477
21478 DEFVAR_INT ("scroll-margin", &scroll_margin,
21479 doc: /* *Number of lines of margin at the top and bottom of a window.
21480 Recenter the window whenever point gets within this many lines
21481 of the top or bottom of the window. */);
21482 scroll_margin = 0;
21483
21484 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
21485 doc: /* Pixels per inch on current display.
21486 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21487 Vdisplay_pixels_per_inch = make_float (72.0);
21488
21489 #if GLYPH_DEBUG
21490 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
21491 #endif
21492
21493 DEFVAR_BOOL ("truncate-partial-width-windows",
21494 &truncate_partial_width_windows,
21495 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21496 truncate_partial_width_windows = 1;
21497
21498 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
21499 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
21500 Any other value means to use the appropriate face, `mode-line',
21501 `header-line', or `menu' respectively. */);
21502 mode_line_inverse_video = 1;
21503
21504 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
21505 doc: /* *Maximum buffer size for which line number should be displayed.
21506 If the buffer is bigger than this, the line number does not appear
21507 in the mode line. A value of nil means no limit. */);
21508 Vline_number_display_limit = Qnil;
21509
21510 DEFVAR_INT ("line-number-display-limit-width",
21511 &line_number_display_limit_width,
21512 doc: /* *Maximum line width (in characters) for line number display.
21513 If the average length of the lines near point is bigger than this, then the
21514 line number may be omitted from the mode line. */);
21515 line_number_display_limit_width = 200;
21516
21517 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
21518 doc: /* *Non-nil means highlight region even in nonselected windows. */);
21519 highlight_nonselected_windows = 0;
21520
21521 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
21522 doc: /* Non-nil if more than one frame is visible on this display.
21523 Minibuffer-only frames don't count, but iconified frames do.
21524 This variable is not guaranteed to be accurate except while processing
21525 `frame-title-format' and `icon-title-format'. */);
21526
21527 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
21528 doc: /* Template for displaying the title bar of visible frames.
21529 \(Assuming the window manager supports this feature.)
21530 This variable has the same structure as `mode-line-format' (which see),
21531 and is used only on frames for which no explicit name has been set
21532 \(see `modify-frame-parameters'). */);
21533
21534 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
21535 doc: /* Template for displaying the title bar of an iconified frame.
21536 \(Assuming the window manager supports this feature.)
21537 This variable has the same structure as `mode-line-format' (which see),
21538 and is used only on frames for which no explicit name has been set
21539 \(see `modify-frame-parameters'). */);
21540 Vicon_title_format
21541 = Vframe_title_format
21542 = Fcons (intern ("multiple-frames"),
21543 Fcons (build_string ("%b"),
21544 Fcons (Fcons (empty_string,
21545 Fcons (intern ("invocation-name"),
21546 Fcons (build_string ("@"),
21547 Fcons (intern ("system-name"),
21548 Qnil)))),
21549 Qnil)));
21550
21551 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
21552 doc: /* Maximum number of lines to keep in the message log buffer.
21553 If nil, disable message logging. If t, log messages but don't truncate
21554 the buffer when it becomes large. */);
21555 Vmessage_log_max = make_number (50);
21556
21557 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
21558 doc: /* Functions called before redisplay, if window sizes have changed.
21559 The value should be a list of functions that take one argument.
21560 Just before redisplay, for each frame, if any of its windows have changed
21561 size since the last redisplay, or have been split or deleted,
21562 all the functions in the list are called, with the frame as argument. */);
21563 Vwindow_size_change_functions = Qnil;
21564
21565 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
21566 doc: /* List of Functions to call before redisplaying a window with scrolling.
21567 Each function is called with two arguments, the window
21568 and its new display-start position. Note that the value of `window-end'
21569 is not valid when these functions are called. */);
21570 Vwindow_scroll_functions = Qnil;
21571
21572 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
21573 doc: /* *Non-nil means autoselect window with mouse pointer. */);
21574 mouse_autoselect_window = 0;
21575
21576 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21577 doc: /* *Non-nil means automatically resize tool-bars.
21578 This increases a tool-bar's height if not all tool-bar items are visible.
21579 It decreases a tool-bar's height when it would display blank lines
21580 otherwise. */);
21581 auto_resize_tool_bars_p = 1;
21582
21583 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21584 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21585 auto_raise_tool_bar_buttons_p = 1;
21586
21587 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21588 doc: /* *Margin around tool-bar buttons in pixels.
21589 If an integer, use that for both horizontal and vertical margins.
21590 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21591 HORZ specifying the horizontal margin, and VERT specifying the
21592 vertical margin. */);
21593 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21594
21595 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21596 doc: /* *Relief thickness of tool-bar buttons. */);
21597 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21598
21599 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21600 doc: /* List of functions to call to fontify regions of text.
21601 Each function is called with one argument POS. Functions must
21602 fontify a region starting at POS in the current buffer, and give
21603 fontified regions the property `fontified'. */);
21604 Vfontification_functions = Qnil;
21605 Fmake_variable_buffer_local (Qfontification_functions);
21606
21607 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21608 &unibyte_display_via_language_environment,
21609 doc: /* *Non-nil means display unibyte text according to language environment.
21610 Specifically this means that unibyte non-ASCII characters
21611 are displayed by converting them to the equivalent multibyte characters
21612 according to the current language environment. As a result, they are
21613 displayed according to the current fontset. */);
21614 unibyte_display_via_language_environment = 0;
21615
21616 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21617 doc: /* *Maximum height for resizing mini-windows.
21618 If a float, it specifies a fraction of the mini-window frame's height.
21619 If an integer, it specifies a number of lines. */);
21620 Vmax_mini_window_height = make_float (0.25);
21621
21622 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21623 doc: /* *How to resize mini-windows.
21624 A value of nil means don't automatically resize mini-windows.
21625 A value of t means resize them to fit the text displayed in them.
21626 A value of `grow-only', the default, means let mini-windows grow
21627 only, until their display becomes empty, at which point the windows
21628 go back to their normal size. */);
21629 Vresize_mini_windows = Qgrow_only;
21630
21631 DEFVAR_LISP ("cursor-in-non-selected-windows",
21632 &Vcursor_in_non_selected_windows,
21633 doc: /* *Cursor type to display in non-selected windows.
21634 t means to use hollow box cursor. See `cursor-type' for other values. */);
21635 Vcursor_in_non_selected_windows = Qt;
21636
21637 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21638 doc: /* Alist specifying how to blink the cursor off.
21639 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21640 `cursor-type' frame-parameter or variable equals ON-STATE,
21641 comparing using `equal', Emacs uses OFF-STATE to specify
21642 how to blink it off. */);
21643 Vblink_cursor_alist = Qnil;
21644
21645 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21646 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21647 automatic_hscrolling_p = 1;
21648
21649 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21650 doc: /* *How many columns away from the window edge point is allowed to get
21651 before automatic hscrolling will horizontally scroll the window. */);
21652 hscroll_margin = 5;
21653
21654 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21655 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21656 When point is less than `automatic-hscroll-margin' columns from the window
21657 edge, automatic hscrolling will scroll the window by the amount of columns
21658 determined by this variable. If its value is a positive integer, scroll that
21659 many columns. If it's a positive floating-point number, it specifies the
21660 fraction of the window's width to scroll. If it's nil or zero, point will be
21661 centered horizontally after the scroll. Any other value, including negative
21662 numbers, are treated as if the value were zero.
21663
21664 Automatic hscrolling always moves point outside the scroll margin, so if
21665 point was more than scroll step columns inside the margin, the window will
21666 scroll more than the value given by the scroll step.
21667
21668 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21669 and `scroll-right' overrides this variable's effect. */);
21670 Vhscroll_step = make_number (0);
21671
21672 DEFVAR_LISP ("image-types", &Vimage_types,
21673 doc: /* List of supported image types.
21674 Each element of the list is a symbol for a supported image type. */);
21675 Vimage_types = Qnil;
21676
21677 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21678 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21679 Bind this around calls to `message' to let it take effect. */);
21680 message_truncate_lines = 0;
21681
21682 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21683 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21684 Can be used to update submenus whose contents should vary. */);
21685 Vmenu_bar_update_hook = Qnil;
21686
21687 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21688 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21689 inhibit_menubar_update = 0;
21690
21691 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21692 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21693 inhibit_eval_during_redisplay = 0;
21694
21695 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21696 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21697 inhibit_free_realized_faces = 0;
21698
21699 #if GLYPH_DEBUG
21700 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21701 doc: /* Inhibit try_window_id display optimization. */);
21702 inhibit_try_window_id = 0;
21703
21704 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21705 doc: /* Inhibit try_window_reusing display optimization. */);
21706 inhibit_try_window_reusing = 0;
21707
21708 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21709 doc: /* Inhibit try_cursor_movement display optimization. */);
21710 inhibit_try_cursor_movement = 0;
21711 #endif /* GLYPH_DEBUG */
21712 }
21713
21714
21715 /* Initialize this module when Emacs starts. */
21716
21717 void
21718 init_xdisp ()
21719 {
21720 Lisp_Object root_window;
21721 struct window *mini_w;
21722
21723 current_header_line_height = current_mode_line_height = -1;
21724
21725 CHARPOS (this_line_start_pos) = 0;
21726
21727 mini_w = XWINDOW (minibuf_window);
21728 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21729
21730 if (!noninteractive)
21731 {
21732 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21733 int i;
21734
21735 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
21736 set_window_height (root_window,
21737 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
21738 0);
21739 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
21740 set_window_height (minibuf_window, 1, 0);
21741
21742 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
21743 mini_w->total_cols = make_number (FRAME_COLS (f));
21744
21745 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21746 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21747 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21748
21749 /* The default ellipsis glyphs `...'. */
21750 for (i = 0; i < 3; ++i)
21751 default_invis_vector[i] = make_number ('.');
21752 }
21753
21754 {
21755 /* Allocate the buffer for frame titles.
21756 Also used for `format-mode-line'. */
21757 int size = 100;
21758 frame_title_buf = (char *) xmalloc (size);
21759 frame_title_buf_end = frame_title_buf + size;
21760 frame_title_ptr = NULL;
21761 }
21762
21763 help_echo_showing_p = 0;
21764 }
21765
21766
21767 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
21768 (do not change this comment) */