*** empty log message ***
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,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 #endif
202
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
206
207 #define INFINITY 10000000
208
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
214
215 extern int interrupt_input;
216 extern int command_loop_level;
217
218 extern int minibuffer_auto_raise;
219 extern Lisp_Object Vminibuffer_list;
220
221 extern Lisp_Object Qface;
222 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
223
224 extern Lisp_Object Voverriding_local_map;
225 extern Lisp_Object Voverriding_local_map_menu_flag;
226 extern Lisp_Object Qmenu_item;
227 extern Lisp_Object Qwhen;
228 extern Lisp_Object Qhelp_echo;
229
230 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
231 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
232 Lisp_Object Qredisplay_end_trigger_functions;
233 Lisp_Object Qinhibit_point_motion_hooks;
234 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
235 Lisp_Object Qfontified;
236 Lisp_Object Qgrow_only;
237 Lisp_Object Qinhibit_eval_during_redisplay;
238 Lisp_Object Qbuffer_position, Qposition, Qobject;
239
240 /* Cursor shapes */
241 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
242
243 /* Pointer shapes */
244 Lisp_Object Qarrow, Qhand, Qtext;
245
246 Lisp_Object Qrisky_local_variable;
247
248 /* Holds the list (error). */
249 Lisp_Object list_of_error;
250
251 /* Functions called to fontify regions of text. */
252
253 Lisp_Object Vfontification_functions;
254 Lisp_Object Qfontification_functions;
255
256 /* Non-zero means automatically select any window when the mouse
257 cursor moves into it. */
258 int mouse_autoselect_window;
259
260 /* Non-zero means draw tool bar buttons raised when the mouse moves
261 over them. */
262
263 int auto_raise_tool_bar_buttons_p;
264
265 /* Margin around tool bar buttons in pixels. */
266
267 Lisp_Object Vtool_bar_button_margin;
268
269 /* Thickness of shadow to draw around tool bar buttons. */
270
271 EMACS_INT tool_bar_button_relief;
272
273 /* Non-zero means automatically resize tool-bars so that all tool-bar
274 items are visible, and no blank lines remain. */
275
276 int auto_resize_tool_bars_p;
277
278 /* Non-zero means draw block and hollow cursor as wide as the glyph
279 under it. For example, if a block cursor is over a tab, it will be
280 drawn as wide as that tab on the display. */
281
282 int x_stretch_cursor_p;
283
284 /* Non-nil means don't actually do any redisplay. */
285
286 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
287
288 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
289
290 int inhibit_eval_during_redisplay;
291
292 /* Names of text properties relevant for redisplay. */
293
294 Lisp_Object Qdisplay;
295 extern Lisp_Object Qface, Qinvisible, Qwidth;
296
297 /* Symbols used in text property values. */
298
299 Lisp_Object Vdisplay_pixels_per_inch;
300 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
301 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
302 Lisp_Object Qslice;
303 Lisp_Object Qcenter;
304 Lisp_Object Qmargin, Qpointer;
305 Lisp_Object Qline_height, Qtotal;
306 extern Lisp_Object Qheight;
307 extern Lisp_Object QCwidth, QCheight, QCascent;
308 extern Lisp_Object Qscroll_bar;
309 extern Lisp_Object Qcursor;
310
311 /* Non-nil means highlight trailing whitespace. */
312
313 Lisp_Object Vshow_trailing_whitespace;
314
315 #ifdef HAVE_WINDOW_SYSTEM
316 extern Lisp_Object Voverflow_newline_into_fringe;
317
318 /* Test if overflow newline into fringe. Called with iterator IT
319 at or past right window margin, and with IT->current_x set. */
320
321 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
322 (!NILP (Voverflow_newline_into_fringe) \
323 && FRAME_WINDOW_P (it->f) \
324 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
325 && it->current_x == it->last_visible_x)
326
327 #endif /* HAVE_WINDOW_SYSTEM */
328
329 /* Non-nil means show the text cursor in void text areas
330 i.e. in blank areas after eol and eob. This used to be
331 the default in 21.3. */
332
333 Lisp_Object Vvoid_text_area_pointer;
334
335 /* Name of the face used to highlight trailing whitespace. */
336
337 Lisp_Object Qtrailing_whitespace;
338
339 /* The symbol `image' which is the car of the lists used to represent
340 images in Lisp. */
341
342 Lisp_Object Qimage;
343
344 /* The image map types. */
345 Lisp_Object QCmap, QCpointer;
346 Lisp_Object Qrect, Qcircle, Qpoly;
347
348 /* Non-zero means print newline to stdout before next mini-buffer
349 message. */
350
351 int noninteractive_need_newline;
352
353 /* Non-zero means print newline to message log before next message. */
354
355 static int message_log_need_newline;
356
357 /* Three markers that message_dolog uses.
358 It could allocate them itself, but that causes trouble
359 in handling memory-full errors. */
360 static Lisp_Object message_dolog_marker1;
361 static Lisp_Object message_dolog_marker2;
362 static Lisp_Object message_dolog_marker3;
363 \f
364 /* The buffer position of the first character appearing entirely or
365 partially on the line of the selected window which contains the
366 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
367 redisplay optimization in redisplay_internal. */
368
369 static struct text_pos this_line_start_pos;
370
371 /* Number of characters past the end of the line above, including the
372 terminating newline. */
373
374 static struct text_pos this_line_end_pos;
375
376 /* The vertical positions and the height of this line. */
377
378 static int this_line_vpos;
379 static int this_line_y;
380 static int this_line_pixel_height;
381
382 /* X position at which this display line starts. Usually zero;
383 negative if first character is partially visible. */
384
385 static int this_line_start_x;
386
387 /* Buffer that this_line_.* variables are referring to. */
388
389 static struct buffer *this_line_buffer;
390
391 /* Nonzero means truncate lines in all windows less wide than the
392 frame. */
393
394 int truncate_partial_width_windows;
395
396 /* A flag to control how to display unibyte 8-bit character. */
397
398 int unibyte_display_via_language_environment;
399
400 /* Nonzero means we have more than one non-mini-buffer-only frame.
401 Not guaranteed to be accurate except while parsing
402 frame-title-format. */
403
404 int multiple_frames;
405
406 Lisp_Object Vglobal_mode_string;
407
408
409 /* List of variables (symbols) which hold markers for overlay arrows.
410 The symbols on this list are examined during redisplay to determine
411 where to display overlay arrows. */
412
413 Lisp_Object Voverlay_arrow_variable_list;
414
415 /* Marker for where to display an arrow on top of the buffer text. */
416
417 Lisp_Object Voverlay_arrow_position;
418
419 /* String to display for the arrow. Only used on terminal frames. */
420
421 Lisp_Object Voverlay_arrow_string;
422
423 /* Values of those variables at last redisplay are stored as
424 properties on `overlay-arrow-position' symbol. However, if
425 Voverlay_arrow_position is a marker, last-arrow-position is its
426 numerical position. */
427
428 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
429
430 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
431 properties on a symbol in overlay-arrow-variable-list. */
432
433 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
434
435 /* Like mode-line-format, but for the title bar on a visible frame. */
436
437 Lisp_Object Vframe_title_format;
438
439 /* Like mode-line-format, but for the title bar on an iconified frame. */
440
441 Lisp_Object Vicon_title_format;
442
443 /* List of functions to call when a window's size changes. These
444 functions get one arg, a frame on which one or more windows' sizes
445 have changed. */
446
447 static Lisp_Object Vwindow_size_change_functions;
448
449 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
450
451 /* Nonzero if overlay arrow has been displayed once in this window. */
452
453 static int overlay_arrow_seen;
454
455 /* Nonzero means highlight the region even in nonselected windows. */
456
457 int highlight_nonselected_windows;
458
459 /* If cursor motion alone moves point off frame, try scrolling this
460 many lines up or down if that will bring it back. */
461
462 static EMACS_INT scroll_step;
463
464 /* Nonzero means scroll just far enough to bring point back on the
465 screen, when appropriate. */
466
467 static EMACS_INT scroll_conservatively;
468
469 /* Recenter the window whenever point gets within this many lines of
470 the top or bottom of the window. This value is translated into a
471 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
472 that there is really a fixed pixel height scroll margin. */
473
474 EMACS_INT scroll_margin;
475
476 /* Number of windows showing the buffer of the selected window (or
477 another buffer with the same base buffer). keyboard.c refers to
478 this. */
479
480 int buffer_shared;
481
482 /* Vector containing glyphs for an ellipsis `...'. */
483
484 static Lisp_Object default_invis_vector[3];
485
486 /* Zero means display the mode-line/header-line/menu-bar in the default face
487 (this slightly odd definition is for compatibility with previous versions
488 of emacs), non-zero means display them using their respective faces.
489
490 This variable is deprecated. */
491
492 int mode_line_inverse_video;
493
494 /* Prompt to display in front of the mini-buffer contents. */
495
496 Lisp_Object minibuf_prompt;
497
498 /* Width of current mini-buffer prompt. Only set after display_line
499 of the line that contains the prompt. */
500
501 int minibuf_prompt_width;
502
503 /* This is the window where the echo area message was displayed. It
504 is always a mini-buffer window, but it may not be the same window
505 currently active as a mini-buffer. */
506
507 Lisp_Object echo_area_window;
508
509 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
510 pushes the current message and the value of
511 message_enable_multibyte on the stack, the function restore_message
512 pops the stack and displays MESSAGE again. */
513
514 Lisp_Object Vmessage_stack;
515
516 /* Nonzero means multibyte characters were enabled when the echo area
517 message was specified. */
518
519 int message_enable_multibyte;
520
521 /* Nonzero if we should redraw the mode lines on the next redisplay. */
522
523 int update_mode_lines;
524
525 /* Nonzero if window sizes or contents have changed since last
526 redisplay that finished. */
527
528 int windows_or_buffers_changed;
529
530 /* Nonzero means a frame's cursor type has been changed. */
531
532 int cursor_type_changed;
533
534 /* Nonzero after display_mode_line if %l was used and it displayed a
535 line number. */
536
537 int line_number_displayed;
538
539 /* Maximum buffer size for which to display line numbers. */
540
541 Lisp_Object Vline_number_display_limit;
542
543 /* Line width to consider when repositioning for line number display. */
544
545 static EMACS_INT line_number_display_limit_width;
546
547 /* Number of lines to keep in the message log buffer. t means
548 infinite. nil means don't log at all. */
549
550 Lisp_Object Vmessage_log_max;
551
552 /* The name of the *Messages* buffer, a string. */
553
554 static Lisp_Object Vmessages_buffer_name;
555
556 /* Current, index 0, and last displayed echo area message. Either
557 buffers from echo_buffers, or nil to indicate no message. */
558
559 Lisp_Object echo_area_buffer[2];
560
561 /* The buffers referenced from echo_area_buffer. */
562
563 static Lisp_Object echo_buffer[2];
564
565 /* A vector saved used in with_area_buffer to reduce consing. */
566
567 static Lisp_Object Vwith_echo_area_save_vector;
568
569 /* Non-zero means display_echo_area should display the last echo area
570 message again. Set by redisplay_preserve_echo_area. */
571
572 static int display_last_displayed_message_p;
573
574 /* Nonzero if echo area is being used by print; zero if being used by
575 message. */
576
577 int message_buf_print;
578
579 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
580
581 Lisp_Object Qinhibit_menubar_update;
582 int inhibit_menubar_update;
583
584 /* Maximum height for resizing mini-windows. Either a float
585 specifying a fraction of the available height, or an integer
586 specifying a number of lines. */
587
588 Lisp_Object Vmax_mini_window_height;
589
590 /* Non-zero means messages should be displayed with truncated
591 lines instead of being continued. */
592
593 int message_truncate_lines;
594 Lisp_Object Qmessage_truncate_lines;
595
596 /* Set to 1 in clear_message to make redisplay_internal aware
597 of an emptied echo area. */
598
599 static int message_cleared_p;
600
601 /* Non-zero means we want a hollow cursor in windows that are not
602 selected. Zero means there's no cursor in such windows. */
603
604 Lisp_Object Vcursor_in_non_selected_windows;
605 Lisp_Object Qcursor_in_non_selected_windows;
606
607 /* How to blink the default frame cursor off. */
608 Lisp_Object Vblink_cursor_alist;
609
610 /* A scratch glyph row with contents used for generating truncation
611 glyphs. Also used in direct_output_for_insert. */
612
613 #define MAX_SCRATCH_GLYPHS 100
614 struct glyph_row scratch_glyph_row;
615 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
616
617 /* Ascent and height of the last line processed by move_it_to. */
618
619 static int last_max_ascent, last_height;
620
621 /* Non-zero if there's a help-echo in the echo area. */
622
623 int help_echo_showing_p;
624
625 /* If >= 0, computed, exact values of mode-line and header-line height
626 to use in the macros CURRENT_MODE_LINE_HEIGHT and
627 CURRENT_HEADER_LINE_HEIGHT. */
628
629 int current_mode_line_height, current_header_line_height;
630
631 /* The maximum distance to look ahead for text properties. Values
632 that are too small let us call compute_char_face and similar
633 functions too often which is expensive. Values that are too large
634 let us call compute_char_face and alike too often because we
635 might not be interested in text properties that far away. */
636
637 #define TEXT_PROP_DISTANCE_LIMIT 100
638
639 #if GLYPH_DEBUG
640
641 /* Variables to turn off display optimizations from Lisp. */
642
643 int inhibit_try_window_id, inhibit_try_window_reusing;
644 int inhibit_try_cursor_movement;
645
646 /* Non-zero means print traces of redisplay if compiled with
647 GLYPH_DEBUG != 0. */
648
649 int trace_redisplay_p;
650
651 #endif /* GLYPH_DEBUG */
652
653 #ifdef DEBUG_TRACE_MOVE
654 /* Non-zero means trace with TRACE_MOVE to stderr. */
655 int trace_move;
656
657 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
658 #else
659 #define TRACE_MOVE(x) (void) 0
660 #endif
661
662 /* Non-zero means automatically scroll windows horizontally to make
663 point visible. */
664
665 int automatic_hscrolling_p;
666
667 /* How close to the margin can point get before the window is scrolled
668 horizontally. */
669 EMACS_INT hscroll_margin;
670
671 /* How much to scroll horizontally when point is inside the above margin. */
672 Lisp_Object Vhscroll_step;
673
674 /* The variable `resize-mini-windows'. If nil, don't resize
675 mini-windows. If t, always resize them to fit the text they
676 display. If `grow-only', let mini-windows grow only until they
677 become empty. */
678
679 Lisp_Object Vresize_mini_windows;
680
681 /* Buffer being redisplayed -- for redisplay_window_error. */
682
683 struct buffer *displayed_buffer;
684
685 /* Value returned from text property handlers (see below). */
686
687 enum prop_handled
688 {
689 HANDLED_NORMALLY,
690 HANDLED_RECOMPUTE_PROPS,
691 HANDLED_OVERLAY_STRING_CONSUMED,
692 HANDLED_RETURN
693 };
694
695 /* A description of text properties that redisplay is interested
696 in. */
697
698 struct props
699 {
700 /* The name of the property. */
701 Lisp_Object *name;
702
703 /* A unique index for the property. */
704 enum prop_idx idx;
705
706 /* A handler function called to set up iterator IT from the property
707 at IT's current position. Value is used to steer handle_stop. */
708 enum prop_handled (*handler) P_ ((struct it *it));
709 };
710
711 static enum prop_handled handle_face_prop P_ ((struct it *));
712 static enum prop_handled handle_invisible_prop P_ ((struct it *));
713 static enum prop_handled handle_display_prop P_ ((struct it *));
714 static enum prop_handled handle_composition_prop P_ ((struct it *));
715 static enum prop_handled handle_overlay_change P_ ((struct it *));
716 static enum prop_handled handle_fontified_prop P_ ((struct it *));
717
718 /* Properties handled by iterators. */
719
720 static struct props it_props[] =
721 {
722 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
723 /* Handle `face' before `display' because some sub-properties of
724 `display' need to know the face. */
725 {&Qface, FACE_PROP_IDX, handle_face_prop},
726 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
727 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
728 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
729 {NULL, 0, NULL}
730 };
731
732 /* Value is the position described by X. If X is a marker, value is
733 the marker_position of X. Otherwise, value is X. */
734
735 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
736
737 /* Enumeration returned by some move_it_.* functions internally. */
738
739 enum move_it_result
740 {
741 /* Not used. Undefined value. */
742 MOVE_UNDEFINED,
743
744 /* Move ended at the requested buffer position or ZV. */
745 MOVE_POS_MATCH_OR_ZV,
746
747 /* Move ended at the requested X pixel position. */
748 MOVE_X_REACHED,
749
750 /* Move within a line ended at the end of a line that must be
751 continued. */
752 MOVE_LINE_CONTINUED,
753
754 /* Move within a line ended at the end of a line that would
755 be displayed truncated. */
756 MOVE_LINE_TRUNCATED,
757
758 /* Move within a line ended at a line end. */
759 MOVE_NEWLINE_OR_CR
760 };
761
762 /* This counter is used to clear the face cache every once in a while
763 in redisplay_internal. It is incremented for each redisplay.
764 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
765 cleared. */
766
767 #define CLEAR_FACE_CACHE_COUNT 500
768 static int clear_face_cache_count;
769
770 /* Record the previous terminal frame we displayed. */
771
772 static struct frame *previous_terminal_frame;
773
774 /* Non-zero while redisplay_internal is in progress. */
775
776 int redisplaying_p;
777
778 /* Non-zero means don't free realized faces. Bound while freeing
779 realized faces is dangerous because glyph matrices might still
780 reference them. */
781
782 int inhibit_free_realized_faces;
783 Lisp_Object Qinhibit_free_realized_faces;
784
785 /* If a string, XTread_socket generates an event to display that string.
786 (The display is done in read_char.) */
787
788 Lisp_Object help_echo_string;
789 Lisp_Object help_echo_window;
790 Lisp_Object help_echo_object;
791 int help_echo_pos;
792
793 /* Temporary variable for XTread_socket. */
794
795 Lisp_Object previous_help_echo_string;
796
797 /* Null glyph slice */
798
799 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
800
801 \f
802 /* Function prototypes. */
803
804 static void setup_for_ellipsis P_ ((struct it *));
805 static void mark_window_display_accurate_1 P_ ((struct window *, int));
806 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
807 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
808 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
809 static int redisplay_mode_lines P_ ((Lisp_Object, int));
810 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
811
812 #if 0
813 static int invisible_text_between_p P_ ((struct it *, int, int));
814 #endif
815
816 static int next_element_from_ellipsis P_ ((struct it *));
817 static void pint2str P_ ((char *, int, int));
818 static void pint2hrstr P_ ((char *, int, int));
819 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
820 struct text_pos));
821 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
822 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
823 static void store_frame_title_char P_ ((char));
824 static int store_frame_title P_ ((const unsigned char *, int, int));
825 static void x_consider_frame_title P_ ((Lisp_Object));
826 static void handle_stop P_ ((struct it *));
827 static int tool_bar_lines_needed P_ ((struct frame *));
828 static int single_display_prop_intangible_p P_ ((Lisp_Object));
829 static void ensure_echo_area_buffers P_ ((void));
830 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
831 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
832 static int with_echo_area_buffer P_ ((struct window *, int,
833 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
834 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
835 static void clear_garbaged_frames P_ ((void));
836 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
838 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
839 static int display_echo_area P_ ((struct window *));
840 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
841 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
842 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
843 static int string_char_and_length P_ ((const unsigned char *, int, int *));
844 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
845 struct text_pos));
846 static int compute_window_start_on_continuation_line P_ ((struct window *));
847 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
848 static void insert_left_trunc_glyphs P_ ((struct it *));
849 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
850 Lisp_Object));
851 static void extend_face_to_end_of_line P_ ((struct it *));
852 static int append_space_for_newline P_ ((struct it *, int));
853 static int make_cursor_line_fully_visible P_ ((struct window *, int));
854 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
855 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
856 static int trailing_whitespace_p P_ ((int));
857 static int message_log_check_duplicate P_ ((int, int, int, int));
858 static void push_it P_ ((struct it *));
859 static void pop_it P_ ((struct it *));
860 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
861 static void select_frame_for_redisplay P_ ((Lisp_Object));
862 static void redisplay_internal P_ ((int));
863 static int echo_area_display P_ ((int));
864 static void redisplay_windows P_ ((Lisp_Object));
865 static void redisplay_window P_ ((Lisp_Object, int));
866 static Lisp_Object redisplay_window_error ();
867 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
868 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
869 static void update_menu_bar P_ ((struct frame *, int));
870 static int try_window_reusing_current_matrix P_ ((struct window *));
871 static int try_window_id P_ ((struct window *));
872 static int display_line P_ ((struct it *));
873 static int display_mode_lines P_ ((struct window *));
874 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
875 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
876 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
877 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
878 static void display_menu_bar P_ ((struct window *));
879 static int display_count_lines P_ ((int, int, int, int, int *));
880 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
881 int, int, struct it *, int, int, int, int));
882 static void compute_line_metrics P_ ((struct it *));
883 static void run_redisplay_end_trigger_hook P_ ((struct it *));
884 static int get_overlay_strings P_ ((struct it *, int));
885 static void next_overlay_string P_ ((struct it *));
886 static void reseat P_ ((struct it *, struct text_pos, int));
887 static void reseat_1 P_ ((struct it *, struct text_pos, int));
888 static void back_to_previous_visible_line_start P_ ((struct it *));
889 static void reseat_at_previous_visible_line_start P_ ((struct it *));
890 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
891 static int next_element_from_display_vector P_ ((struct it *));
892 static int next_element_from_string P_ ((struct it *));
893 static int next_element_from_c_string P_ ((struct it *));
894 static int next_element_from_buffer P_ ((struct it *));
895 static int next_element_from_composition P_ ((struct it *));
896 static int next_element_from_image P_ ((struct it *));
897 static int next_element_from_stretch P_ ((struct it *));
898 static void load_overlay_strings P_ ((struct it *, int));
899 static int init_from_display_pos P_ ((struct it *, struct window *,
900 struct display_pos *));
901 static void reseat_to_string P_ ((struct it *, unsigned char *,
902 Lisp_Object, int, int, int, int));
903 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
904 int, int, int));
905 void move_it_vertically_backward P_ ((struct it *, int));
906 static void init_to_row_start P_ ((struct it *, struct window *,
907 struct glyph_row *));
908 static int init_to_row_end P_ ((struct it *, struct window *,
909 struct glyph_row *));
910 static void back_to_previous_line_start P_ ((struct it *));
911 static int forward_to_next_line_start P_ ((struct it *, int *));
912 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
913 Lisp_Object, int));
914 static struct text_pos string_pos P_ ((int, Lisp_Object));
915 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
916 static int number_of_chars P_ ((unsigned char *, int));
917 static void compute_stop_pos P_ ((struct it *));
918 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
919 Lisp_Object));
920 static int face_before_or_after_it_pos P_ ((struct it *, int));
921 static int next_overlay_change P_ ((int));
922 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
923 Lisp_Object, struct text_pos *,
924 int));
925 static int underlying_face_id P_ ((struct it *));
926 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
927 struct window *));
928
929 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
930 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
931
932 #ifdef HAVE_WINDOW_SYSTEM
933
934 static void update_tool_bar P_ ((struct frame *, int));
935 static void build_desired_tool_bar_string P_ ((struct frame *f));
936 static int redisplay_tool_bar P_ ((struct frame *));
937 static void display_tool_bar_line P_ ((struct it *));
938 static void notice_overwritten_cursor P_ ((struct window *,
939 enum glyph_row_area,
940 int, int, int, int));
941
942
943
944 #endif /* HAVE_WINDOW_SYSTEM */
945
946 \f
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
950
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
954
955 This is the height of W minus the height of a mode line, if any. */
956
957 INLINE int
958 window_text_bottom_y (w)
959 struct window *w;
960 {
961 int height = WINDOW_TOTAL_HEIGHT (w);
962
963 if (WINDOW_WANTS_MODELINE_P (w))
964 height -= CURRENT_MODE_LINE_HEIGHT (w);
965 return height;
966 }
967
968 /* Return the pixel width of display area AREA of window W. AREA < 0
969 means return the total width of W, not including fringes to
970 the left and right of the window. */
971
972 INLINE int
973 window_box_width (w, area)
974 struct window *w;
975 int area;
976 {
977 int cols = XFASTINT (w->total_cols);
978 int pixels = 0;
979
980 if (!w->pseudo_window_p)
981 {
982 cols -= WINDOW_SCROLL_BAR_COLS (w);
983
984 if (area == TEXT_AREA)
985 {
986 if (INTEGERP (w->left_margin_cols))
987 cols -= XFASTINT (w->left_margin_cols);
988 if (INTEGERP (w->right_margin_cols))
989 cols -= XFASTINT (w->right_margin_cols);
990 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
991 }
992 else if (area == LEFT_MARGIN_AREA)
993 {
994 cols = (INTEGERP (w->left_margin_cols)
995 ? XFASTINT (w->left_margin_cols) : 0);
996 pixels = 0;
997 }
998 else if (area == RIGHT_MARGIN_AREA)
999 {
1000 cols = (INTEGERP (w->right_margin_cols)
1001 ? XFASTINT (w->right_margin_cols) : 0);
1002 pixels = 0;
1003 }
1004 }
1005
1006 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1007 }
1008
1009
1010 /* Return the pixel height of the display area of window W, not
1011 including mode lines of W, if any. */
1012
1013 INLINE int
1014 window_box_height (w)
1015 struct window *w;
1016 {
1017 struct frame *f = XFRAME (w->frame);
1018 int height = WINDOW_TOTAL_HEIGHT (w);
1019
1020 xassert (height >= 0);
1021
1022 /* Note: the code below that determines the mode-line/header-line
1023 height is essentially the same as that contained in the macro
1024 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1025 the appropriate glyph row has its `mode_line_p' flag set,
1026 and if it doesn't, uses estimate_mode_line_height instead. */
1027
1028 if (WINDOW_WANTS_MODELINE_P (w))
1029 {
1030 struct glyph_row *ml_row
1031 = (w->current_matrix && w->current_matrix->rows
1032 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1033 : 0);
1034 if (ml_row && ml_row->mode_line_p)
1035 height -= ml_row->height;
1036 else
1037 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1038 }
1039
1040 if (WINDOW_WANTS_HEADER_LINE_P (w))
1041 {
1042 struct glyph_row *hl_row
1043 = (w->current_matrix && w->current_matrix->rows
1044 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1045 : 0);
1046 if (hl_row && hl_row->mode_line_p)
1047 height -= hl_row->height;
1048 else
1049 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1050 }
1051
1052 /* With a very small font and a mode-line that's taller than
1053 default, we might end up with a negative height. */
1054 return max (0, height);
1055 }
1056
1057 /* Return the window-relative coordinate of the left edge of display
1058 area AREA of window W. AREA < 0 means return the left edge of the
1059 whole window, to the right of the left fringe of W. */
1060
1061 INLINE int
1062 window_box_left_offset (w, area)
1063 struct window *w;
1064 int area;
1065 {
1066 int x;
1067
1068 if (w->pseudo_window_p)
1069 return 0;
1070
1071 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1072
1073 if (area == TEXT_AREA)
1074 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1075 + window_box_width (w, LEFT_MARGIN_AREA));
1076 else if (area == RIGHT_MARGIN_AREA)
1077 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1078 + window_box_width (w, LEFT_MARGIN_AREA)
1079 + window_box_width (w, TEXT_AREA)
1080 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1081 ? 0
1082 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1083 else if (area == LEFT_MARGIN_AREA
1084 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1085 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1086
1087 return x;
1088 }
1089
1090
1091 /* Return the window-relative coordinate of the right edge of display
1092 area AREA of window W. AREA < 0 means return the left edge of the
1093 whole window, to the left of the right fringe of W. */
1094
1095 INLINE int
1096 window_box_right_offset (w, area)
1097 struct window *w;
1098 int area;
1099 {
1100 return window_box_left_offset (w, area) + window_box_width (w, area);
1101 }
1102
1103 /* Return the frame-relative coordinate of the left edge of display
1104 area AREA of window W. AREA < 0 means return the left edge of the
1105 whole window, to the right of the left fringe of W. */
1106
1107 INLINE int
1108 window_box_left (w, area)
1109 struct window *w;
1110 int area;
1111 {
1112 struct frame *f = XFRAME (w->frame);
1113 int x;
1114
1115 if (w->pseudo_window_p)
1116 return FRAME_INTERNAL_BORDER_WIDTH (f);
1117
1118 x = (WINDOW_LEFT_EDGE_X (w)
1119 + window_box_left_offset (w, area));
1120
1121 return x;
1122 }
1123
1124
1125 /* Return the frame-relative coordinate of the right edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the left of the right fringe of W. */
1128
1129 INLINE int
1130 window_box_right (w, area)
1131 struct window *w;
1132 int area;
1133 {
1134 return window_box_left (w, area) + window_box_width (w, area);
1135 }
1136
1137 /* Get the bounding box of the display area AREA of window W, without
1138 mode lines, in frame-relative coordinates. AREA < 0 means the
1139 whole window, not including the left and right fringes of
1140 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1141 coordinates of the upper-left corner of the box. Return in
1142 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1143
1144 INLINE void
1145 window_box (w, area, box_x, box_y, box_width, box_height)
1146 struct window *w;
1147 int area;
1148 int *box_x, *box_y, *box_width, *box_height;
1149 {
1150 if (box_width)
1151 *box_width = window_box_width (w, area);
1152 if (box_height)
1153 *box_height = window_box_height (w);
1154 if (box_x)
1155 *box_x = window_box_left (w, area);
1156 if (box_y)
1157 {
1158 *box_y = WINDOW_TOP_EDGE_Y (w);
1159 if (WINDOW_WANTS_HEADER_LINE_P (w))
1160 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1161 }
1162 }
1163
1164
1165 /* Get the bounding box of the display area AREA of window W, without
1166 mode lines. AREA < 0 means the whole window, not including the
1167 left and right fringe of the window. Return in *TOP_LEFT_X
1168 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1169 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1170 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1171 box. */
1172
1173 INLINE void
1174 window_box_edges (w, area, top_left_x, top_left_y,
1175 bottom_right_x, bottom_right_y)
1176 struct window *w;
1177 int area;
1178 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1179 {
1180 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1181 bottom_right_y);
1182 *bottom_right_x += *top_left_x;
1183 *bottom_right_y += *top_left_y;
1184 }
1185
1186
1187 \f
1188 /***********************************************************************
1189 Utilities
1190 ***********************************************************************/
1191
1192 /* Return the bottom y-position of the line the iterator IT is in.
1193 This can modify IT's settings. */
1194
1195 int
1196 line_bottom_y (it)
1197 struct it *it;
1198 {
1199 int line_height = it->max_ascent + it->max_descent;
1200 int line_top_y = it->current_y;
1201
1202 if (line_height == 0)
1203 {
1204 if (last_height)
1205 line_height = last_height;
1206 else if (IT_CHARPOS (*it) < ZV)
1207 {
1208 move_it_by_lines (it, 1, 1);
1209 line_height = (it->max_ascent || it->max_descent
1210 ? it->max_ascent + it->max_descent
1211 : last_height);
1212 }
1213 else
1214 {
1215 struct glyph_row *row = it->glyph_row;
1216
1217 /* Use the default character height. */
1218 it->glyph_row = NULL;
1219 it->what = IT_CHARACTER;
1220 it->c = ' ';
1221 it->len = 1;
1222 PRODUCE_GLYPHS (it);
1223 line_height = it->ascent + it->descent;
1224 it->glyph_row = row;
1225 }
1226 }
1227
1228 return line_top_y + line_height;
1229 }
1230
1231
1232 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1233 1 if POS is visible and the line containing POS is fully visible.
1234 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1235 and header-lines heights. */
1236
1237 int
1238 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1239 struct window *w;
1240 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1241 {
1242 struct it it;
1243 struct text_pos top;
1244 int visible_p;
1245 struct buffer *old_buffer = NULL;
1246
1247 if (XBUFFER (w->buffer) != current_buffer)
1248 {
1249 old_buffer = current_buffer;
1250 set_buffer_internal_1 (XBUFFER (w->buffer));
1251 }
1252
1253 *fully = visible_p = 0;
1254 SET_TEXT_POS_FROM_MARKER (top, w->start);
1255
1256 /* Compute exact mode line heights, if requested. */
1257 if (exact_mode_line_heights_p)
1258 {
1259 if (WINDOW_WANTS_MODELINE_P (w))
1260 current_mode_line_height
1261 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1262 current_buffer->mode_line_format);
1263
1264 if (WINDOW_WANTS_HEADER_LINE_P (w))
1265 current_header_line_height
1266 = display_mode_line (w, HEADER_LINE_FACE_ID,
1267 current_buffer->header_line_format);
1268 }
1269
1270 start_display (&it, w, top);
1271 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1272 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1273
1274 /* Note that we may overshoot because of invisible text. */
1275 if (IT_CHARPOS (it) >= charpos)
1276 {
1277 int top_y = it.current_y;
1278 int bottom_y = line_bottom_y (&it);
1279 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1280
1281 if (top_y < window_top_y)
1282 visible_p = bottom_y > window_top_y;
1283 else if (top_y < it.last_visible_y)
1284 {
1285 visible_p = 1;
1286 *fully = bottom_y <= it.last_visible_y;
1287 }
1288 if (visible_p && x)
1289 {
1290 *x = it.current_x;
1291 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1292 }
1293 }
1294 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1295 {
1296 struct it it2;
1297
1298 it2 = it;
1299 move_it_by_lines (&it, 1, 0);
1300 if (charpos < IT_CHARPOS (it))
1301 {
1302 visible_p = 1;
1303 if (x)
1304 {
1305 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1306 *x = it2.current_x;
1307 *y = it2.current_y + it2.max_ascent - it2.ascent;
1308 }
1309 }
1310 }
1311
1312 if (old_buffer)
1313 set_buffer_internal_1 (old_buffer);
1314
1315 current_header_line_height = current_mode_line_height = -1;
1316
1317 return visible_p;
1318 }
1319
1320
1321 /* Return the next character from STR which is MAXLEN bytes long.
1322 Return in *LEN the length of the character. This is like
1323 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1324 we find one, we return a `?', but with the length of the invalid
1325 character. */
1326
1327 static INLINE int
1328 string_char_and_length (str, maxlen, len)
1329 const unsigned char *str;
1330 int maxlen, *len;
1331 {
1332 int c;
1333
1334 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1335 if (!CHAR_VALID_P (c, 1))
1336 /* We may not change the length here because other places in Emacs
1337 don't use this function, i.e. they silently accept invalid
1338 characters. */
1339 c = '?';
1340
1341 return c;
1342 }
1343
1344
1345
1346 /* Given a position POS containing a valid character and byte position
1347 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1348
1349 static struct text_pos
1350 string_pos_nchars_ahead (pos, string, nchars)
1351 struct text_pos pos;
1352 Lisp_Object string;
1353 int nchars;
1354 {
1355 xassert (STRINGP (string) && nchars >= 0);
1356
1357 if (STRING_MULTIBYTE (string))
1358 {
1359 int rest = SBYTES (string) - BYTEPOS (pos);
1360 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1361 int len;
1362
1363 while (nchars--)
1364 {
1365 string_char_and_length (p, rest, &len);
1366 p += len, rest -= len;
1367 xassert (rest >= 0);
1368 CHARPOS (pos) += 1;
1369 BYTEPOS (pos) += len;
1370 }
1371 }
1372 else
1373 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1374
1375 return pos;
1376 }
1377
1378
1379 /* Value is the text position, i.e. character and byte position,
1380 for character position CHARPOS in STRING. */
1381
1382 static INLINE struct text_pos
1383 string_pos (charpos, string)
1384 int charpos;
1385 Lisp_Object string;
1386 {
1387 struct text_pos pos;
1388 xassert (STRINGP (string));
1389 xassert (charpos >= 0);
1390 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1391 return pos;
1392 }
1393
1394
1395 /* Value is a text position, i.e. character and byte position, for
1396 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1397 means recognize multibyte characters. */
1398
1399 static struct text_pos
1400 c_string_pos (charpos, s, multibyte_p)
1401 int charpos;
1402 unsigned char *s;
1403 int multibyte_p;
1404 {
1405 struct text_pos pos;
1406
1407 xassert (s != NULL);
1408 xassert (charpos >= 0);
1409
1410 if (multibyte_p)
1411 {
1412 int rest = strlen (s), len;
1413
1414 SET_TEXT_POS (pos, 0, 0);
1415 while (charpos--)
1416 {
1417 string_char_and_length (s, rest, &len);
1418 s += len, rest -= len;
1419 xassert (rest >= 0);
1420 CHARPOS (pos) += 1;
1421 BYTEPOS (pos) += len;
1422 }
1423 }
1424 else
1425 SET_TEXT_POS (pos, charpos, charpos);
1426
1427 return pos;
1428 }
1429
1430
1431 /* Value is the number of characters in C string S. MULTIBYTE_P
1432 non-zero means recognize multibyte characters. */
1433
1434 static int
1435 number_of_chars (s, multibyte_p)
1436 unsigned char *s;
1437 int multibyte_p;
1438 {
1439 int nchars;
1440
1441 if (multibyte_p)
1442 {
1443 int rest = strlen (s), len;
1444 unsigned char *p = (unsigned char *) s;
1445
1446 for (nchars = 0; rest > 0; ++nchars)
1447 {
1448 string_char_and_length (p, rest, &len);
1449 rest -= len, p += len;
1450 }
1451 }
1452 else
1453 nchars = strlen (s);
1454
1455 return nchars;
1456 }
1457
1458
1459 /* Compute byte position NEWPOS->bytepos corresponding to
1460 NEWPOS->charpos. POS is a known position in string STRING.
1461 NEWPOS->charpos must be >= POS.charpos. */
1462
1463 static void
1464 compute_string_pos (newpos, pos, string)
1465 struct text_pos *newpos, pos;
1466 Lisp_Object string;
1467 {
1468 xassert (STRINGP (string));
1469 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1470
1471 if (STRING_MULTIBYTE (string))
1472 *newpos = string_pos_nchars_ahead (pos, string,
1473 CHARPOS (*newpos) - CHARPOS (pos));
1474 else
1475 BYTEPOS (*newpos) = CHARPOS (*newpos);
1476 }
1477
1478 /* EXPORT:
1479 Return an estimation of the pixel height of mode or top lines on
1480 frame F. FACE_ID specifies what line's height to estimate. */
1481
1482 int
1483 estimate_mode_line_height (f, face_id)
1484 struct frame *f;
1485 enum face_id face_id;
1486 {
1487 #ifdef HAVE_WINDOW_SYSTEM
1488 if (FRAME_WINDOW_P (f))
1489 {
1490 int height = FONT_HEIGHT (FRAME_FONT (f));
1491
1492 /* This function is called so early when Emacs starts that the face
1493 cache and mode line face are not yet initialized. */
1494 if (FRAME_FACE_CACHE (f))
1495 {
1496 struct face *face = FACE_FROM_ID (f, face_id);
1497 if (face)
1498 {
1499 if (face->font)
1500 height = FONT_HEIGHT (face->font);
1501 if (face->box_line_width > 0)
1502 height += 2 * face->box_line_width;
1503 }
1504 }
1505
1506 return height;
1507 }
1508 #endif
1509
1510 return 1;
1511 }
1512
1513 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1514 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1515 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1516 not force the value into range. */
1517
1518 void
1519 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1520 FRAME_PTR f;
1521 register int pix_x, pix_y;
1522 int *x, *y;
1523 NativeRectangle *bounds;
1524 int noclip;
1525 {
1526
1527 #ifdef HAVE_WINDOW_SYSTEM
1528 if (FRAME_WINDOW_P (f))
1529 {
1530 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1531 even for negative values. */
1532 if (pix_x < 0)
1533 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1534 if (pix_y < 0)
1535 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1536
1537 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1538 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1539
1540 if (bounds)
1541 STORE_NATIVE_RECT (*bounds,
1542 FRAME_COL_TO_PIXEL_X (f, pix_x),
1543 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1544 FRAME_COLUMN_WIDTH (f) - 1,
1545 FRAME_LINE_HEIGHT (f) - 1);
1546
1547 if (!noclip)
1548 {
1549 if (pix_x < 0)
1550 pix_x = 0;
1551 else if (pix_x > FRAME_TOTAL_COLS (f))
1552 pix_x = FRAME_TOTAL_COLS (f);
1553
1554 if (pix_y < 0)
1555 pix_y = 0;
1556 else if (pix_y > FRAME_LINES (f))
1557 pix_y = FRAME_LINES (f);
1558 }
1559 }
1560 #endif
1561
1562 *x = pix_x;
1563 *y = pix_y;
1564 }
1565
1566
1567 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1568 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1569 can't tell the positions because W's display is not up to date,
1570 return 0. */
1571
1572 int
1573 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1574 struct window *w;
1575 int hpos, vpos;
1576 int *frame_x, *frame_y;
1577 {
1578 #ifdef HAVE_WINDOW_SYSTEM
1579 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1580 {
1581 int success_p;
1582
1583 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1584 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1585
1586 if (display_completed)
1587 {
1588 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1589 struct glyph *glyph = row->glyphs[TEXT_AREA];
1590 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1591
1592 hpos = row->x;
1593 vpos = row->y;
1594 while (glyph < end)
1595 {
1596 hpos += glyph->pixel_width;
1597 ++glyph;
1598 }
1599
1600 /* If first glyph is partially visible, its first visible position is still 0. */
1601 if (hpos < 0)
1602 hpos = 0;
1603
1604 success_p = 1;
1605 }
1606 else
1607 {
1608 hpos = vpos = 0;
1609 success_p = 0;
1610 }
1611
1612 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1613 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1614 return success_p;
1615 }
1616 #endif
1617
1618 *frame_x = hpos;
1619 *frame_y = vpos;
1620 return 1;
1621 }
1622
1623
1624 #ifdef HAVE_WINDOW_SYSTEM
1625
1626 /* Find the glyph under window-relative coordinates X/Y in window W.
1627 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1628 strings. Return in *HPOS and *VPOS the row and column number of
1629 the glyph found. Return in *AREA the glyph area containing X.
1630 Value is a pointer to the glyph found or null if X/Y is not on
1631 text, or we can't tell because W's current matrix is not up to
1632 date. */
1633
1634 static struct glyph *
1635 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1636 struct window *w;
1637 int x, y;
1638 int *hpos, *vpos, *dx, *dy, *area;
1639 {
1640 struct glyph *glyph, *end;
1641 struct glyph_row *row = NULL;
1642 int x0, i;
1643
1644 /* Find row containing Y. Give up if some row is not enabled. */
1645 for (i = 0; i < w->current_matrix->nrows; ++i)
1646 {
1647 row = MATRIX_ROW (w->current_matrix, i);
1648 if (!row->enabled_p)
1649 return NULL;
1650 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1651 break;
1652 }
1653
1654 *vpos = i;
1655 *hpos = 0;
1656
1657 /* Give up if Y is not in the window. */
1658 if (i == w->current_matrix->nrows)
1659 return NULL;
1660
1661 /* Get the glyph area containing X. */
1662 if (w->pseudo_window_p)
1663 {
1664 *area = TEXT_AREA;
1665 x0 = 0;
1666 }
1667 else
1668 {
1669 if (x < window_box_left_offset (w, TEXT_AREA))
1670 {
1671 *area = LEFT_MARGIN_AREA;
1672 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1673 }
1674 else if (x < window_box_right_offset (w, TEXT_AREA))
1675 {
1676 *area = TEXT_AREA;
1677 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1678 }
1679 else
1680 {
1681 *area = RIGHT_MARGIN_AREA;
1682 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1683 }
1684 }
1685
1686 /* Find glyph containing X. */
1687 glyph = row->glyphs[*area];
1688 end = glyph + row->used[*area];
1689 x -= x0;
1690 while (glyph < end && x >= glyph->pixel_width)
1691 {
1692 x -= glyph->pixel_width;
1693 ++glyph;
1694 }
1695
1696 if (glyph == end)
1697 return NULL;
1698
1699 if (dx)
1700 {
1701 *dx = x;
1702 *dy = y - (row->y + row->ascent - glyph->ascent);
1703 }
1704
1705 *hpos = glyph - row->glyphs[*area];
1706 return glyph;
1707 }
1708
1709
1710 /* EXPORT:
1711 Convert frame-relative x/y to coordinates relative to window W.
1712 Takes pseudo-windows into account. */
1713
1714 void
1715 frame_to_window_pixel_xy (w, x, y)
1716 struct window *w;
1717 int *x, *y;
1718 {
1719 if (w->pseudo_window_p)
1720 {
1721 /* A pseudo-window is always full-width, and starts at the
1722 left edge of the frame, plus a frame border. */
1723 struct frame *f = XFRAME (w->frame);
1724 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1725 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1726 }
1727 else
1728 {
1729 *x -= WINDOW_LEFT_EDGE_X (w);
1730 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1731 }
1732 }
1733
1734 /* EXPORT:
1735 Return in *R the clipping rectangle for glyph string S. */
1736
1737 void
1738 get_glyph_string_clip_rect (s, nr)
1739 struct glyph_string *s;
1740 NativeRectangle *nr;
1741 {
1742 XRectangle r;
1743
1744 if (s->row->full_width_p)
1745 {
1746 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1747 r.x = WINDOW_LEFT_EDGE_X (s->w);
1748 r.width = WINDOW_TOTAL_WIDTH (s->w);
1749
1750 /* Unless displaying a mode or menu bar line, which are always
1751 fully visible, clip to the visible part of the row. */
1752 if (s->w->pseudo_window_p)
1753 r.height = s->row->visible_height;
1754 else
1755 r.height = s->height;
1756 }
1757 else
1758 {
1759 /* This is a text line that may be partially visible. */
1760 r.x = window_box_left (s->w, s->area);
1761 r.width = window_box_width (s->w, s->area);
1762 r.height = s->row->visible_height;
1763 }
1764
1765 /* If S draws overlapping rows, it's sufficient to use the top and
1766 bottom of the window for clipping because this glyph string
1767 intentionally draws over other lines. */
1768 if (s->for_overlaps_p)
1769 {
1770 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1771 r.height = window_text_bottom_y (s->w) - r.y;
1772 }
1773 else
1774 {
1775 /* Don't use S->y for clipping because it doesn't take partially
1776 visible lines into account. For example, it can be negative for
1777 partially visible lines at the top of a window. */
1778 if (!s->row->full_width_p
1779 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1780 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1781 else
1782 r.y = max (0, s->row->y);
1783
1784 /* If drawing a tool-bar window, draw it over the internal border
1785 at the top of the window. */
1786 if (s->w == XWINDOW (s->f->tool_bar_window))
1787 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1788 }
1789
1790 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1791
1792 /* If drawing the cursor, don't let glyph draw outside its
1793 advertised boundaries. Cleartype does this under some circumstances. */
1794 if (s->hl == DRAW_CURSOR)
1795 {
1796 struct glyph *glyph = s->first_glyph;
1797 int height;
1798
1799 if (s->x > r.x)
1800 {
1801 r.width -= s->x - r.x;
1802 r.x = s->x;
1803 }
1804 r.width = min (r.width, glyph->pixel_width);
1805
1806 /* Don't draw cursor glyph taller than our actual glyph. */
1807 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1808 if (height < r.height)
1809 {
1810 int max_y = r.y + r.height;
1811 r.y = min (max_y, s->ybase + glyph->descent - height);
1812 r.height = min (max_y - r.y, height);
1813 }
1814 }
1815
1816 #ifdef CONVERT_FROM_XRECT
1817 CONVERT_FROM_XRECT (r, *nr);
1818 #else
1819 *nr = r;
1820 #endif
1821 }
1822
1823 #endif /* HAVE_WINDOW_SYSTEM */
1824
1825 \f
1826 /***********************************************************************
1827 Lisp form evaluation
1828 ***********************************************************************/
1829
1830 /* Error handler for safe_eval and safe_call. */
1831
1832 static Lisp_Object
1833 safe_eval_handler (arg)
1834 Lisp_Object arg;
1835 {
1836 add_to_log ("Error during redisplay: %s", arg, Qnil);
1837 return Qnil;
1838 }
1839
1840
1841 /* Evaluate SEXPR and return the result, or nil if something went
1842 wrong. Prevent redisplay during the evaluation. */
1843
1844 Lisp_Object
1845 safe_eval (sexpr)
1846 Lisp_Object sexpr;
1847 {
1848 Lisp_Object val;
1849
1850 if (inhibit_eval_during_redisplay)
1851 val = Qnil;
1852 else
1853 {
1854 int count = SPECPDL_INDEX ();
1855 struct gcpro gcpro1;
1856
1857 GCPRO1 (sexpr);
1858 specbind (Qinhibit_redisplay, Qt);
1859 /* Use Qt to ensure debugger does not run,
1860 so there is no possibility of wanting to redisplay. */
1861 val = internal_condition_case_1 (Feval, sexpr, Qt,
1862 safe_eval_handler);
1863 UNGCPRO;
1864 val = unbind_to (count, val);
1865 }
1866
1867 return val;
1868 }
1869
1870
1871 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1872 Return the result, or nil if something went wrong. Prevent
1873 redisplay during the evaluation. */
1874
1875 Lisp_Object
1876 safe_call (nargs, args)
1877 int nargs;
1878 Lisp_Object *args;
1879 {
1880 Lisp_Object val;
1881
1882 if (inhibit_eval_during_redisplay)
1883 val = Qnil;
1884 else
1885 {
1886 int count = SPECPDL_INDEX ();
1887 struct gcpro gcpro1;
1888
1889 GCPRO1 (args[0]);
1890 gcpro1.nvars = nargs;
1891 specbind (Qinhibit_redisplay, Qt);
1892 /* Use Qt to ensure debugger does not run,
1893 so there is no possibility of wanting to redisplay. */
1894 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1895 safe_eval_handler);
1896 UNGCPRO;
1897 val = unbind_to (count, val);
1898 }
1899
1900 return val;
1901 }
1902
1903
1904 /* Call function FN with one argument ARG.
1905 Return the result, or nil if something went wrong. */
1906
1907 Lisp_Object
1908 safe_call1 (fn, arg)
1909 Lisp_Object fn, arg;
1910 {
1911 Lisp_Object args[2];
1912 args[0] = fn;
1913 args[1] = arg;
1914 return safe_call (2, args);
1915 }
1916
1917
1918 \f
1919 /***********************************************************************
1920 Debugging
1921 ***********************************************************************/
1922
1923 #if 0
1924
1925 /* Define CHECK_IT to perform sanity checks on iterators.
1926 This is for debugging. It is too slow to do unconditionally. */
1927
1928 static void
1929 check_it (it)
1930 struct it *it;
1931 {
1932 if (it->method == next_element_from_string)
1933 {
1934 xassert (STRINGP (it->string));
1935 xassert (IT_STRING_CHARPOS (*it) >= 0);
1936 }
1937 else
1938 {
1939 xassert (IT_STRING_CHARPOS (*it) < 0);
1940 if (it->method == next_element_from_buffer)
1941 {
1942 /* Check that character and byte positions agree. */
1943 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1944 }
1945 }
1946
1947 if (it->dpvec)
1948 xassert (it->current.dpvec_index >= 0);
1949 else
1950 xassert (it->current.dpvec_index < 0);
1951 }
1952
1953 #define CHECK_IT(IT) check_it ((IT))
1954
1955 #else /* not 0 */
1956
1957 #define CHECK_IT(IT) (void) 0
1958
1959 #endif /* not 0 */
1960
1961
1962 #if GLYPH_DEBUG
1963
1964 /* Check that the window end of window W is what we expect it
1965 to be---the last row in the current matrix displaying text. */
1966
1967 static void
1968 check_window_end (w)
1969 struct window *w;
1970 {
1971 if (!MINI_WINDOW_P (w)
1972 && !NILP (w->window_end_valid))
1973 {
1974 struct glyph_row *row;
1975 xassert ((row = MATRIX_ROW (w->current_matrix,
1976 XFASTINT (w->window_end_vpos)),
1977 !row->enabled_p
1978 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1979 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1980 }
1981 }
1982
1983 #define CHECK_WINDOW_END(W) check_window_end ((W))
1984
1985 #else /* not GLYPH_DEBUG */
1986
1987 #define CHECK_WINDOW_END(W) (void) 0
1988
1989 #endif /* not GLYPH_DEBUG */
1990
1991
1992 \f
1993 /***********************************************************************
1994 Iterator initialization
1995 ***********************************************************************/
1996
1997 /* Initialize IT for displaying current_buffer in window W, starting
1998 at character position CHARPOS. CHARPOS < 0 means that no buffer
1999 position is specified which is useful when the iterator is assigned
2000 a position later. BYTEPOS is the byte position corresponding to
2001 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2002
2003 If ROW is not null, calls to produce_glyphs with IT as parameter
2004 will produce glyphs in that row.
2005
2006 BASE_FACE_ID is the id of a base face to use. It must be one of
2007 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2008 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2009 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2010
2011 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2012 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2013 will be initialized to use the corresponding mode line glyph row of
2014 the desired matrix of W. */
2015
2016 void
2017 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2018 struct it *it;
2019 struct window *w;
2020 int charpos, bytepos;
2021 struct glyph_row *row;
2022 enum face_id base_face_id;
2023 {
2024 int highlight_region_p;
2025
2026 /* Some precondition checks. */
2027 xassert (w != NULL && it != NULL);
2028 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2029 && charpos <= ZV));
2030
2031 /* If face attributes have been changed since the last redisplay,
2032 free realized faces now because they depend on face definitions
2033 that might have changed. Don't free faces while there might be
2034 desired matrices pending which reference these faces. */
2035 if (face_change_count && !inhibit_free_realized_faces)
2036 {
2037 face_change_count = 0;
2038 free_all_realized_faces (Qnil);
2039 }
2040
2041 /* Use one of the mode line rows of W's desired matrix if
2042 appropriate. */
2043 if (row == NULL)
2044 {
2045 if (base_face_id == MODE_LINE_FACE_ID
2046 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2047 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2048 else if (base_face_id == HEADER_LINE_FACE_ID)
2049 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2050 }
2051
2052 /* Clear IT. */
2053 bzero (it, sizeof *it);
2054 it->current.overlay_string_index = -1;
2055 it->current.dpvec_index = -1;
2056 it->base_face_id = base_face_id;
2057 it->string = Qnil;
2058 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2059
2060 /* The window in which we iterate over current_buffer: */
2061 XSETWINDOW (it->window, w);
2062 it->w = w;
2063 it->f = XFRAME (w->frame);
2064
2065 /* Extra space between lines (on window systems only). */
2066 if (base_face_id == DEFAULT_FACE_ID
2067 && FRAME_WINDOW_P (it->f))
2068 {
2069 if (NATNUMP (current_buffer->extra_line_spacing))
2070 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2071 else if (FLOATP (current_buffer->extra_line_spacing))
2072 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2073 * FRAME_LINE_HEIGHT (it->f));
2074 else if (it->f->extra_line_spacing > 0)
2075 it->extra_line_spacing = it->f->extra_line_spacing;
2076 }
2077
2078 /* If realized faces have been removed, e.g. because of face
2079 attribute changes of named faces, recompute them. When running
2080 in batch mode, the face cache of Vterminal_frame is null. If
2081 we happen to get called, make a dummy face cache. */
2082 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2083 init_frame_faces (it->f);
2084 if (FRAME_FACE_CACHE (it->f)->used == 0)
2085 recompute_basic_faces (it->f);
2086
2087 /* Current value of the `slice', `space-width', and 'height' properties. */
2088 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2089 it->space_width = Qnil;
2090 it->font_height = Qnil;
2091 it->override_ascent = -1;
2092
2093 /* Are control characters displayed as `^C'? */
2094 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2095
2096 /* -1 means everything between a CR and the following line end
2097 is invisible. >0 means lines indented more than this value are
2098 invisible. */
2099 it->selective = (INTEGERP (current_buffer->selective_display)
2100 ? XFASTINT (current_buffer->selective_display)
2101 : (!NILP (current_buffer->selective_display)
2102 ? -1 : 0));
2103 it->selective_display_ellipsis_p
2104 = !NILP (current_buffer->selective_display_ellipses);
2105
2106 /* Display table to use. */
2107 it->dp = window_display_table (w);
2108
2109 /* Are multibyte characters enabled in current_buffer? */
2110 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2111
2112 /* Non-zero if we should highlight the region. */
2113 highlight_region_p
2114 = (!NILP (Vtransient_mark_mode)
2115 && !NILP (current_buffer->mark_active)
2116 && XMARKER (current_buffer->mark)->buffer != 0);
2117
2118 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2119 start and end of a visible region in window IT->w. Set both to
2120 -1 to indicate no region. */
2121 if (highlight_region_p
2122 /* Maybe highlight only in selected window. */
2123 && (/* Either show region everywhere. */
2124 highlight_nonselected_windows
2125 /* Or show region in the selected window. */
2126 || w == XWINDOW (selected_window)
2127 /* Or show the region if we are in the mini-buffer and W is
2128 the window the mini-buffer refers to. */
2129 || (MINI_WINDOW_P (XWINDOW (selected_window))
2130 && WINDOWP (minibuf_selected_window)
2131 && w == XWINDOW (minibuf_selected_window))))
2132 {
2133 int charpos = marker_position (current_buffer->mark);
2134 it->region_beg_charpos = min (PT, charpos);
2135 it->region_end_charpos = max (PT, charpos);
2136 }
2137 else
2138 it->region_beg_charpos = it->region_end_charpos = -1;
2139
2140 /* Get the position at which the redisplay_end_trigger hook should
2141 be run, if it is to be run at all. */
2142 if (MARKERP (w->redisplay_end_trigger)
2143 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2144 it->redisplay_end_trigger_charpos
2145 = marker_position (w->redisplay_end_trigger);
2146 else if (INTEGERP (w->redisplay_end_trigger))
2147 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2148
2149 /* Correct bogus values of tab_width. */
2150 it->tab_width = XINT (current_buffer->tab_width);
2151 if (it->tab_width <= 0 || it->tab_width > 1000)
2152 it->tab_width = 8;
2153
2154 /* Are lines in the display truncated? */
2155 it->truncate_lines_p
2156 = (base_face_id != DEFAULT_FACE_ID
2157 || XINT (it->w->hscroll)
2158 || (truncate_partial_width_windows
2159 && !WINDOW_FULL_WIDTH_P (it->w))
2160 || !NILP (current_buffer->truncate_lines));
2161
2162 /* Get dimensions of truncation and continuation glyphs. These are
2163 displayed as fringe bitmaps under X, so we don't need them for such
2164 frames. */
2165 if (!FRAME_WINDOW_P (it->f))
2166 {
2167 if (it->truncate_lines_p)
2168 {
2169 /* We will need the truncation glyph. */
2170 xassert (it->glyph_row == NULL);
2171 produce_special_glyphs (it, IT_TRUNCATION);
2172 it->truncation_pixel_width = it->pixel_width;
2173 }
2174 else
2175 {
2176 /* We will need the continuation glyph. */
2177 xassert (it->glyph_row == NULL);
2178 produce_special_glyphs (it, IT_CONTINUATION);
2179 it->continuation_pixel_width = it->pixel_width;
2180 }
2181
2182 /* Reset these values to zero because the produce_special_glyphs
2183 above has changed them. */
2184 it->pixel_width = it->ascent = it->descent = 0;
2185 it->phys_ascent = it->phys_descent = 0;
2186 }
2187
2188 /* Set this after getting the dimensions of truncation and
2189 continuation glyphs, so that we don't produce glyphs when calling
2190 produce_special_glyphs, above. */
2191 it->glyph_row = row;
2192 it->area = TEXT_AREA;
2193
2194 /* Get the dimensions of the display area. The display area
2195 consists of the visible window area plus a horizontally scrolled
2196 part to the left of the window. All x-values are relative to the
2197 start of this total display area. */
2198 if (base_face_id != DEFAULT_FACE_ID)
2199 {
2200 /* Mode lines, menu bar in terminal frames. */
2201 it->first_visible_x = 0;
2202 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2203 }
2204 else
2205 {
2206 it->first_visible_x
2207 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2208 it->last_visible_x = (it->first_visible_x
2209 + window_box_width (w, TEXT_AREA));
2210
2211 /* If we truncate lines, leave room for the truncator glyph(s) at
2212 the right margin. Otherwise, leave room for the continuation
2213 glyph(s). Truncation and continuation glyphs are not inserted
2214 for window-based redisplay. */
2215 if (!FRAME_WINDOW_P (it->f))
2216 {
2217 if (it->truncate_lines_p)
2218 it->last_visible_x -= it->truncation_pixel_width;
2219 else
2220 it->last_visible_x -= it->continuation_pixel_width;
2221 }
2222
2223 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2224 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2225 }
2226
2227 /* Leave room for a border glyph. */
2228 if (!FRAME_WINDOW_P (it->f)
2229 && !WINDOW_RIGHTMOST_P (it->w))
2230 it->last_visible_x -= 1;
2231
2232 it->last_visible_y = window_text_bottom_y (w);
2233
2234 /* For mode lines and alike, arrange for the first glyph having a
2235 left box line if the face specifies a box. */
2236 if (base_face_id != DEFAULT_FACE_ID)
2237 {
2238 struct face *face;
2239
2240 it->face_id = base_face_id;
2241
2242 /* If we have a boxed mode line, make the first character appear
2243 with a left box line. */
2244 face = FACE_FROM_ID (it->f, base_face_id);
2245 if (face->box != FACE_NO_BOX)
2246 it->start_of_box_run_p = 1;
2247 }
2248
2249 /* If a buffer position was specified, set the iterator there,
2250 getting overlays and face properties from that position. */
2251 if (charpos >= BUF_BEG (current_buffer))
2252 {
2253 it->end_charpos = ZV;
2254 it->face_id = -1;
2255 IT_CHARPOS (*it) = charpos;
2256
2257 /* Compute byte position if not specified. */
2258 if (bytepos < charpos)
2259 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2260 else
2261 IT_BYTEPOS (*it) = bytepos;
2262
2263 it->start = it->current;
2264
2265 /* Compute faces etc. */
2266 reseat (it, it->current.pos, 1);
2267 }
2268
2269 CHECK_IT (it);
2270 }
2271
2272
2273 /* Initialize IT for the display of window W with window start POS. */
2274
2275 void
2276 start_display (it, w, pos)
2277 struct it *it;
2278 struct window *w;
2279 struct text_pos pos;
2280 {
2281 struct glyph_row *row;
2282 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2283
2284 row = w->desired_matrix->rows + first_vpos;
2285 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2286 it->first_vpos = first_vpos;
2287
2288 if (!it->truncate_lines_p)
2289 {
2290 int start_at_line_beg_p;
2291 int first_y = it->current_y;
2292
2293 /* If window start is not at a line start, skip forward to POS to
2294 get the correct continuation lines width. */
2295 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2296 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2297 if (!start_at_line_beg_p)
2298 {
2299 int new_x;
2300
2301 reseat_at_previous_visible_line_start (it);
2302 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2303
2304 new_x = it->current_x + it->pixel_width;
2305
2306 /* If lines are continued, this line may end in the middle
2307 of a multi-glyph character (e.g. a control character
2308 displayed as \003, or in the middle of an overlay
2309 string). In this case move_it_to above will not have
2310 taken us to the start of the continuation line but to the
2311 end of the continued line. */
2312 if (it->current_x > 0
2313 && !it->truncate_lines_p /* Lines are continued. */
2314 && (/* And glyph doesn't fit on the line. */
2315 new_x > it->last_visible_x
2316 /* Or it fits exactly and we're on a window
2317 system frame. */
2318 || (new_x == it->last_visible_x
2319 && FRAME_WINDOW_P (it->f))))
2320 {
2321 if (it->current.dpvec_index >= 0
2322 || it->current.overlay_string_index >= 0)
2323 {
2324 set_iterator_to_next (it, 1);
2325 move_it_in_display_line_to (it, -1, -1, 0);
2326 }
2327
2328 it->continuation_lines_width += it->current_x;
2329 }
2330
2331 /* We're starting a new display line, not affected by the
2332 height of the continued line, so clear the appropriate
2333 fields in the iterator structure. */
2334 it->max_ascent = it->max_descent = 0;
2335 it->max_phys_ascent = it->max_phys_descent = 0;
2336
2337 it->current_y = first_y;
2338 it->vpos = 0;
2339 it->current_x = it->hpos = 0;
2340 }
2341 }
2342
2343 #if 0 /* Don't assert the following because start_display is sometimes
2344 called intentionally with a window start that is not at a
2345 line start. Please leave this code in as a comment. */
2346
2347 /* Window start should be on a line start, now. */
2348 xassert (it->continuation_lines_width
2349 || IT_CHARPOS (it) == BEGV
2350 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2351 #endif /* 0 */
2352 }
2353
2354
2355 /* Return 1 if POS is a position in ellipses displayed for invisible
2356 text. W is the window we display, for text property lookup. */
2357
2358 static int
2359 in_ellipses_for_invisible_text_p (pos, w)
2360 struct display_pos *pos;
2361 struct window *w;
2362 {
2363 Lisp_Object prop, window;
2364 int ellipses_p = 0;
2365 int charpos = CHARPOS (pos->pos);
2366
2367 /* If POS specifies a position in a display vector, this might
2368 be for an ellipsis displayed for invisible text. We won't
2369 get the iterator set up for delivering that ellipsis unless
2370 we make sure that it gets aware of the invisible text. */
2371 if (pos->dpvec_index >= 0
2372 && pos->overlay_string_index < 0
2373 && CHARPOS (pos->string_pos) < 0
2374 && charpos > BEGV
2375 && (XSETWINDOW (window, w),
2376 prop = Fget_char_property (make_number (charpos),
2377 Qinvisible, window),
2378 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2379 {
2380 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2381 window);
2382 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2383 }
2384
2385 return ellipses_p;
2386 }
2387
2388
2389 /* Initialize IT for stepping through current_buffer in window W,
2390 starting at position POS that includes overlay string and display
2391 vector/ control character translation position information. Value
2392 is zero if there are overlay strings with newlines at POS. */
2393
2394 static int
2395 init_from_display_pos (it, w, pos)
2396 struct it *it;
2397 struct window *w;
2398 struct display_pos *pos;
2399 {
2400 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2401 int i, overlay_strings_with_newlines = 0;
2402
2403 /* If POS specifies a position in a display vector, this might
2404 be for an ellipsis displayed for invisible text. We won't
2405 get the iterator set up for delivering that ellipsis unless
2406 we make sure that it gets aware of the invisible text. */
2407 if (in_ellipses_for_invisible_text_p (pos, w))
2408 {
2409 --charpos;
2410 bytepos = 0;
2411 }
2412
2413 /* Keep in mind: the call to reseat in init_iterator skips invisible
2414 text, so we might end up at a position different from POS. This
2415 is only a problem when POS is a row start after a newline and an
2416 overlay starts there with an after-string, and the overlay has an
2417 invisible property. Since we don't skip invisible text in
2418 display_line and elsewhere immediately after consuming the
2419 newline before the row start, such a POS will not be in a string,
2420 but the call to init_iterator below will move us to the
2421 after-string. */
2422 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2423
2424 for (i = 0; i < it->n_overlay_strings; ++i)
2425 {
2426 const char *s = SDATA (it->overlay_strings[i]);
2427 const char *e = s + SBYTES (it->overlay_strings[i]);
2428
2429 while (s < e && *s != '\n')
2430 ++s;
2431
2432 if (s < e)
2433 {
2434 overlay_strings_with_newlines = 1;
2435 break;
2436 }
2437 }
2438
2439 /* If position is within an overlay string, set up IT to the right
2440 overlay string. */
2441 if (pos->overlay_string_index >= 0)
2442 {
2443 int relative_index;
2444
2445 /* If the first overlay string happens to have a `display'
2446 property for an image, the iterator will be set up for that
2447 image, and we have to undo that setup first before we can
2448 correct the overlay string index. */
2449 if (it->method == next_element_from_image)
2450 pop_it (it);
2451
2452 /* We already have the first chunk of overlay strings in
2453 IT->overlay_strings. Load more until the one for
2454 pos->overlay_string_index is in IT->overlay_strings. */
2455 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2456 {
2457 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2458 it->current.overlay_string_index = 0;
2459 while (n--)
2460 {
2461 load_overlay_strings (it, 0);
2462 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2463 }
2464 }
2465
2466 it->current.overlay_string_index = pos->overlay_string_index;
2467 relative_index = (it->current.overlay_string_index
2468 % OVERLAY_STRING_CHUNK_SIZE);
2469 it->string = it->overlay_strings[relative_index];
2470 xassert (STRINGP (it->string));
2471 it->current.string_pos = pos->string_pos;
2472 it->method = next_element_from_string;
2473 }
2474
2475 #if 0 /* This is bogus because POS not having an overlay string
2476 position does not mean it's after the string. Example: A
2477 line starting with a before-string and initialization of IT
2478 to the previous row's end position. */
2479 else if (it->current.overlay_string_index >= 0)
2480 {
2481 /* If POS says we're already after an overlay string ending at
2482 POS, make sure to pop the iterator because it will be in
2483 front of that overlay string. When POS is ZV, we've thereby
2484 also ``processed'' overlay strings at ZV. */
2485 while (it->sp)
2486 pop_it (it);
2487 it->current.overlay_string_index = -1;
2488 it->method = next_element_from_buffer;
2489 if (CHARPOS (pos->pos) == ZV)
2490 it->overlay_strings_at_end_processed_p = 1;
2491 }
2492 #endif /* 0 */
2493
2494 if (CHARPOS (pos->string_pos) >= 0)
2495 {
2496 /* Recorded position is not in an overlay string, but in another
2497 string. This can only be a string from a `display' property.
2498 IT should already be filled with that string. */
2499 it->current.string_pos = pos->string_pos;
2500 xassert (STRINGP (it->string));
2501 }
2502
2503 /* Restore position in display vector translations, control
2504 character translations or ellipses. */
2505 if (pos->dpvec_index >= 0)
2506 {
2507 if (it->dpvec == NULL)
2508 get_next_display_element (it);
2509 xassert (it->dpvec && it->current.dpvec_index == 0);
2510 it->current.dpvec_index = pos->dpvec_index;
2511 }
2512
2513 CHECK_IT (it);
2514 return !overlay_strings_with_newlines;
2515 }
2516
2517
2518 /* Initialize IT for stepping through current_buffer in window W
2519 starting at ROW->start. */
2520
2521 static void
2522 init_to_row_start (it, w, row)
2523 struct it *it;
2524 struct window *w;
2525 struct glyph_row *row;
2526 {
2527 init_from_display_pos (it, w, &row->start);
2528 it->start = row->start;
2529 it->continuation_lines_width = row->continuation_lines_width;
2530 CHECK_IT (it);
2531 }
2532
2533
2534 /* Initialize IT for stepping through current_buffer in window W
2535 starting in the line following ROW, i.e. starting at ROW->end.
2536 Value is zero if there are overlay strings with newlines at ROW's
2537 end position. */
2538
2539 static int
2540 init_to_row_end (it, w, row)
2541 struct it *it;
2542 struct window *w;
2543 struct glyph_row *row;
2544 {
2545 int success = 0;
2546
2547 if (init_from_display_pos (it, w, &row->end))
2548 {
2549 if (row->continued_p)
2550 it->continuation_lines_width
2551 = row->continuation_lines_width + row->pixel_width;
2552 CHECK_IT (it);
2553 success = 1;
2554 }
2555
2556 return success;
2557 }
2558
2559
2560
2561 \f
2562 /***********************************************************************
2563 Text properties
2564 ***********************************************************************/
2565
2566 /* Called when IT reaches IT->stop_charpos. Handle text property and
2567 overlay changes. Set IT->stop_charpos to the next position where
2568 to stop. */
2569
2570 static void
2571 handle_stop (it)
2572 struct it *it;
2573 {
2574 enum prop_handled handled;
2575 int handle_overlay_change_p = 1;
2576 struct props *p;
2577
2578 it->dpvec = NULL;
2579 it->current.dpvec_index = -1;
2580
2581 do
2582 {
2583 handled = HANDLED_NORMALLY;
2584
2585 /* Call text property handlers. */
2586 for (p = it_props; p->handler; ++p)
2587 {
2588 handled = p->handler (it);
2589
2590 if (handled == HANDLED_RECOMPUTE_PROPS)
2591 break;
2592 else if (handled == HANDLED_RETURN)
2593 return;
2594 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2595 handle_overlay_change_p = 0;
2596 }
2597
2598 if (handled != HANDLED_RECOMPUTE_PROPS)
2599 {
2600 /* Don't check for overlay strings below when set to deliver
2601 characters from a display vector. */
2602 if (it->method == next_element_from_display_vector)
2603 handle_overlay_change_p = 0;
2604
2605 /* Handle overlay changes. */
2606 if (handle_overlay_change_p)
2607 handled = handle_overlay_change (it);
2608
2609 /* Determine where to stop next. */
2610 if (handled == HANDLED_NORMALLY)
2611 compute_stop_pos (it);
2612 }
2613 }
2614 while (handled == HANDLED_RECOMPUTE_PROPS);
2615 }
2616
2617
2618 /* Compute IT->stop_charpos from text property and overlay change
2619 information for IT's current position. */
2620
2621 static void
2622 compute_stop_pos (it)
2623 struct it *it;
2624 {
2625 register INTERVAL iv, next_iv;
2626 Lisp_Object object, limit, position;
2627
2628 /* If nowhere else, stop at the end. */
2629 it->stop_charpos = it->end_charpos;
2630
2631 if (STRINGP (it->string))
2632 {
2633 /* Strings are usually short, so don't limit the search for
2634 properties. */
2635 object = it->string;
2636 limit = Qnil;
2637 position = make_number (IT_STRING_CHARPOS (*it));
2638 }
2639 else
2640 {
2641 int charpos;
2642
2643 /* If next overlay change is in front of the current stop pos
2644 (which is IT->end_charpos), stop there. Note: value of
2645 next_overlay_change is point-max if no overlay change
2646 follows. */
2647 charpos = next_overlay_change (IT_CHARPOS (*it));
2648 if (charpos < it->stop_charpos)
2649 it->stop_charpos = charpos;
2650
2651 /* If showing the region, we have to stop at the region
2652 start or end because the face might change there. */
2653 if (it->region_beg_charpos > 0)
2654 {
2655 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2656 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2657 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2658 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2659 }
2660
2661 /* Set up variables for computing the stop position from text
2662 property changes. */
2663 XSETBUFFER (object, current_buffer);
2664 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2665 position = make_number (IT_CHARPOS (*it));
2666
2667 }
2668
2669 /* Get the interval containing IT's position. Value is a null
2670 interval if there isn't such an interval. */
2671 iv = validate_interval_range (object, &position, &position, 0);
2672 if (!NULL_INTERVAL_P (iv))
2673 {
2674 Lisp_Object values_here[LAST_PROP_IDX];
2675 struct props *p;
2676
2677 /* Get properties here. */
2678 for (p = it_props; p->handler; ++p)
2679 values_here[p->idx] = textget (iv->plist, *p->name);
2680
2681 /* Look for an interval following iv that has different
2682 properties. */
2683 for (next_iv = next_interval (iv);
2684 (!NULL_INTERVAL_P (next_iv)
2685 && (NILP (limit)
2686 || XFASTINT (limit) > next_iv->position));
2687 next_iv = next_interval (next_iv))
2688 {
2689 for (p = it_props; p->handler; ++p)
2690 {
2691 Lisp_Object new_value;
2692
2693 new_value = textget (next_iv->plist, *p->name);
2694 if (!EQ (values_here[p->idx], new_value))
2695 break;
2696 }
2697
2698 if (p->handler)
2699 break;
2700 }
2701
2702 if (!NULL_INTERVAL_P (next_iv))
2703 {
2704 if (INTEGERP (limit)
2705 && next_iv->position >= XFASTINT (limit))
2706 /* No text property change up to limit. */
2707 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2708 else
2709 /* Text properties change in next_iv. */
2710 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2711 }
2712 }
2713
2714 xassert (STRINGP (it->string)
2715 || (it->stop_charpos >= BEGV
2716 && it->stop_charpos >= IT_CHARPOS (*it)));
2717 }
2718
2719
2720 /* Return the position of the next overlay change after POS in
2721 current_buffer. Value is point-max if no overlay change
2722 follows. This is like `next-overlay-change' but doesn't use
2723 xmalloc. */
2724
2725 static int
2726 next_overlay_change (pos)
2727 int pos;
2728 {
2729 int noverlays;
2730 int endpos;
2731 Lisp_Object *overlays;
2732 int i;
2733
2734 /* Get all overlays at the given position. */
2735 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2736
2737 /* If any of these overlays ends before endpos,
2738 use its ending point instead. */
2739 for (i = 0; i < noverlays; ++i)
2740 {
2741 Lisp_Object oend;
2742 int oendpos;
2743
2744 oend = OVERLAY_END (overlays[i]);
2745 oendpos = OVERLAY_POSITION (oend);
2746 endpos = min (endpos, oendpos);
2747 }
2748
2749 return endpos;
2750 }
2751
2752
2753 \f
2754 /***********************************************************************
2755 Fontification
2756 ***********************************************************************/
2757
2758 /* Handle changes in the `fontified' property of the current buffer by
2759 calling hook functions from Qfontification_functions to fontify
2760 regions of text. */
2761
2762 static enum prop_handled
2763 handle_fontified_prop (it)
2764 struct it *it;
2765 {
2766 Lisp_Object prop, pos;
2767 enum prop_handled handled = HANDLED_NORMALLY;
2768
2769 /* Get the value of the `fontified' property at IT's current buffer
2770 position. (The `fontified' property doesn't have a special
2771 meaning in strings.) If the value is nil, call functions from
2772 Qfontification_functions. */
2773 if (!STRINGP (it->string)
2774 && it->s == NULL
2775 && !NILP (Vfontification_functions)
2776 && !NILP (Vrun_hooks)
2777 && (pos = make_number (IT_CHARPOS (*it)),
2778 prop = Fget_char_property (pos, Qfontified, Qnil),
2779 NILP (prop)))
2780 {
2781 int count = SPECPDL_INDEX ();
2782 Lisp_Object val;
2783
2784 val = Vfontification_functions;
2785 specbind (Qfontification_functions, Qnil);
2786
2787 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2788 safe_call1 (val, pos);
2789 else
2790 {
2791 Lisp_Object globals, fn;
2792 struct gcpro gcpro1, gcpro2;
2793
2794 globals = Qnil;
2795 GCPRO2 (val, globals);
2796
2797 for (; CONSP (val); val = XCDR (val))
2798 {
2799 fn = XCAR (val);
2800
2801 if (EQ (fn, Qt))
2802 {
2803 /* A value of t indicates this hook has a local
2804 binding; it means to run the global binding too.
2805 In a global value, t should not occur. If it
2806 does, we must ignore it to avoid an endless
2807 loop. */
2808 for (globals = Fdefault_value (Qfontification_functions);
2809 CONSP (globals);
2810 globals = XCDR (globals))
2811 {
2812 fn = XCAR (globals);
2813 if (!EQ (fn, Qt))
2814 safe_call1 (fn, pos);
2815 }
2816 }
2817 else
2818 safe_call1 (fn, pos);
2819 }
2820
2821 UNGCPRO;
2822 }
2823
2824 unbind_to (count, Qnil);
2825
2826 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2827 something. This avoids an endless loop if they failed to
2828 fontify the text for which reason ever. */
2829 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2830 handled = HANDLED_RECOMPUTE_PROPS;
2831 }
2832
2833 return handled;
2834 }
2835
2836
2837 \f
2838 /***********************************************************************
2839 Faces
2840 ***********************************************************************/
2841
2842 /* Set up iterator IT from face properties at its current position.
2843 Called from handle_stop. */
2844
2845 static enum prop_handled
2846 handle_face_prop (it)
2847 struct it *it;
2848 {
2849 int new_face_id, next_stop;
2850
2851 if (!STRINGP (it->string))
2852 {
2853 new_face_id
2854 = face_at_buffer_position (it->w,
2855 IT_CHARPOS (*it),
2856 it->region_beg_charpos,
2857 it->region_end_charpos,
2858 &next_stop,
2859 (IT_CHARPOS (*it)
2860 + TEXT_PROP_DISTANCE_LIMIT),
2861 0);
2862
2863 /* Is this a start of a run of characters with box face?
2864 Caveat: this can be called for a freshly initialized
2865 iterator; face_id is -1 in this case. We know that the new
2866 face will not change until limit, i.e. if the new face has a
2867 box, all characters up to limit will have one. But, as
2868 usual, we don't know whether limit is really the end. */
2869 if (new_face_id != it->face_id)
2870 {
2871 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2872
2873 /* If new face has a box but old face has not, this is
2874 the start of a run of characters with box, i.e. it has
2875 a shadow on the left side. The value of face_id of the
2876 iterator will be -1 if this is the initial call that gets
2877 the face. In this case, we have to look in front of IT's
2878 position and see whether there is a face != new_face_id. */
2879 it->start_of_box_run_p
2880 = (new_face->box != FACE_NO_BOX
2881 && (it->face_id >= 0
2882 || IT_CHARPOS (*it) == BEG
2883 || new_face_id != face_before_it_pos (it)));
2884 it->face_box_p = new_face->box != FACE_NO_BOX;
2885 }
2886 }
2887 else
2888 {
2889 int base_face_id, bufpos;
2890
2891 if (it->current.overlay_string_index >= 0)
2892 bufpos = IT_CHARPOS (*it);
2893 else
2894 bufpos = 0;
2895
2896 /* For strings from a buffer, i.e. overlay strings or strings
2897 from a `display' property, use the face at IT's current
2898 buffer position as the base face to merge with, so that
2899 overlay strings appear in the same face as surrounding
2900 text, unless they specify their own faces. */
2901 base_face_id = underlying_face_id (it);
2902
2903 new_face_id = face_at_string_position (it->w,
2904 it->string,
2905 IT_STRING_CHARPOS (*it),
2906 bufpos,
2907 it->region_beg_charpos,
2908 it->region_end_charpos,
2909 &next_stop,
2910 base_face_id, 0);
2911
2912 #if 0 /* This shouldn't be neccessary. Let's check it. */
2913 /* If IT is used to display a mode line we would really like to
2914 use the mode line face instead of the frame's default face. */
2915 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2916 && new_face_id == DEFAULT_FACE_ID)
2917 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2918 #endif
2919
2920 /* Is this a start of a run of characters with box? Caveat:
2921 this can be called for a freshly allocated iterator; face_id
2922 is -1 is this case. We know that the new face will not
2923 change until the next check pos, i.e. if the new face has a
2924 box, all characters up to that position will have a
2925 box. But, as usual, we don't know whether that position
2926 is really the end. */
2927 if (new_face_id != it->face_id)
2928 {
2929 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2930 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2931
2932 /* If new face has a box but old face hasn't, this is the
2933 start of a run of characters with box, i.e. it has a
2934 shadow on the left side. */
2935 it->start_of_box_run_p
2936 = new_face->box && (old_face == NULL || !old_face->box);
2937 it->face_box_p = new_face->box != FACE_NO_BOX;
2938 }
2939 }
2940
2941 it->face_id = new_face_id;
2942 return HANDLED_NORMALLY;
2943 }
2944
2945
2946 /* Return the ID of the face ``underlying'' IT's current position,
2947 which is in a string. If the iterator is associated with a
2948 buffer, return the face at IT's current buffer position.
2949 Otherwise, use the iterator's base_face_id. */
2950
2951 static int
2952 underlying_face_id (it)
2953 struct it *it;
2954 {
2955 int face_id = it->base_face_id, i;
2956
2957 xassert (STRINGP (it->string));
2958
2959 for (i = it->sp - 1; i >= 0; --i)
2960 if (NILP (it->stack[i].string))
2961 face_id = it->stack[i].face_id;
2962
2963 return face_id;
2964 }
2965
2966
2967 /* Compute the face one character before or after the current position
2968 of IT. BEFORE_P non-zero means get the face in front of IT's
2969 position. Value is the id of the face. */
2970
2971 static int
2972 face_before_or_after_it_pos (it, before_p)
2973 struct it *it;
2974 int before_p;
2975 {
2976 int face_id, limit;
2977 int next_check_charpos;
2978 struct text_pos pos;
2979
2980 xassert (it->s == NULL);
2981
2982 if (STRINGP (it->string))
2983 {
2984 int bufpos, base_face_id;
2985
2986 /* No face change past the end of the string (for the case
2987 we are padding with spaces). No face change before the
2988 string start. */
2989 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2990 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2991 return it->face_id;
2992
2993 /* Set pos to the position before or after IT's current position. */
2994 if (before_p)
2995 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2996 else
2997 /* For composition, we must check the character after the
2998 composition. */
2999 pos = (it->what == IT_COMPOSITION
3000 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3001 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3002
3003 if (it->current.overlay_string_index >= 0)
3004 bufpos = IT_CHARPOS (*it);
3005 else
3006 bufpos = 0;
3007
3008 base_face_id = underlying_face_id (it);
3009
3010 /* Get the face for ASCII, or unibyte. */
3011 face_id = face_at_string_position (it->w,
3012 it->string,
3013 CHARPOS (pos),
3014 bufpos,
3015 it->region_beg_charpos,
3016 it->region_end_charpos,
3017 &next_check_charpos,
3018 base_face_id, 0);
3019
3020 /* Correct the face for charsets different from ASCII. Do it
3021 for the multibyte case only. The face returned above is
3022 suitable for unibyte text if IT->string is unibyte. */
3023 if (STRING_MULTIBYTE (it->string))
3024 {
3025 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3026 int rest = SBYTES (it->string) - BYTEPOS (pos);
3027 int c, len;
3028 struct face *face = FACE_FROM_ID (it->f, face_id);
3029
3030 c = string_char_and_length (p, rest, &len);
3031 face_id = FACE_FOR_CHAR (it->f, face, c);
3032 }
3033 }
3034 else
3035 {
3036 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3037 || (IT_CHARPOS (*it) <= BEGV && before_p))
3038 return it->face_id;
3039
3040 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3041 pos = it->current.pos;
3042
3043 if (before_p)
3044 DEC_TEXT_POS (pos, it->multibyte_p);
3045 else
3046 {
3047 if (it->what == IT_COMPOSITION)
3048 /* For composition, we must check the position after the
3049 composition. */
3050 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3051 else
3052 INC_TEXT_POS (pos, it->multibyte_p);
3053 }
3054
3055 /* Determine face for CHARSET_ASCII, or unibyte. */
3056 face_id = face_at_buffer_position (it->w,
3057 CHARPOS (pos),
3058 it->region_beg_charpos,
3059 it->region_end_charpos,
3060 &next_check_charpos,
3061 limit, 0);
3062
3063 /* Correct the face for charsets different from ASCII. Do it
3064 for the multibyte case only. The face returned above is
3065 suitable for unibyte text if current_buffer is unibyte. */
3066 if (it->multibyte_p)
3067 {
3068 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3069 struct face *face = FACE_FROM_ID (it->f, face_id);
3070 face_id = FACE_FOR_CHAR (it->f, face, c);
3071 }
3072 }
3073
3074 return face_id;
3075 }
3076
3077
3078 \f
3079 /***********************************************************************
3080 Invisible text
3081 ***********************************************************************/
3082
3083 /* Set up iterator IT from invisible properties at its current
3084 position. Called from handle_stop. */
3085
3086 static enum prop_handled
3087 handle_invisible_prop (it)
3088 struct it *it;
3089 {
3090 enum prop_handled handled = HANDLED_NORMALLY;
3091
3092 if (STRINGP (it->string))
3093 {
3094 extern Lisp_Object Qinvisible;
3095 Lisp_Object prop, end_charpos, limit, charpos;
3096
3097 /* Get the value of the invisible text property at the
3098 current position. Value will be nil if there is no such
3099 property. */
3100 charpos = make_number (IT_STRING_CHARPOS (*it));
3101 prop = Fget_text_property (charpos, Qinvisible, it->string);
3102
3103 if (!NILP (prop)
3104 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3105 {
3106 handled = HANDLED_RECOMPUTE_PROPS;
3107
3108 /* Get the position at which the next change of the
3109 invisible text property can be found in IT->string.
3110 Value will be nil if the property value is the same for
3111 all the rest of IT->string. */
3112 XSETINT (limit, SCHARS (it->string));
3113 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3114 it->string, limit);
3115
3116 /* Text at current position is invisible. The next
3117 change in the property is at position end_charpos.
3118 Move IT's current position to that position. */
3119 if (INTEGERP (end_charpos)
3120 && XFASTINT (end_charpos) < XFASTINT (limit))
3121 {
3122 struct text_pos old;
3123 old = it->current.string_pos;
3124 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3125 compute_string_pos (&it->current.string_pos, old, it->string);
3126 }
3127 else
3128 {
3129 /* The rest of the string is invisible. If this is an
3130 overlay string, proceed with the next overlay string
3131 or whatever comes and return a character from there. */
3132 if (it->current.overlay_string_index >= 0)
3133 {
3134 next_overlay_string (it);
3135 /* Don't check for overlay strings when we just
3136 finished processing them. */
3137 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3138 }
3139 else
3140 {
3141 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3142 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3143 }
3144 }
3145 }
3146 }
3147 else
3148 {
3149 int invis_p, newpos, next_stop, start_charpos;
3150 Lisp_Object pos, prop, overlay;
3151
3152 /* First of all, is there invisible text at this position? */
3153 start_charpos = IT_CHARPOS (*it);
3154 pos = make_number (IT_CHARPOS (*it));
3155 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3156 &overlay);
3157 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3158
3159 /* If we are on invisible text, skip over it. */
3160 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3161 {
3162 /* Record whether we have to display an ellipsis for the
3163 invisible text. */
3164 int display_ellipsis_p = invis_p == 2;
3165
3166 handled = HANDLED_RECOMPUTE_PROPS;
3167
3168 /* Loop skipping over invisible text. The loop is left at
3169 ZV or with IT on the first char being visible again. */
3170 do
3171 {
3172 /* Try to skip some invisible text. Return value is the
3173 position reached which can be equal to IT's position
3174 if there is nothing invisible here. This skips both
3175 over invisible text properties and overlays with
3176 invisible property. */
3177 newpos = skip_invisible (IT_CHARPOS (*it),
3178 &next_stop, ZV, it->window);
3179
3180 /* If we skipped nothing at all we weren't at invisible
3181 text in the first place. If everything to the end of
3182 the buffer was skipped, end the loop. */
3183 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3184 invis_p = 0;
3185 else
3186 {
3187 /* We skipped some characters but not necessarily
3188 all there are. Check if we ended up on visible
3189 text. Fget_char_property returns the property of
3190 the char before the given position, i.e. if we
3191 get invis_p = 0, this means that the char at
3192 newpos is visible. */
3193 pos = make_number (newpos);
3194 prop = Fget_char_property (pos, Qinvisible, it->window);
3195 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3196 }
3197
3198 /* If we ended up on invisible text, proceed to
3199 skip starting with next_stop. */
3200 if (invis_p)
3201 IT_CHARPOS (*it) = next_stop;
3202 }
3203 while (invis_p);
3204
3205 /* The position newpos is now either ZV or on visible text. */
3206 IT_CHARPOS (*it) = newpos;
3207 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3208
3209 /* If there are before-strings at the start of invisible
3210 text, and the text is invisible because of a text
3211 property, arrange to show before-strings because 20.x did
3212 it that way. (If the text is invisible because of an
3213 overlay property instead of a text property, this is
3214 already handled in the overlay code.) */
3215 if (NILP (overlay)
3216 && get_overlay_strings (it, start_charpos))
3217 {
3218 handled = HANDLED_RECOMPUTE_PROPS;
3219 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3220 }
3221 else if (display_ellipsis_p)
3222 setup_for_ellipsis (it);
3223 }
3224 }
3225
3226 return handled;
3227 }
3228
3229
3230 /* Make iterator IT return `...' next. */
3231
3232 static void
3233 setup_for_ellipsis (it)
3234 struct it *it;
3235 {
3236 if (it->dp
3237 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3238 {
3239 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3240 it->dpvec = v->contents;
3241 it->dpend = v->contents + v->size;
3242 }
3243 else
3244 {
3245 /* Default `...'. */
3246 it->dpvec = default_invis_vector;
3247 it->dpend = default_invis_vector + 3;
3248 }
3249
3250 /* The ellipsis display does not replace the display of the
3251 character at the new position. Indicate this by setting
3252 IT->dpvec_char_len to zero. */
3253 it->dpvec_char_len = 0;
3254
3255 it->current.dpvec_index = 0;
3256 it->method = next_element_from_display_vector;
3257 }
3258
3259
3260 \f
3261 /***********************************************************************
3262 'display' property
3263 ***********************************************************************/
3264
3265 /* Set up iterator IT from `display' property at its current position.
3266 Called from handle_stop. */
3267
3268 static enum prop_handled
3269 handle_display_prop (it)
3270 struct it *it;
3271 {
3272 Lisp_Object prop, object;
3273 struct text_pos *position;
3274 int display_replaced_p = 0;
3275
3276 if (STRINGP (it->string))
3277 {
3278 object = it->string;
3279 position = &it->current.string_pos;
3280 }
3281 else
3282 {
3283 object = it->w->buffer;
3284 position = &it->current.pos;
3285 }
3286
3287 /* Reset those iterator values set from display property values. */
3288 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3289 it->space_width = Qnil;
3290 it->font_height = Qnil;
3291 it->voffset = 0;
3292
3293 /* We don't support recursive `display' properties, i.e. string
3294 values that have a string `display' property, that have a string
3295 `display' property etc. */
3296 if (!it->string_from_display_prop_p)
3297 it->area = TEXT_AREA;
3298
3299 prop = Fget_char_property (make_number (position->charpos),
3300 Qdisplay, object);
3301 if (NILP (prop))
3302 return HANDLED_NORMALLY;
3303
3304 if (CONSP (prop)
3305 /* Simple properties. */
3306 && !EQ (XCAR (prop), Qimage)
3307 && !EQ (XCAR (prop), Qspace)
3308 && !EQ (XCAR (prop), Qwhen)
3309 && !EQ (XCAR (prop), Qslice)
3310 && !EQ (XCAR (prop), Qspace_width)
3311 && !EQ (XCAR (prop), Qheight)
3312 && !EQ (XCAR (prop), Qraise)
3313 /* Marginal area specifications. */
3314 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3315 && !EQ (XCAR (prop), Qleft_fringe)
3316 && !EQ (XCAR (prop), Qright_fringe)
3317 && !NILP (XCAR (prop)))
3318 {
3319 for (; CONSP (prop); prop = XCDR (prop))
3320 {
3321 if (handle_single_display_prop (it, XCAR (prop), object,
3322 position, display_replaced_p))
3323 display_replaced_p = 1;
3324 }
3325 }
3326 else if (VECTORP (prop))
3327 {
3328 int i;
3329 for (i = 0; i < ASIZE (prop); ++i)
3330 if (handle_single_display_prop (it, AREF (prop, i), object,
3331 position, display_replaced_p))
3332 display_replaced_p = 1;
3333 }
3334 else
3335 {
3336 if (handle_single_display_prop (it, prop, object, position, 0))
3337 display_replaced_p = 1;
3338 }
3339
3340 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3341 }
3342
3343
3344 /* Value is the position of the end of the `display' property starting
3345 at START_POS in OBJECT. */
3346
3347 static struct text_pos
3348 display_prop_end (it, object, start_pos)
3349 struct it *it;
3350 Lisp_Object object;
3351 struct text_pos start_pos;
3352 {
3353 Lisp_Object end;
3354 struct text_pos end_pos;
3355
3356 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3357 Qdisplay, object, Qnil);
3358 CHARPOS (end_pos) = XFASTINT (end);
3359 if (STRINGP (object))
3360 compute_string_pos (&end_pos, start_pos, it->string);
3361 else
3362 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3363
3364 return end_pos;
3365 }
3366
3367
3368 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3369 is the object in which the `display' property was found. *POSITION
3370 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3371 means that we previously saw a display sub-property which already
3372 replaced text display with something else, for example an image;
3373 ignore such properties after the first one has been processed.
3374
3375 If PROP is a `space' or `image' sub-property, set *POSITION to the
3376 end position of the `display' property.
3377
3378 Value is non-zero if something was found which replaces the display
3379 of buffer or string text. */
3380
3381 static int
3382 handle_single_display_prop (it, prop, object, position,
3383 display_replaced_before_p)
3384 struct it *it;
3385 Lisp_Object prop;
3386 Lisp_Object object;
3387 struct text_pos *position;
3388 int display_replaced_before_p;
3389 {
3390 Lisp_Object value;
3391 int replaces_text_display_p = 0;
3392 Lisp_Object form;
3393
3394 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3395 evaluated. If the result is nil, VALUE is ignored. */
3396 form = Qt;
3397 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3398 {
3399 prop = XCDR (prop);
3400 if (!CONSP (prop))
3401 return 0;
3402 form = XCAR (prop);
3403 prop = XCDR (prop);
3404 }
3405
3406 if (!NILP (form) && !EQ (form, Qt))
3407 {
3408 int count = SPECPDL_INDEX ();
3409 struct gcpro gcpro1;
3410
3411 /* Bind `object' to the object having the `display' property, a
3412 buffer or string. Bind `position' to the position in the
3413 object where the property was found, and `buffer-position'
3414 to the current position in the buffer. */
3415 specbind (Qobject, object);
3416 specbind (Qposition, make_number (CHARPOS (*position)));
3417 specbind (Qbuffer_position,
3418 make_number (STRINGP (object)
3419 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3420 GCPRO1 (form);
3421 form = safe_eval (form);
3422 UNGCPRO;
3423 unbind_to (count, Qnil);
3424 }
3425
3426 if (NILP (form))
3427 return 0;
3428
3429 if (CONSP (prop)
3430 && EQ (XCAR (prop), Qheight)
3431 && CONSP (XCDR (prop)))
3432 {
3433 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3434 return 0;
3435
3436 /* `(height HEIGHT)'. */
3437 it->font_height = XCAR (XCDR (prop));
3438 if (!NILP (it->font_height))
3439 {
3440 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3441 int new_height = -1;
3442
3443 if (CONSP (it->font_height)
3444 && (EQ (XCAR (it->font_height), Qplus)
3445 || EQ (XCAR (it->font_height), Qminus))
3446 && CONSP (XCDR (it->font_height))
3447 && INTEGERP (XCAR (XCDR (it->font_height))))
3448 {
3449 /* `(+ N)' or `(- N)' where N is an integer. */
3450 int steps = XINT (XCAR (XCDR (it->font_height)));
3451 if (EQ (XCAR (it->font_height), Qplus))
3452 steps = - steps;
3453 it->face_id = smaller_face (it->f, it->face_id, steps);
3454 }
3455 else if (FUNCTIONP (it->font_height))
3456 {
3457 /* Call function with current height as argument.
3458 Value is the new height. */
3459 Lisp_Object height;
3460 height = safe_call1 (it->font_height,
3461 face->lface[LFACE_HEIGHT_INDEX]);
3462 if (NUMBERP (height))
3463 new_height = XFLOATINT (height);
3464 }
3465 else if (NUMBERP (it->font_height))
3466 {
3467 /* Value is a multiple of the canonical char height. */
3468 struct face *face;
3469
3470 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3471 new_height = (XFLOATINT (it->font_height)
3472 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3473 }
3474 else
3475 {
3476 /* Evaluate IT->font_height with `height' bound to the
3477 current specified height to get the new height. */
3478 Lisp_Object value;
3479 int count = SPECPDL_INDEX ();
3480
3481 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3482 value = safe_eval (it->font_height);
3483 unbind_to (count, Qnil);
3484
3485 if (NUMBERP (value))
3486 new_height = XFLOATINT (value);
3487 }
3488
3489 if (new_height > 0)
3490 it->face_id = face_with_height (it->f, it->face_id, new_height);
3491 }
3492 }
3493 else if (CONSP (prop)
3494 && EQ (XCAR (prop), Qspace_width)
3495 && CONSP (XCDR (prop)))
3496 {
3497 /* `(space_width WIDTH)'. */
3498 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3499 return 0;
3500
3501 value = XCAR (XCDR (prop));
3502 if (NUMBERP (value) && XFLOATINT (value) > 0)
3503 it->space_width = value;
3504 }
3505 else if (CONSP (prop)
3506 && EQ (XCAR (prop), Qslice))
3507 {
3508 /* `(slice X Y WIDTH HEIGHT)'. */
3509 Lisp_Object tem;
3510
3511 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3512 return 0;
3513
3514 if (tem = XCDR (prop), CONSP (tem))
3515 {
3516 it->slice.x = XCAR (tem);
3517 if (tem = XCDR (tem), CONSP (tem))
3518 {
3519 it->slice.y = XCAR (tem);
3520 if (tem = XCDR (tem), CONSP (tem))
3521 {
3522 it->slice.width = XCAR (tem);
3523 if (tem = XCDR (tem), CONSP (tem))
3524 it->slice.height = XCAR (tem);
3525 }
3526 }
3527 }
3528 }
3529 else if (CONSP (prop)
3530 && EQ (XCAR (prop), Qraise)
3531 && CONSP (XCDR (prop)))
3532 {
3533 /* `(raise FACTOR)'. */
3534 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3535 return 0;
3536
3537 #ifdef HAVE_WINDOW_SYSTEM
3538 value = XCAR (XCDR (prop));
3539 if (NUMBERP (value))
3540 {
3541 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3542 it->voffset = - (XFLOATINT (value)
3543 * (FONT_HEIGHT (face->font)));
3544 }
3545 #endif /* HAVE_WINDOW_SYSTEM */
3546 }
3547 else if (!it->string_from_display_prop_p)
3548 {
3549 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3550 VALUE) or `((margin nil) VALUE)' or VALUE. */
3551 Lisp_Object location, value;
3552 struct text_pos start_pos;
3553 int valid_p;
3554
3555 /* Characters having this form of property are not displayed, so
3556 we have to find the end of the property. */
3557 start_pos = *position;
3558 *position = display_prop_end (it, object, start_pos);
3559 value = Qnil;
3560
3561 /* Let's stop at the new position and assume that all
3562 text properties change there. */
3563 it->stop_charpos = position->charpos;
3564
3565 if (CONSP (prop)
3566 && (EQ (XCAR (prop), Qleft_fringe)
3567 || EQ (XCAR (prop), Qright_fringe))
3568 && CONSP (XCDR (prop)))
3569 {
3570 unsigned face_id = DEFAULT_FACE_ID;
3571
3572 /* Save current settings of IT so that we can restore them
3573 when we are finished with the glyph property value. */
3574
3575 /* `(left-fringe BITMAP FACE)'. */
3576 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3577 return 0;
3578
3579 #ifdef HAVE_WINDOW_SYSTEM
3580 value = XCAR (XCDR (prop));
3581 if (!NUMBERP (value)
3582 || !valid_fringe_bitmap_id_p (XINT (value)))
3583 return 0;
3584
3585 if (CONSP (XCDR (XCDR (prop))))
3586 {
3587 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3588
3589 face_id = lookup_named_face (it->f, face_name, 'A');
3590 if (face_id < 0)
3591 return 0;
3592 }
3593
3594 push_it (it);
3595
3596 it->area = TEXT_AREA;
3597 it->what = IT_IMAGE;
3598 it->image_id = -1; /* no image */
3599 it->position = start_pos;
3600 it->object = NILP (object) ? it->w->buffer : object;
3601 it->method = next_element_from_image;
3602 it->face_id = face_id;
3603
3604 /* Say that we haven't consumed the characters with
3605 `display' property yet. The call to pop_it in
3606 set_iterator_to_next will clean this up. */
3607 *position = start_pos;
3608
3609 if (EQ (XCAR (prop), Qleft_fringe))
3610 {
3611 it->left_user_fringe_bitmap = XINT (value);
3612 it->left_user_fringe_face_id = face_id;
3613 }
3614 else
3615 {
3616 it->right_user_fringe_bitmap = XINT (value);
3617 it->right_user_fringe_face_id = face_id;
3618 }
3619 #endif /* HAVE_WINDOW_SYSTEM */
3620 return 1;
3621 }
3622
3623 location = Qunbound;
3624 if (CONSP (prop) && CONSP (XCAR (prop)))
3625 {
3626 Lisp_Object tem;
3627
3628 value = XCDR (prop);
3629 if (CONSP (value))
3630 value = XCAR (value);
3631
3632 tem = XCAR (prop);
3633 if (EQ (XCAR (tem), Qmargin)
3634 && (tem = XCDR (tem),
3635 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3636 (NILP (tem)
3637 || EQ (tem, Qleft_margin)
3638 || EQ (tem, Qright_margin))))
3639 location = tem;
3640 }
3641
3642 if (EQ (location, Qunbound))
3643 {
3644 location = Qnil;
3645 value = prop;
3646 }
3647
3648 valid_p = (STRINGP (value)
3649 #ifdef HAVE_WINDOW_SYSTEM
3650 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3651 #endif /* not HAVE_WINDOW_SYSTEM */
3652 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3653
3654 if ((EQ (location, Qleft_margin)
3655 || EQ (location, Qright_margin)
3656 || NILP (location))
3657 && valid_p
3658 && !display_replaced_before_p)
3659 {
3660 replaces_text_display_p = 1;
3661
3662 /* Save current settings of IT so that we can restore them
3663 when we are finished with the glyph property value. */
3664 push_it (it);
3665
3666 if (NILP (location))
3667 it->area = TEXT_AREA;
3668 else if (EQ (location, Qleft_margin))
3669 it->area = LEFT_MARGIN_AREA;
3670 else
3671 it->area = RIGHT_MARGIN_AREA;
3672
3673 if (STRINGP (value))
3674 {
3675 it->string = value;
3676 it->multibyte_p = STRING_MULTIBYTE (it->string);
3677 it->current.overlay_string_index = -1;
3678 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3679 it->end_charpos = it->string_nchars = SCHARS (it->string);
3680 it->method = next_element_from_string;
3681 it->stop_charpos = 0;
3682 it->string_from_display_prop_p = 1;
3683 /* Say that we haven't consumed the characters with
3684 `display' property yet. The call to pop_it in
3685 set_iterator_to_next will clean this up. */
3686 *position = start_pos;
3687 }
3688 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3689 {
3690 it->method = next_element_from_stretch;
3691 it->object = value;
3692 it->current.pos = it->position = start_pos;
3693 }
3694 #ifdef HAVE_WINDOW_SYSTEM
3695 else
3696 {
3697 it->what = IT_IMAGE;
3698 it->image_id = lookup_image (it->f, value);
3699 it->position = start_pos;
3700 it->object = NILP (object) ? it->w->buffer : object;
3701 it->method = next_element_from_image;
3702
3703 /* Say that we haven't consumed the characters with
3704 `display' property yet. The call to pop_it in
3705 set_iterator_to_next will clean this up. */
3706 *position = start_pos;
3707 }
3708 #endif /* HAVE_WINDOW_SYSTEM */
3709 }
3710 else
3711 /* Invalid property or property not supported. Restore
3712 the position to what it was before. */
3713 *position = start_pos;
3714 }
3715
3716 return replaces_text_display_p;
3717 }
3718
3719
3720 /* Check if PROP is a display sub-property value whose text should be
3721 treated as intangible. */
3722
3723 static int
3724 single_display_prop_intangible_p (prop)
3725 Lisp_Object prop;
3726 {
3727 /* Skip over `when FORM'. */
3728 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3729 {
3730 prop = XCDR (prop);
3731 if (!CONSP (prop))
3732 return 0;
3733 prop = XCDR (prop);
3734 }
3735
3736 if (STRINGP (prop))
3737 return 1;
3738
3739 if (!CONSP (prop))
3740 return 0;
3741
3742 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3743 we don't need to treat text as intangible. */
3744 if (EQ (XCAR (prop), Qmargin))
3745 {
3746 prop = XCDR (prop);
3747 if (!CONSP (prop))
3748 return 0;
3749
3750 prop = XCDR (prop);
3751 if (!CONSP (prop)
3752 || EQ (XCAR (prop), Qleft_margin)
3753 || EQ (XCAR (prop), Qright_margin))
3754 return 0;
3755 }
3756
3757 return (CONSP (prop)
3758 && (EQ (XCAR (prop), Qimage)
3759 || EQ (XCAR (prop), Qspace)));
3760 }
3761
3762
3763 /* Check if PROP is a display property value whose text should be
3764 treated as intangible. */
3765
3766 int
3767 display_prop_intangible_p (prop)
3768 Lisp_Object prop;
3769 {
3770 if (CONSP (prop)
3771 && CONSP (XCAR (prop))
3772 && !EQ (Qmargin, XCAR (XCAR (prop))))
3773 {
3774 /* A list of sub-properties. */
3775 while (CONSP (prop))
3776 {
3777 if (single_display_prop_intangible_p (XCAR (prop)))
3778 return 1;
3779 prop = XCDR (prop);
3780 }
3781 }
3782 else if (VECTORP (prop))
3783 {
3784 /* A vector of sub-properties. */
3785 int i;
3786 for (i = 0; i < ASIZE (prop); ++i)
3787 if (single_display_prop_intangible_p (AREF (prop, i)))
3788 return 1;
3789 }
3790 else
3791 return single_display_prop_intangible_p (prop);
3792
3793 return 0;
3794 }
3795
3796
3797 /* Return 1 if PROP is a display sub-property value containing STRING. */
3798
3799 static int
3800 single_display_prop_string_p (prop, string)
3801 Lisp_Object prop, string;
3802 {
3803 if (EQ (string, prop))
3804 return 1;
3805
3806 /* Skip over `when FORM'. */
3807 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3808 {
3809 prop = XCDR (prop);
3810 if (!CONSP (prop))
3811 return 0;
3812 prop = XCDR (prop);
3813 }
3814
3815 if (CONSP (prop))
3816 /* Skip over `margin LOCATION'. */
3817 if (EQ (XCAR (prop), Qmargin))
3818 {
3819 prop = XCDR (prop);
3820 if (!CONSP (prop))
3821 return 0;
3822
3823 prop = XCDR (prop);
3824 if (!CONSP (prop))
3825 return 0;
3826 }
3827
3828 return CONSP (prop) && EQ (XCAR (prop), string);
3829 }
3830
3831
3832 /* Return 1 if STRING appears in the `display' property PROP. */
3833
3834 static int
3835 display_prop_string_p (prop, string)
3836 Lisp_Object prop, string;
3837 {
3838 if (CONSP (prop)
3839 && CONSP (XCAR (prop))
3840 && !EQ (Qmargin, XCAR (XCAR (prop))))
3841 {
3842 /* A list of sub-properties. */
3843 while (CONSP (prop))
3844 {
3845 if (single_display_prop_string_p (XCAR (prop), string))
3846 return 1;
3847 prop = XCDR (prop);
3848 }
3849 }
3850 else if (VECTORP (prop))
3851 {
3852 /* A vector of sub-properties. */
3853 int i;
3854 for (i = 0; i < ASIZE (prop); ++i)
3855 if (single_display_prop_string_p (AREF (prop, i), string))
3856 return 1;
3857 }
3858 else
3859 return single_display_prop_string_p (prop, string);
3860
3861 return 0;
3862 }
3863
3864
3865 /* Determine from which buffer position in W's buffer STRING comes
3866 from. AROUND_CHARPOS is an approximate position where it could
3867 be from. Value is the buffer position or 0 if it couldn't be
3868 determined.
3869
3870 W's buffer must be current.
3871
3872 This function is necessary because we don't record buffer positions
3873 in glyphs generated from strings (to keep struct glyph small).
3874 This function may only use code that doesn't eval because it is
3875 called asynchronously from note_mouse_highlight. */
3876
3877 int
3878 string_buffer_position (w, string, around_charpos)
3879 struct window *w;
3880 Lisp_Object string;
3881 int around_charpos;
3882 {
3883 Lisp_Object limit, prop, pos;
3884 const int MAX_DISTANCE = 1000;
3885 int found = 0;
3886
3887 pos = make_number (around_charpos);
3888 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3889 while (!found && !EQ (pos, limit))
3890 {
3891 prop = Fget_char_property (pos, Qdisplay, Qnil);
3892 if (!NILP (prop) && display_prop_string_p (prop, string))
3893 found = 1;
3894 else
3895 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3896 }
3897
3898 if (!found)
3899 {
3900 pos = make_number (around_charpos);
3901 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3902 while (!found && !EQ (pos, limit))
3903 {
3904 prop = Fget_char_property (pos, Qdisplay, Qnil);
3905 if (!NILP (prop) && display_prop_string_p (prop, string))
3906 found = 1;
3907 else
3908 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3909 limit);
3910 }
3911 }
3912
3913 return found ? XINT (pos) : 0;
3914 }
3915
3916
3917 \f
3918 /***********************************************************************
3919 `composition' property
3920 ***********************************************************************/
3921
3922 /* Set up iterator IT from `composition' property at its current
3923 position. Called from handle_stop. */
3924
3925 static enum prop_handled
3926 handle_composition_prop (it)
3927 struct it *it;
3928 {
3929 Lisp_Object prop, string;
3930 int pos, pos_byte, end;
3931 enum prop_handled handled = HANDLED_NORMALLY;
3932
3933 if (STRINGP (it->string))
3934 {
3935 pos = IT_STRING_CHARPOS (*it);
3936 pos_byte = IT_STRING_BYTEPOS (*it);
3937 string = it->string;
3938 }
3939 else
3940 {
3941 pos = IT_CHARPOS (*it);
3942 pos_byte = IT_BYTEPOS (*it);
3943 string = Qnil;
3944 }
3945
3946 /* If there's a valid composition and point is not inside of the
3947 composition (in the case that the composition is from the current
3948 buffer), draw a glyph composed from the composition components. */
3949 if (find_composition (pos, -1, &pos, &end, &prop, string)
3950 && COMPOSITION_VALID_P (pos, end, prop)
3951 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3952 {
3953 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3954
3955 if (id >= 0)
3956 {
3957 it->method = next_element_from_composition;
3958 it->cmp_id = id;
3959 it->cmp_len = COMPOSITION_LENGTH (prop);
3960 /* For a terminal, draw only the first character of the
3961 components. */
3962 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3963 it->len = (STRINGP (it->string)
3964 ? string_char_to_byte (it->string, end)
3965 : CHAR_TO_BYTE (end)) - pos_byte;
3966 it->stop_charpos = end;
3967 handled = HANDLED_RETURN;
3968 }
3969 }
3970
3971 return handled;
3972 }
3973
3974
3975 \f
3976 /***********************************************************************
3977 Overlay strings
3978 ***********************************************************************/
3979
3980 /* The following structure is used to record overlay strings for
3981 later sorting in load_overlay_strings. */
3982
3983 struct overlay_entry
3984 {
3985 Lisp_Object overlay;
3986 Lisp_Object string;
3987 int priority;
3988 int after_string_p;
3989 };
3990
3991
3992 /* Set up iterator IT from overlay strings at its current position.
3993 Called from handle_stop. */
3994
3995 static enum prop_handled
3996 handle_overlay_change (it)
3997 struct it *it;
3998 {
3999 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4000 return HANDLED_RECOMPUTE_PROPS;
4001 else
4002 return HANDLED_NORMALLY;
4003 }
4004
4005
4006 /* Set up the next overlay string for delivery by IT, if there is an
4007 overlay string to deliver. Called by set_iterator_to_next when the
4008 end of the current overlay string is reached. If there are more
4009 overlay strings to display, IT->string and
4010 IT->current.overlay_string_index are set appropriately here.
4011 Otherwise IT->string is set to nil. */
4012
4013 static void
4014 next_overlay_string (it)
4015 struct it *it;
4016 {
4017 ++it->current.overlay_string_index;
4018 if (it->current.overlay_string_index == it->n_overlay_strings)
4019 {
4020 /* No more overlay strings. Restore IT's settings to what
4021 they were before overlay strings were processed, and
4022 continue to deliver from current_buffer. */
4023 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4024
4025 pop_it (it);
4026 xassert (it->stop_charpos >= BEGV
4027 && it->stop_charpos <= it->end_charpos);
4028 it->string = Qnil;
4029 it->current.overlay_string_index = -1;
4030 SET_TEXT_POS (it->current.string_pos, -1, -1);
4031 it->n_overlay_strings = 0;
4032 it->method = next_element_from_buffer;
4033
4034 /* If we're at the end of the buffer, record that we have
4035 processed the overlay strings there already, so that
4036 next_element_from_buffer doesn't try it again. */
4037 if (IT_CHARPOS (*it) >= it->end_charpos)
4038 it->overlay_strings_at_end_processed_p = 1;
4039
4040 /* If we have to display `...' for invisible text, set
4041 the iterator up for that. */
4042 if (display_ellipsis_p)
4043 setup_for_ellipsis (it);
4044 }
4045 else
4046 {
4047 /* There are more overlay strings to process. If
4048 IT->current.overlay_string_index has advanced to a position
4049 where we must load IT->overlay_strings with more strings, do
4050 it. */
4051 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4052
4053 if (it->current.overlay_string_index && i == 0)
4054 load_overlay_strings (it, 0);
4055
4056 /* Initialize IT to deliver display elements from the overlay
4057 string. */
4058 it->string = it->overlay_strings[i];
4059 it->multibyte_p = STRING_MULTIBYTE (it->string);
4060 SET_TEXT_POS (it->current.string_pos, 0, 0);
4061 it->method = next_element_from_string;
4062 it->stop_charpos = 0;
4063 }
4064
4065 CHECK_IT (it);
4066 }
4067
4068
4069 /* Compare two overlay_entry structures E1 and E2. Used as a
4070 comparison function for qsort in load_overlay_strings. Overlay
4071 strings for the same position are sorted so that
4072
4073 1. All after-strings come in front of before-strings, except
4074 when they come from the same overlay.
4075
4076 2. Within after-strings, strings are sorted so that overlay strings
4077 from overlays with higher priorities come first.
4078
4079 2. Within before-strings, strings are sorted so that overlay
4080 strings from overlays with higher priorities come last.
4081
4082 Value is analogous to strcmp. */
4083
4084
4085 static int
4086 compare_overlay_entries (e1, e2)
4087 void *e1, *e2;
4088 {
4089 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4090 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4091 int result;
4092
4093 if (entry1->after_string_p != entry2->after_string_p)
4094 {
4095 /* Let after-strings appear in front of before-strings if
4096 they come from different overlays. */
4097 if (EQ (entry1->overlay, entry2->overlay))
4098 result = entry1->after_string_p ? 1 : -1;
4099 else
4100 result = entry1->after_string_p ? -1 : 1;
4101 }
4102 else if (entry1->after_string_p)
4103 /* After-strings sorted in order of decreasing priority. */
4104 result = entry2->priority - entry1->priority;
4105 else
4106 /* Before-strings sorted in order of increasing priority. */
4107 result = entry1->priority - entry2->priority;
4108
4109 return result;
4110 }
4111
4112
4113 /* Load the vector IT->overlay_strings with overlay strings from IT's
4114 current buffer position, or from CHARPOS if that is > 0. Set
4115 IT->n_overlays to the total number of overlay strings found.
4116
4117 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4118 a time. On entry into load_overlay_strings,
4119 IT->current.overlay_string_index gives the number of overlay
4120 strings that have already been loaded by previous calls to this
4121 function.
4122
4123 IT->add_overlay_start contains an additional overlay start
4124 position to consider for taking overlay strings from, if non-zero.
4125 This position comes into play when the overlay has an `invisible'
4126 property, and both before and after-strings. When we've skipped to
4127 the end of the overlay, because of its `invisible' property, we
4128 nevertheless want its before-string to appear.
4129 IT->add_overlay_start will contain the overlay start position
4130 in this case.
4131
4132 Overlay strings are sorted so that after-string strings come in
4133 front of before-string strings. Within before and after-strings,
4134 strings are sorted by overlay priority. See also function
4135 compare_overlay_entries. */
4136
4137 static void
4138 load_overlay_strings (it, charpos)
4139 struct it *it;
4140 int charpos;
4141 {
4142 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4143 Lisp_Object overlay, window, str, invisible;
4144 struct Lisp_Overlay *ov;
4145 int start, end;
4146 int size = 20;
4147 int n = 0, i, j, invis_p;
4148 struct overlay_entry *entries
4149 = (struct overlay_entry *) alloca (size * sizeof *entries);
4150
4151 if (charpos <= 0)
4152 charpos = IT_CHARPOS (*it);
4153
4154 /* Append the overlay string STRING of overlay OVERLAY to vector
4155 `entries' which has size `size' and currently contains `n'
4156 elements. AFTER_P non-zero means STRING is an after-string of
4157 OVERLAY. */
4158 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4159 do \
4160 { \
4161 Lisp_Object priority; \
4162 \
4163 if (n == size) \
4164 { \
4165 int new_size = 2 * size; \
4166 struct overlay_entry *old = entries; \
4167 entries = \
4168 (struct overlay_entry *) alloca (new_size \
4169 * sizeof *entries); \
4170 bcopy (old, entries, size * sizeof *entries); \
4171 size = new_size; \
4172 } \
4173 \
4174 entries[n].string = (STRING); \
4175 entries[n].overlay = (OVERLAY); \
4176 priority = Foverlay_get ((OVERLAY), Qpriority); \
4177 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4178 entries[n].after_string_p = (AFTER_P); \
4179 ++n; \
4180 } \
4181 while (0)
4182
4183 /* Process overlay before the overlay center. */
4184 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4185 {
4186 XSETMISC (overlay, ov);
4187 xassert (OVERLAYP (overlay));
4188 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4189 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4190
4191 if (end < charpos)
4192 break;
4193
4194 /* Skip this overlay if it doesn't start or end at IT's current
4195 position. */
4196 if (end != charpos && start != charpos)
4197 continue;
4198
4199 /* Skip this overlay if it doesn't apply to IT->w. */
4200 window = Foverlay_get (overlay, Qwindow);
4201 if (WINDOWP (window) && XWINDOW (window) != it->w)
4202 continue;
4203
4204 /* If the text ``under'' the overlay is invisible, both before-
4205 and after-strings from this overlay are visible; start and
4206 end position are indistinguishable. */
4207 invisible = Foverlay_get (overlay, Qinvisible);
4208 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4209
4210 /* If overlay has a non-empty before-string, record it. */
4211 if ((start == charpos || (end == charpos && invis_p))
4212 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4213 && SCHARS (str))
4214 RECORD_OVERLAY_STRING (overlay, str, 0);
4215
4216 /* If overlay has a non-empty after-string, record it. */
4217 if ((end == charpos || (start == charpos && invis_p))
4218 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4219 && SCHARS (str))
4220 RECORD_OVERLAY_STRING (overlay, str, 1);
4221 }
4222
4223 /* Process overlays after the overlay center. */
4224 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4225 {
4226 XSETMISC (overlay, ov);
4227 xassert (OVERLAYP (overlay));
4228 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4229 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4230
4231 if (start > charpos)
4232 break;
4233
4234 /* Skip this overlay if it doesn't start or end at IT's current
4235 position. */
4236 if (end != charpos && start != charpos)
4237 continue;
4238
4239 /* Skip this overlay if it doesn't apply to IT->w. */
4240 window = Foverlay_get (overlay, Qwindow);
4241 if (WINDOWP (window) && XWINDOW (window) != it->w)
4242 continue;
4243
4244 /* If the text ``under'' the overlay is invisible, it has a zero
4245 dimension, and both before- and after-strings apply. */
4246 invisible = Foverlay_get (overlay, Qinvisible);
4247 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4248
4249 /* If overlay has a non-empty before-string, record it. */
4250 if ((start == charpos || (end == charpos && invis_p))
4251 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4252 && SCHARS (str))
4253 RECORD_OVERLAY_STRING (overlay, str, 0);
4254
4255 /* If overlay has a non-empty after-string, record it. */
4256 if ((end == charpos || (start == charpos && invis_p))
4257 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4258 && SCHARS (str))
4259 RECORD_OVERLAY_STRING (overlay, str, 1);
4260 }
4261
4262 #undef RECORD_OVERLAY_STRING
4263
4264 /* Sort entries. */
4265 if (n > 1)
4266 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4267
4268 /* Record the total number of strings to process. */
4269 it->n_overlay_strings = n;
4270
4271 /* IT->current.overlay_string_index is the number of overlay strings
4272 that have already been consumed by IT. Copy some of the
4273 remaining overlay strings to IT->overlay_strings. */
4274 i = 0;
4275 j = it->current.overlay_string_index;
4276 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4277 it->overlay_strings[i++] = entries[j++].string;
4278
4279 CHECK_IT (it);
4280 }
4281
4282
4283 /* Get the first chunk of overlay strings at IT's current buffer
4284 position, or at CHARPOS if that is > 0. Value is non-zero if at
4285 least one overlay string was found. */
4286
4287 static int
4288 get_overlay_strings (it, charpos)
4289 struct it *it;
4290 int charpos;
4291 {
4292 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4293 process. This fills IT->overlay_strings with strings, and sets
4294 IT->n_overlay_strings to the total number of strings to process.
4295 IT->pos.overlay_string_index has to be set temporarily to zero
4296 because load_overlay_strings needs this; it must be set to -1
4297 when no overlay strings are found because a zero value would
4298 indicate a position in the first overlay string. */
4299 it->current.overlay_string_index = 0;
4300 load_overlay_strings (it, charpos);
4301
4302 /* If we found overlay strings, set up IT to deliver display
4303 elements from the first one. Otherwise set up IT to deliver
4304 from current_buffer. */
4305 if (it->n_overlay_strings)
4306 {
4307 /* Make sure we know settings in current_buffer, so that we can
4308 restore meaningful values when we're done with the overlay
4309 strings. */
4310 compute_stop_pos (it);
4311 xassert (it->face_id >= 0);
4312
4313 /* Save IT's settings. They are restored after all overlay
4314 strings have been processed. */
4315 xassert (it->sp == 0);
4316 push_it (it);
4317
4318 /* Set up IT to deliver display elements from the first overlay
4319 string. */
4320 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4321 it->string = it->overlay_strings[0];
4322 it->stop_charpos = 0;
4323 xassert (STRINGP (it->string));
4324 it->end_charpos = SCHARS (it->string);
4325 it->multibyte_p = STRING_MULTIBYTE (it->string);
4326 it->method = next_element_from_string;
4327 }
4328 else
4329 {
4330 it->string = Qnil;
4331 it->current.overlay_string_index = -1;
4332 it->method = next_element_from_buffer;
4333 }
4334
4335 CHECK_IT (it);
4336
4337 /* Value is non-zero if we found at least one overlay string. */
4338 return STRINGP (it->string);
4339 }
4340
4341
4342 \f
4343 /***********************************************************************
4344 Saving and restoring state
4345 ***********************************************************************/
4346
4347 /* Save current settings of IT on IT->stack. Called, for example,
4348 before setting up IT for an overlay string, to be able to restore
4349 IT's settings to what they were after the overlay string has been
4350 processed. */
4351
4352 static void
4353 push_it (it)
4354 struct it *it;
4355 {
4356 struct iterator_stack_entry *p;
4357
4358 xassert (it->sp < 2);
4359 p = it->stack + it->sp;
4360
4361 p->stop_charpos = it->stop_charpos;
4362 xassert (it->face_id >= 0);
4363 p->face_id = it->face_id;
4364 p->string = it->string;
4365 p->pos = it->current;
4366 p->end_charpos = it->end_charpos;
4367 p->string_nchars = it->string_nchars;
4368 p->area = it->area;
4369 p->multibyte_p = it->multibyte_p;
4370 p->slice = it->slice;
4371 p->space_width = it->space_width;
4372 p->font_height = it->font_height;
4373 p->voffset = it->voffset;
4374 p->string_from_display_prop_p = it->string_from_display_prop_p;
4375 p->display_ellipsis_p = 0;
4376 ++it->sp;
4377 }
4378
4379
4380 /* Restore IT's settings from IT->stack. Called, for example, when no
4381 more overlay strings must be processed, and we return to delivering
4382 display elements from a buffer, or when the end of a string from a
4383 `display' property is reached and we return to delivering display
4384 elements from an overlay string, or from a buffer. */
4385
4386 static void
4387 pop_it (it)
4388 struct it *it;
4389 {
4390 struct iterator_stack_entry *p;
4391
4392 xassert (it->sp > 0);
4393 --it->sp;
4394 p = it->stack + it->sp;
4395 it->stop_charpos = p->stop_charpos;
4396 it->face_id = p->face_id;
4397 it->string = p->string;
4398 it->current = p->pos;
4399 it->end_charpos = p->end_charpos;
4400 it->string_nchars = p->string_nchars;
4401 it->area = p->area;
4402 it->multibyte_p = p->multibyte_p;
4403 it->slice = p->slice;
4404 it->space_width = p->space_width;
4405 it->font_height = p->font_height;
4406 it->voffset = p->voffset;
4407 it->string_from_display_prop_p = p->string_from_display_prop_p;
4408 }
4409
4410
4411 \f
4412 /***********************************************************************
4413 Moving over lines
4414 ***********************************************************************/
4415
4416 /* Set IT's current position to the previous line start. */
4417
4418 static void
4419 back_to_previous_line_start (it)
4420 struct it *it;
4421 {
4422 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4423 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4424 }
4425
4426
4427 /* Move IT to the next line start.
4428
4429 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4430 we skipped over part of the text (as opposed to moving the iterator
4431 continuously over the text). Otherwise, don't change the value
4432 of *SKIPPED_P.
4433
4434 Newlines may come from buffer text, overlay strings, or strings
4435 displayed via the `display' property. That's the reason we can't
4436 simply use find_next_newline_no_quit.
4437
4438 Note that this function may not skip over invisible text that is so
4439 because of text properties and immediately follows a newline. If
4440 it would, function reseat_at_next_visible_line_start, when called
4441 from set_iterator_to_next, would effectively make invisible
4442 characters following a newline part of the wrong glyph row, which
4443 leads to wrong cursor motion. */
4444
4445 static int
4446 forward_to_next_line_start (it, skipped_p)
4447 struct it *it;
4448 int *skipped_p;
4449 {
4450 int old_selective, newline_found_p, n;
4451 const int MAX_NEWLINE_DISTANCE = 500;
4452
4453 /* If already on a newline, just consume it to avoid unintended
4454 skipping over invisible text below. */
4455 if (it->what == IT_CHARACTER
4456 && it->c == '\n'
4457 && CHARPOS (it->position) == IT_CHARPOS (*it))
4458 {
4459 set_iterator_to_next (it, 0);
4460 it->c = 0;
4461 return 1;
4462 }
4463
4464 /* Don't handle selective display in the following. It's (a)
4465 unnecessary because it's done by the caller, and (b) leads to an
4466 infinite recursion because next_element_from_ellipsis indirectly
4467 calls this function. */
4468 old_selective = it->selective;
4469 it->selective = 0;
4470
4471 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4472 from buffer text. */
4473 for (n = newline_found_p = 0;
4474 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4475 n += STRINGP (it->string) ? 0 : 1)
4476 {
4477 if (!get_next_display_element (it))
4478 return 0;
4479 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4480 set_iterator_to_next (it, 0);
4481 }
4482
4483 /* If we didn't find a newline near enough, see if we can use a
4484 short-cut. */
4485 if (!newline_found_p)
4486 {
4487 int start = IT_CHARPOS (*it);
4488 int limit = find_next_newline_no_quit (start, 1);
4489 Lisp_Object pos;
4490
4491 xassert (!STRINGP (it->string));
4492
4493 /* If there isn't any `display' property in sight, and no
4494 overlays, we can just use the position of the newline in
4495 buffer text. */
4496 if (it->stop_charpos >= limit
4497 || ((pos = Fnext_single_property_change (make_number (start),
4498 Qdisplay,
4499 Qnil, make_number (limit)),
4500 NILP (pos))
4501 && next_overlay_change (start) == ZV))
4502 {
4503 IT_CHARPOS (*it) = limit;
4504 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4505 *skipped_p = newline_found_p = 1;
4506 }
4507 else
4508 {
4509 while (get_next_display_element (it)
4510 && !newline_found_p)
4511 {
4512 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4513 set_iterator_to_next (it, 0);
4514 }
4515 }
4516 }
4517
4518 it->selective = old_selective;
4519 return newline_found_p;
4520 }
4521
4522
4523 /* Set IT's current position to the previous visible line start. Skip
4524 invisible text that is so either due to text properties or due to
4525 selective display. Caution: this does not change IT->current_x and
4526 IT->hpos. */
4527
4528 static void
4529 back_to_previous_visible_line_start (it)
4530 struct it *it;
4531 {
4532 int visible_p = 0;
4533
4534 /* Go back one newline if not on BEGV already. */
4535 if (IT_CHARPOS (*it) > BEGV)
4536 back_to_previous_line_start (it);
4537
4538 /* Move over lines that are invisible because of selective display
4539 or text properties. */
4540 while (IT_CHARPOS (*it) > BEGV
4541 && !visible_p)
4542 {
4543 visible_p = 1;
4544
4545 /* If selective > 0, then lines indented more than that values
4546 are invisible. */
4547 if (it->selective > 0
4548 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4549 (double) it->selective)) /* iftc */
4550 visible_p = 0;
4551 else
4552 {
4553 Lisp_Object prop;
4554
4555 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4556 Qinvisible, it->window);
4557 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4558 visible_p = 0;
4559 }
4560
4561 if (visible_p)
4562 {
4563 struct it it2 = *it;
4564
4565 if (handle_display_prop (&it2) == HANDLED_RETURN)
4566 visible_p = 0;
4567 }
4568
4569 /* Back one more newline if the current one is invisible. */
4570 if (!visible_p)
4571 back_to_previous_line_start (it);
4572 }
4573
4574 xassert (IT_CHARPOS (*it) >= BEGV);
4575 xassert (IT_CHARPOS (*it) == BEGV
4576 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4577 CHECK_IT (it);
4578 }
4579
4580
4581 /* Reseat iterator IT at the previous visible line start. Skip
4582 invisible text that is so either due to text properties or due to
4583 selective display. At the end, update IT's overlay information,
4584 face information etc. */
4585
4586 static void
4587 reseat_at_previous_visible_line_start (it)
4588 struct it *it;
4589 {
4590 back_to_previous_visible_line_start (it);
4591 reseat (it, it->current.pos, 1);
4592 CHECK_IT (it);
4593 }
4594
4595
4596 /* Reseat iterator IT on the next visible line start in the current
4597 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4598 preceding the line start. Skip over invisible text that is so
4599 because of selective display. Compute faces, overlays etc at the
4600 new position. Note that this function does not skip over text that
4601 is invisible because of text properties. */
4602
4603 static void
4604 reseat_at_next_visible_line_start (it, on_newline_p)
4605 struct it *it;
4606 int on_newline_p;
4607 {
4608 int newline_found_p, skipped_p = 0;
4609
4610 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4611
4612 /* Skip over lines that are invisible because they are indented
4613 more than the value of IT->selective. */
4614 if (it->selective > 0)
4615 while (IT_CHARPOS (*it) < ZV
4616 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4617 (double) it->selective)) /* iftc */
4618 {
4619 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4620 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4621 }
4622
4623 /* Position on the newline if that's what's requested. */
4624 if (on_newline_p && newline_found_p)
4625 {
4626 if (STRINGP (it->string))
4627 {
4628 if (IT_STRING_CHARPOS (*it) > 0)
4629 {
4630 --IT_STRING_CHARPOS (*it);
4631 --IT_STRING_BYTEPOS (*it);
4632 }
4633 }
4634 else if (IT_CHARPOS (*it) > BEGV)
4635 {
4636 --IT_CHARPOS (*it);
4637 --IT_BYTEPOS (*it);
4638 reseat (it, it->current.pos, 0);
4639 }
4640 }
4641 else if (skipped_p)
4642 reseat (it, it->current.pos, 0);
4643
4644 CHECK_IT (it);
4645 }
4646
4647
4648 \f
4649 /***********************************************************************
4650 Changing an iterator's position
4651 ***********************************************************************/
4652
4653 /* Change IT's current position to POS in current_buffer. If FORCE_P
4654 is non-zero, always check for text properties at the new position.
4655 Otherwise, text properties are only looked up if POS >=
4656 IT->check_charpos of a property. */
4657
4658 static void
4659 reseat (it, pos, force_p)
4660 struct it *it;
4661 struct text_pos pos;
4662 int force_p;
4663 {
4664 int original_pos = IT_CHARPOS (*it);
4665
4666 reseat_1 (it, pos, 0);
4667
4668 /* Determine where to check text properties. Avoid doing it
4669 where possible because text property lookup is very expensive. */
4670 if (force_p
4671 || CHARPOS (pos) > it->stop_charpos
4672 || CHARPOS (pos) < original_pos)
4673 handle_stop (it);
4674
4675 CHECK_IT (it);
4676 }
4677
4678
4679 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4680 IT->stop_pos to POS, also. */
4681
4682 static void
4683 reseat_1 (it, pos, set_stop_p)
4684 struct it *it;
4685 struct text_pos pos;
4686 int set_stop_p;
4687 {
4688 /* Don't call this function when scanning a C string. */
4689 xassert (it->s == NULL);
4690
4691 /* POS must be a reasonable value. */
4692 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4693
4694 it->current.pos = it->position = pos;
4695 XSETBUFFER (it->object, current_buffer);
4696 it->end_charpos = ZV;
4697 it->dpvec = NULL;
4698 it->current.dpvec_index = -1;
4699 it->current.overlay_string_index = -1;
4700 IT_STRING_CHARPOS (*it) = -1;
4701 IT_STRING_BYTEPOS (*it) = -1;
4702 it->string = Qnil;
4703 it->method = next_element_from_buffer;
4704 /* RMS: I added this to fix a bug in move_it_vertically_backward
4705 where it->area continued to relate to the starting point
4706 for the backward motion. Bug report from
4707 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4708 However, I am not sure whether reseat still does the right thing
4709 in general after this change. */
4710 it->area = TEXT_AREA;
4711 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4712 it->sp = 0;
4713 it->face_before_selective_p = 0;
4714
4715 if (set_stop_p)
4716 it->stop_charpos = CHARPOS (pos);
4717 }
4718
4719
4720 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4721 If S is non-null, it is a C string to iterate over. Otherwise,
4722 STRING gives a Lisp string to iterate over.
4723
4724 If PRECISION > 0, don't return more then PRECISION number of
4725 characters from the string.
4726
4727 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4728 characters have been returned. FIELD_WIDTH < 0 means an infinite
4729 field width.
4730
4731 MULTIBYTE = 0 means disable processing of multibyte characters,
4732 MULTIBYTE > 0 means enable it,
4733 MULTIBYTE < 0 means use IT->multibyte_p.
4734
4735 IT must be initialized via a prior call to init_iterator before
4736 calling this function. */
4737
4738 static void
4739 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4740 struct it *it;
4741 unsigned char *s;
4742 Lisp_Object string;
4743 int charpos;
4744 int precision, field_width, multibyte;
4745 {
4746 /* No region in strings. */
4747 it->region_beg_charpos = it->region_end_charpos = -1;
4748
4749 /* No text property checks performed by default, but see below. */
4750 it->stop_charpos = -1;
4751
4752 /* Set iterator position and end position. */
4753 bzero (&it->current, sizeof it->current);
4754 it->current.overlay_string_index = -1;
4755 it->current.dpvec_index = -1;
4756 xassert (charpos >= 0);
4757
4758 /* If STRING is specified, use its multibyteness, otherwise use the
4759 setting of MULTIBYTE, if specified. */
4760 if (multibyte >= 0)
4761 it->multibyte_p = multibyte > 0;
4762
4763 if (s == NULL)
4764 {
4765 xassert (STRINGP (string));
4766 it->string = string;
4767 it->s = NULL;
4768 it->end_charpos = it->string_nchars = SCHARS (string);
4769 it->method = next_element_from_string;
4770 it->current.string_pos = string_pos (charpos, string);
4771 }
4772 else
4773 {
4774 it->s = s;
4775 it->string = Qnil;
4776
4777 /* Note that we use IT->current.pos, not it->current.string_pos,
4778 for displaying C strings. */
4779 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4780 if (it->multibyte_p)
4781 {
4782 it->current.pos = c_string_pos (charpos, s, 1);
4783 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4784 }
4785 else
4786 {
4787 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4788 it->end_charpos = it->string_nchars = strlen (s);
4789 }
4790
4791 it->method = next_element_from_c_string;
4792 }
4793
4794 /* PRECISION > 0 means don't return more than PRECISION characters
4795 from the string. */
4796 if (precision > 0 && it->end_charpos - charpos > precision)
4797 it->end_charpos = it->string_nchars = charpos + precision;
4798
4799 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4800 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4801 FIELD_WIDTH < 0 means infinite field width. This is useful for
4802 padding with `-' at the end of a mode line. */
4803 if (field_width < 0)
4804 field_width = INFINITY;
4805 if (field_width > it->end_charpos - charpos)
4806 it->end_charpos = charpos + field_width;
4807
4808 /* Use the standard display table for displaying strings. */
4809 if (DISP_TABLE_P (Vstandard_display_table))
4810 it->dp = XCHAR_TABLE (Vstandard_display_table);
4811
4812 it->stop_charpos = charpos;
4813 CHECK_IT (it);
4814 }
4815
4816
4817 \f
4818 /***********************************************************************
4819 Iteration
4820 ***********************************************************************/
4821
4822 /* Load IT's display element fields with information about the next
4823 display element from the current position of IT. Value is zero if
4824 end of buffer (or C string) is reached. */
4825
4826 int
4827 get_next_display_element (it)
4828 struct it *it;
4829 {
4830 /* Non-zero means that we found a display element. Zero means that
4831 we hit the end of what we iterate over. Performance note: the
4832 function pointer `method' used here turns out to be faster than
4833 using a sequence of if-statements. */
4834 int success_p = (*it->method) (it);
4835
4836 if (it->what == IT_CHARACTER)
4837 {
4838 /* Map via display table or translate control characters.
4839 IT->c, IT->len etc. have been set to the next character by
4840 the function call above. If we have a display table, and it
4841 contains an entry for IT->c, translate it. Don't do this if
4842 IT->c itself comes from a display table, otherwise we could
4843 end up in an infinite recursion. (An alternative could be to
4844 count the recursion depth of this function and signal an
4845 error when a certain maximum depth is reached.) Is it worth
4846 it? */
4847 if (success_p && it->dpvec == NULL)
4848 {
4849 Lisp_Object dv;
4850
4851 if (it->dp
4852 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4853 VECTORP (dv)))
4854 {
4855 struct Lisp_Vector *v = XVECTOR (dv);
4856
4857 /* Return the first character from the display table
4858 entry, if not empty. If empty, don't display the
4859 current character. */
4860 if (v->size)
4861 {
4862 it->dpvec_char_len = it->len;
4863 it->dpvec = v->contents;
4864 it->dpend = v->contents + v->size;
4865 it->current.dpvec_index = 0;
4866 it->method = next_element_from_display_vector;
4867 success_p = get_next_display_element (it);
4868 }
4869 else
4870 {
4871 set_iterator_to_next (it, 0);
4872 success_p = get_next_display_element (it);
4873 }
4874 }
4875
4876 /* Translate control characters into `\003' or `^C' form.
4877 Control characters coming from a display table entry are
4878 currently not translated because we use IT->dpvec to hold
4879 the translation. This could easily be changed but I
4880 don't believe that it is worth doing.
4881
4882 If it->multibyte_p is nonzero, eight-bit characters and
4883 non-printable multibyte characters are also translated to
4884 octal form.
4885
4886 If it->multibyte_p is zero, eight-bit characters that
4887 don't have corresponding multibyte char code are also
4888 translated to octal form. */
4889 else if ((it->c < ' '
4890 && (it->area != TEXT_AREA
4891 || (it->c != '\n' && it->c != '\t')))
4892 || (it->multibyte_p
4893 ? ((it->c >= 127
4894 && it->len == 1)
4895 || !CHAR_PRINTABLE_P (it->c))
4896 : (it->c >= 127
4897 && it->c == unibyte_char_to_multibyte (it->c))))
4898 {
4899 /* IT->c is a control character which must be displayed
4900 either as '\003' or as `^C' where the '\\' and '^'
4901 can be defined in the display table. Fill
4902 IT->ctl_chars with glyphs for what we have to
4903 display. Then, set IT->dpvec to these glyphs. */
4904 GLYPH g;
4905
4906 if (it->c < 128 && it->ctl_arrow_p)
4907 {
4908 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4909 if (it->dp
4910 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4911 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4912 g = XINT (DISP_CTRL_GLYPH (it->dp));
4913 else
4914 g = FAST_MAKE_GLYPH ('^', 0);
4915 XSETINT (it->ctl_chars[0], g);
4916
4917 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4918 XSETINT (it->ctl_chars[1], g);
4919
4920 /* Set up IT->dpvec and return first character from it. */
4921 it->dpvec_char_len = it->len;
4922 it->dpvec = it->ctl_chars;
4923 it->dpend = it->dpvec + 2;
4924 it->current.dpvec_index = 0;
4925 it->method = next_element_from_display_vector;
4926 get_next_display_element (it);
4927 }
4928 else
4929 {
4930 unsigned char str[MAX_MULTIBYTE_LENGTH];
4931 int len;
4932 int i;
4933 GLYPH escape_glyph;
4934
4935 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4936 if (it->dp
4937 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4938 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4939 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4940 else
4941 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4942
4943 if (SINGLE_BYTE_CHAR_P (it->c))
4944 str[0] = it->c, len = 1;
4945 else
4946 {
4947 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4948 if (len < 0)
4949 {
4950 /* It's an invalid character, which
4951 shouldn't happen actually, but due to
4952 bugs it may happen. Let's print the char
4953 as is, there's not much meaningful we can
4954 do with it. */
4955 str[0] = it->c;
4956 str[1] = it->c >> 8;
4957 str[2] = it->c >> 16;
4958 str[3] = it->c >> 24;
4959 len = 4;
4960 }
4961 }
4962
4963 for (i = 0; i < len; i++)
4964 {
4965 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4966 /* Insert three more glyphs into IT->ctl_chars for
4967 the octal display of the character. */
4968 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4969 XSETINT (it->ctl_chars[i * 4 + 1], g);
4970 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4971 XSETINT (it->ctl_chars[i * 4 + 2], g);
4972 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4973 XSETINT (it->ctl_chars[i * 4 + 3], g);
4974 }
4975
4976 /* Set up IT->dpvec and return the first character
4977 from it. */
4978 it->dpvec_char_len = it->len;
4979 it->dpvec = it->ctl_chars;
4980 it->dpend = it->dpvec + len * 4;
4981 it->current.dpvec_index = 0;
4982 it->method = next_element_from_display_vector;
4983 get_next_display_element (it);
4984 }
4985 }
4986 }
4987
4988 /* Adjust face id for a multibyte character. There are no
4989 multibyte character in unibyte text. */
4990 if (it->multibyte_p
4991 && success_p
4992 && FRAME_WINDOW_P (it->f))
4993 {
4994 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4995 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4996 }
4997 }
4998
4999 /* Is this character the last one of a run of characters with
5000 box? If yes, set IT->end_of_box_run_p to 1. */
5001 if (it->face_box_p
5002 && it->s == NULL)
5003 {
5004 int face_id;
5005 struct face *face;
5006
5007 it->end_of_box_run_p
5008 = ((face_id = face_after_it_pos (it),
5009 face_id != it->face_id)
5010 && (face = FACE_FROM_ID (it->f, face_id),
5011 face->box == FACE_NO_BOX));
5012 }
5013
5014 /* Value is 0 if end of buffer or string reached. */
5015 return success_p;
5016 }
5017
5018
5019 /* Move IT to the next display element.
5020
5021 RESEAT_P non-zero means if called on a newline in buffer text,
5022 skip to the next visible line start.
5023
5024 Functions get_next_display_element and set_iterator_to_next are
5025 separate because I find this arrangement easier to handle than a
5026 get_next_display_element function that also increments IT's
5027 position. The way it is we can first look at an iterator's current
5028 display element, decide whether it fits on a line, and if it does,
5029 increment the iterator position. The other way around we probably
5030 would either need a flag indicating whether the iterator has to be
5031 incremented the next time, or we would have to implement a
5032 decrement position function which would not be easy to write. */
5033
5034 void
5035 set_iterator_to_next (it, reseat_p)
5036 struct it *it;
5037 int reseat_p;
5038 {
5039 /* Reset flags indicating start and end of a sequence of characters
5040 with box. Reset them at the start of this function because
5041 moving the iterator to a new position might set them. */
5042 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5043
5044 if (it->method == next_element_from_buffer)
5045 {
5046 /* The current display element of IT is a character from
5047 current_buffer. Advance in the buffer, and maybe skip over
5048 invisible lines that are so because of selective display. */
5049 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5050 reseat_at_next_visible_line_start (it, 0);
5051 else
5052 {
5053 xassert (it->len != 0);
5054 IT_BYTEPOS (*it) += it->len;
5055 IT_CHARPOS (*it) += 1;
5056 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5057 }
5058 }
5059 else if (it->method == next_element_from_composition)
5060 {
5061 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5062 if (STRINGP (it->string))
5063 {
5064 IT_STRING_BYTEPOS (*it) += it->len;
5065 IT_STRING_CHARPOS (*it) += it->cmp_len;
5066 it->method = next_element_from_string;
5067 goto consider_string_end;
5068 }
5069 else
5070 {
5071 IT_BYTEPOS (*it) += it->len;
5072 IT_CHARPOS (*it) += it->cmp_len;
5073 it->method = next_element_from_buffer;
5074 }
5075 }
5076 else if (it->method == next_element_from_c_string)
5077 {
5078 /* Current display element of IT is from a C string. */
5079 IT_BYTEPOS (*it) += it->len;
5080 IT_CHARPOS (*it) += 1;
5081 }
5082 else if (it->method == next_element_from_display_vector)
5083 {
5084 /* Current display element of IT is from a display table entry.
5085 Advance in the display table definition. Reset it to null if
5086 end reached, and continue with characters from buffers/
5087 strings. */
5088 ++it->current.dpvec_index;
5089
5090 /* Restore face of the iterator to what they were before the
5091 display vector entry (these entries may contain faces). */
5092 it->face_id = it->saved_face_id;
5093
5094 if (it->dpvec + it->current.dpvec_index == it->dpend)
5095 {
5096 if (it->s)
5097 it->method = next_element_from_c_string;
5098 else if (STRINGP (it->string))
5099 it->method = next_element_from_string;
5100 else
5101 it->method = next_element_from_buffer;
5102
5103 it->dpvec = NULL;
5104 it->current.dpvec_index = -1;
5105
5106 /* Skip over characters which were displayed via IT->dpvec. */
5107 if (it->dpvec_char_len < 0)
5108 reseat_at_next_visible_line_start (it, 1);
5109 else if (it->dpvec_char_len > 0)
5110 {
5111 it->len = it->dpvec_char_len;
5112 set_iterator_to_next (it, reseat_p);
5113 }
5114 }
5115 }
5116 else if (it->method == next_element_from_string)
5117 {
5118 /* Current display element is a character from a Lisp string. */
5119 xassert (it->s == NULL && STRINGP (it->string));
5120 IT_STRING_BYTEPOS (*it) += it->len;
5121 IT_STRING_CHARPOS (*it) += 1;
5122
5123 consider_string_end:
5124
5125 if (it->current.overlay_string_index >= 0)
5126 {
5127 /* IT->string is an overlay string. Advance to the
5128 next, if there is one. */
5129 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5130 next_overlay_string (it);
5131 }
5132 else
5133 {
5134 /* IT->string is not an overlay string. If we reached
5135 its end, and there is something on IT->stack, proceed
5136 with what is on the stack. This can be either another
5137 string, this time an overlay string, or a buffer. */
5138 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5139 && it->sp > 0)
5140 {
5141 pop_it (it);
5142 if (!STRINGP (it->string))
5143 it->method = next_element_from_buffer;
5144 else
5145 goto consider_string_end;
5146 }
5147 }
5148 }
5149 else if (it->method == next_element_from_image
5150 || it->method == next_element_from_stretch)
5151 {
5152 /* The position etc with which we have to proceed are on
5153 the stack. The position may be at the end of a string,
5154 if the `display' property takes up the whole string. */
5155 pop_it (it);
5156 it->image_id = 0;
5157 if (STRINGP (it->string))
5158 {
5159 it->method = next_element_from_string;
5160 goto consider_string_end;
5161 }
5162 else
5163 it->method = next_element_from_buffer;
5164 }
5165 else
5166 /* There are no other methods defined, so this should be a bug. */
5167 abort ();
5168
5169 xassert (it->method != next_element_from_string
5170 || (STRINGP (it->string)
5171 && IT_STRING_CHARPOS (*it) >= 0));
5172 }
5173
5174
5175 /* Load IT's display element fields with information about the next
5176 display element which comes from a display table entry or from the
5177 result of translating a control character to one of the forms `^C'
5178 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5179
5180 static int
5181 next_element_from_display_vector (it)
5182 struct it *it;
5183 {
5184 /* Precondition. */
5185 xassert (it->dpvec && it->current.dpvec_index >= 0);
5186
5187 /* Remember the current face id in case glyphs specify faces.
5188 IT's face is restored in set_iterator_to_next. */
5189 it->saved_face_id = it->face_id;
5190
5191 if (INTEGERP (*it->dpvec)
5192 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5193 {
5194 int lface_id;
5195 GLYPH g;
5196
5197 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5198 it->c = FAST_GLYPH_CHAR (g);
5199 it->len = CHAR_BYTES (it->c);
5200
5201 /* The entry may contain a face id to use. Such a face id is
5202 the id of a Lisp face, not a realized face. A face id of
5203 zero means no face is specified. */
5204 lface_id = FAST_GLYPH_FACE (g);
5205 if (lface_id)
5206 {
5207 /* The function returns -1 if lface_id is invalid. */
5208 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5209 if (face_id >= 0)
5210 it->face_id = face_id;
5211 }
5212 }
5213 else
5214 /* Display table entry is invalid. Return a space. */
5215 it->c = ' ', it->len = 1;
5216
5217 /* Don't change position and object of the iterator here. They are
5218 still the values of the character that had this display table
5219 entry or was translated, and that's what we want. */
5220 it->what = IT_CHARACTER;
5221 return 1;
5222 }
5223
5224
5225 /* Load IT with the next display element from Lisp string IT->string.
5226 IT->current.string_pos is the current position within the string.
5227 If IT->current.overlay_string_index >= 0, the Lisp string is an
5228 overlay string. */
5229
5230 static int
5231 next_element_from_string (it)
5232 struct it *it;
5233 {
5234 struct text_pos position;
5235
5236 xassert (STRINGP (it->string));
5237 xassert (IT_STRING_CHARPOS (*it) >= 0);
5238 position = it->current.string_pos;
5239
5240 /* Time to check for invisible text? */
5241 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5242 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5243 {
5244 handle_stop (it);
5245
5246 /* Since a handler may have changed IT->method, we must
5247 recurse here. */
5248 return get_next_display_element (it);
5249 }
5250
5251 if (it->current.overlay_string_index >= 0)
5252 {
5253 /* Get the next character from an overlay string. In overlay
5254 strings, There is no field width or padding with spaces to
5255 do. */
5256 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5257 {
5258 it->what = IT_EOB;
5259 return 0;
5260 }
5261 else if (STRING_MULTIBYTE (it->string))
5262 {
5263 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5264 const unsigned char *s = (SDATA (it->string)
5265 + IT_STRING_BYTEPOS (*it));
5266 it->c = string_char_and_length (s, remaining, &it->len);
5267 }
5268 else
5269 {
5270 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5271 it->len = 1;
5272 }
5273 }
5274 else
5275 {
5276 /* Get the next character from a Lisp string that is not an
5277 overlay string. Such strings come from the mode line, for
5278 example. We may have to pad with spaces, or truncate the
5279 string. See also next_element_from_c_string. */
5280 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5281 {
5282 it->what = IT_EOB;
5283 return 0;
5284 }
5285 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5286 {
5287 /* Pad with spaces. */
5288 it->c = ' ', it->len = 1;
5289 CHARPOS (position) = BYTEPOS (position) = -1;
5290 }
5291 else if (STRING_MULTIBYTE (it->string))
5292 {
5293 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5294 const unsigned char *s = (SDATA (it->string)
5295 + IT_STRING_BYTEPOS (*it));
5296 it->c = string_char_and_length (s, maxlen, &it->len);
5297 }
5298 else
5299 {
5300 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5301 it->len = 1;
5302 }
5303 }
5304
5305 /* Record what we have and where it came from. Note that we store a
5306 buffer position in IT->position although it could arguably be a
5307 string position. */
5308 it->what = IT_CHARACTER;
5309 it->object = it->string;
5310 it->position = position;
5311 return 1;
5312 }
5313
5314
5315 /* Load IT with next display element from C string IT->s.
5316 IT->string_nchars is the maximum number of characters to return
5317 from the string. IT->end_charpos may be greater than
5318 IT->string_nchars when this function is called, in which case we
5319 may have to return padding spaces. Value is zero if end of string
5320 reached, including padding spaces. */
5321
5322 static int
5323 next_element_from_c_string (it)
5324 struct it *it;
5325 {
5326 int success_p = 1;
5327
5328 xassert (it->s);
5329 it->what = IT_CHARACTER;
5330 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5331 it->object = Qnil;
5332
5333 /* IT's position can be greater IT->string_nchars in case a field
5334 width or precision has been specified when the iterator was
5335 initialized. */
5336 if (IT_CHARPOS (*it) >= it->end_charpos)
5337 {
5338 /* End of the game. */
5339 it->what = IT_EOB;
5340 success_p = 0;
5341 }
5342 else if (IT_CHARPOS (*it) >= it->string_nchars)
5343 {
5344 /* Pad with spaces. */
5345 it->c = ' ', it->len = 1;
5346 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5347 }
5348 else if (it->multibyte_p)
5349 {
5350 /* Implementation note: The calls to strlen apparently aren't a
5351 performance problem because there is no noticeable performance
5352 difference between Emacs running in unibyte or multibyte mode. */
5353 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5354 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5355 maxlen, &it->len);
5356 }
5357 else
5358 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5359
5360 return success_p;
5361 }
5362
5363
5364 /* Set up IT to return characters from an ellipsis, if appropriate.
5365 The definition of the ellipsis glyphs may come from a display table
5366 entry. This function Fills IT with the first glyph from the
5367 ellipsis if an ellipsis is to be displayed. */
5368
5369 static int
5370 next_element_from_ellipsis (it)
5371 struct it *it;
5372 {
5373 if (it->selective_display_ellipsis_p)
5374 {
5375 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5376 {
5377 /* Use the display table definition for `...'. Invalid glyphs
5378 will be handled by the method returning elements from dpvec. */
5379 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5380 it->dpvec_char_len = it->len;
5381 it->dpvec = v->contents;
5382 it->dpend = v->contents + v->size;
5383 it->current.dpvec_index = 0;
5384 it->method = next_element_from_display_vector;
5385 }
5386 else
5387 {
5388 /* Use default `...' which is stored in default_invis_vector. */
5389 it->dpvec_char_len = it->len;
5390 it->dpvec = default_invis_vector;
5391 it->dpend = default_invis_vector + 3;
5392 it->current.dpvec_index = 0;
5393 it->method = next_element_from_display_vector;
5394 }
5395 }
5396 else
5397 {
5398 /* The face at the current position may be different from the
5399 face we find after the invisible text. Remember what it
5400 was in IT->saved_face_id, and signal that it's there by
5401 setting face_before_selective_p. */
5402 it->saved_face_id = it->face_id;
5403 it->method = next_element_from_buffer;
5404 reseat_at_next_visible_line_start (it, 1);
5405 it->face_before_selective_p = 1;
5406 }
5407
5408 return get_next_display_element (it);
5409 }
5410
5411
5412 /* Deliver an image display element. The iterator IT is already
5413 filled with image information (done in handle_display_prop). Value
5414 is always 1. */
5415
5416
5417 static int
5418 next_element_from_image (it)
5419 struct it *it;
5420 {
5421 it->what = IT_IMAGE;
5422 return 1;
5423 }
5424
5425
5426 /* Fill iterator IT with next display element from a stretch glyph
5427 property. IT->object is the value of the text property. Value is
5428 always 1. */
5429
5430 static int
5431 next_element_from_stretch (it)
5432 struct it *it;
5433 {
5434 it->what = IT_STRETCH;
5435 return 1;
5436 }
5437
5438
5439 /* Load IT with the next display element from current_buffer. Value
5440 is zero if end of buffer reached. IT->stop_charpos is the next
5441 position at which to stop and check for text properties or buffer
5442 end. */
5443
5444 static int
5445 next_element_from_buffer (it)
5446 struct it *it;
5447 {
5448 int success_p = 1;
5449
5450 /* Check this assumption, otherwise, we would never enter the
5451 if-statement, below. */
5452 xassert (IT_CHARPOS (*it) >= BEGV
5453 && IT_CHARPOS (*it) <= it->stop_charpos);
5454
5455 if (IT_CHARPOS (*it) >= it->stop_charpos)
5456 {
5457 if (IT_CHARPOS (*it) >= it->end_charpos)
5458 {
5459 int overlay_strings_follow_p;
5460
5461 /* End of the game, except when overlay strings follow that
5462 haven't been returned yet. */
5463 if (it->overlay_strings_at_end_processed_p)
5464 overlay_strings_follow_p = 0;
5465 else
5466 {
5467 it->overlay_strings_at_end_processed_p = 1;
5468 overlay_strings_follow_p = get_overlay_strings (it, 0);
5469 }
5470
5471 if (overlay_strings_follow_p)
5472 success_p = get_next_display_element (it);
5473 else
5474 {
5475 it->what = IT_EOB;
5476 it->position = it->current.pos;
5477 success_p = 0;
5478 }
5479 }
5480 else
5481 {
5482 handle_stop (it);
5483 return get_next_display_element (it);
5484 }
5485 }
5486 else
5487 {
5488 /* No face changes, overlays etc. in sight, so just return a
5489 character from current_buffer. */
5490 unsigned char *p;
5491
5492 /* Maybe run the redisplay end trigger hook. Performance note:
5493 This doesn't seem to cost measurable time. */
5494 if (it->redisplay_end_trigger_charpos
5495 && it->glyph_row
5496 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5497 run_redisplay_end_trigger_hook (it);
5498
5499 /* Get the next character, maybe multibyte. */
5500 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5501 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5502 {
5503 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5504 - IT_BYTEPOS (*it));
5505 it->c = string_char_and_length (p, maxlen, &it->len);
5506 }
5507 else
5508 it->c = *p, it->len = 1;
5509
5510 /* Record what we have and where it came from. */
5511 it->what = IT_CHARACTER;;
5512 it->object = it->w->buffer;
5513 it->position = it->current.pos;
5514
5515 /* Normally we return the character found above, except when we
5516 really want to return an ellipsis for selective display. */
5517 if (it->selective)
5518 {
5519 if (it->c == '\n')
5520 {
5521 /* A value of selective > 0 means hide lines indented more
5522 than that number of columns. */
5523 if (it->selective > 0
5524 && IT_CHARPOS (*it) + 1 < ZV
5525 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5526 IT_BYTEPOS (*it) + 1,
5527 (double) it->selective)) /* iftc */
5528 {
5529 success_p = next_element_from_ellipsis (it);
5530 it->dpvec_char_len = -1;
5531 }
5532 }
5533 else if (it->c == '\r' && it->selective == -1)
5534 {
5535 /* A value of selective == -1 means that everything from the
5536 CR to the end of the line is invisible, with maybe an
5537 ellipsis displayed for it. */
5538 success_p = next_element_from_ellipsis (it);
5539 it->dpvec_char_len = -1;
5540 }
5541 }
5542 }
5543
5544 /* Value is zero if end of buffer reached. */
5545 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5546 return success_p;
5547 }
5548
5549
5550 /* Run the redisplay end trigger hook for IT. */
5551
5552 static void
5553 run_redisplay_end_trigger_hook (it)
5554 struct it *it;
5555 {
5556 Lisp_Object args[3];
5557
5558 /* IT->glyph_row should be non-null, i.e. we should be actually
5559 displaying something, or otherwise we should not run the hook. */
5560 xassert (it->glyph_row);
5561
5562 /* Set up hook arguments. */
5563 args[0] = Qredisplay_end_trigger_functions;
5564 args[1] = it->window;
5565 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5566 it->redisplay_end_trigger_charpos = 0;
5567
5568 /* Since we are *trying* to run these functions, don't try to run
5569 them again, even if they get an error. */
5570 it->w->redisplay_end_trigger = Qnil;
5571 Frun_hook_with_args (3, args);
5572
5573 /* Notice if it changed the face of the character we are on. */
5574 handle_face_prop (it);
5575 }
5576
5577
5578 /* Deliver a composition display element. The iterator IT is already
5579 filled with composition information (done in
5580 handle_composition_prop). Value is always 1. */
5581
5582 static int
5583 next_element_from_composition (it)
5584 struct it *it;
5585 {
5586 it->what = IT_COMPOSITION;
5587 it->position = (STRINGP (it->string)
5588 ? it->current.string_pos
5589 : it->current.pos);
5590 return 1;
5591 }
5592
5593
5594 \f
5595 /***********************************************************************
5596 Moving an iterator without producing glyphs
5597 ***********************************************************************/
5598
5599 /* Move iterator IT to a specified buffer or X position within one
5600 line on the display without producing glyphs.
5601
5602 OP should be a bit mask including some or all of these bits:
5603 MOVE_TO_X: Stop on reaching x-position TO_X.
5604 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5605 Regardless of OP's value, stop in reaching the end of the display line.
5606
5607 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5608 This means, in particular, that TO_X includes window's horizontal
5609 scroll amount.
5610
5611 The return value has several possible values that
5612 say what condition caused the scan to stop:
5613
5614 MOVE_POS_MATCH_OR_ZV
5615 - when TO_POS or ZV was reached.
5616
5617 MOVE_X_REACHED
5618 -when TO_X was reached before TO_POS or ZV were reached.
5619
5620 MOVE_LINE_CONTINUED
5621 - when we reached the end of the display area and the line must
5622 be continued.
5623
5624 MOVE_LINE_TRUNCATED
5625 - when we reached the end of the display area and the line is
5626 truncated.
5627
5628 MOVE_NEWLINE_OR_CR
5629 - when we stopped at a line end, i.e. a newline or a CR and selective
5630 display is on. */
5631
5632 static enum move_it_result
5633 move_it_in_display_line_to (it, to_charpos, to_x, op)
5634 struct it *it;
5635 int to_charpos, to_x, op;
5636 {
5637 enum move_it_result result = MOVE_UNDEFINED;
5638 struct glyph_row *saved_glyph_row;
5639
5640 /* Don't produce glyphs in produce_glyphs. */
5641 saved_glyph_row = it->glyph_row;
5642 it->glyph_row = NULL;
5643
5644 #define BUFFER_POS_REACHED_P() \
5645 ((op & MOVE_TO_POS) != 0 \
5646 && BUFFERP (it->object) \
5647 && IT_CHARPOS (*it) >= to_charpos)
5648
5649 while (1)
5650 {
5651 int x, i, ascent = 0, descent = 0;
5652
5653 /* Stop when ZV reached.
5654 We used to stop here when TO_CHARPOS reached as well, but that is
5655 too soon if this glyph does not fit on this line. So we handle it
5656 explicitly below. */
5657 if (!get_next_display_element (it)
5658 || (it->truncate_lines_p
5659 && BUFFER_POS_REACHED_P ()))
5660 {
5661 result = MOVE_POS_MATCH_OR_ZV;
5662 break;
5663 }
5664
5665 /* The call to produce_glyphs will get the metrics of the
5666 display element IT is loaded with. We record in x the
5667 x-position before this display element in case it does not
5668 fit on the line. */
5669 x = it->current_x;
5670
5671 /* Remember the line height so far in case the next element doesn't
5672 fit on the line. */
5673 if (!it->truncate_lines_p)
5674 {
5675 ascent = it->max_ascent;
5676 descent = it->max_descent;
5677 }
5678
5679 PRODUCE_GLYPHS (it);
5680
5681 if (it->area != TEXT_AREA)
5682 {
5683 set_iterator_to_next (it, 1);
5684 continue;
5685 }
5686
5687 /* The number of glyphs we get back in IT->nglyphs will normally
5688 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5689 character on a terminal frame, or (iii) a line end. For the
5690 second case, IT->nglyphs - 1 padding glyphs will be present
5691 (on X frames, there is only one glyph produced for a
5692 composite character.
5693
5694 The behavior implemented below means, for continuation lines,
5695 that as many spaces of a TAB as fit on the current line are
5696 displayed there. For terminal frames, as many glyphs of a
5697 multi-glyph character are displayed in the current line, too.
5698 This is what the old redisplay code did, and we keep it that
5699 way. Under X, the whole shape of a complex character must
5700 fit on the line or it will be completely displayed in the
5701 next line.
5702
5703 Note that both for tabs and padding glyphs, all glyphs have
5704 the same width. */
5705 if (it->nglyphs)
5706 {
5707 /* More than one glyph or glyph doesn't fit on line. All
5708 glyphs have the same width. */
5709 int single_glyph_width = it->pixel_width / it->nglyphs;
5710 int new_x;
5711
5712 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5713 {
5714 new_x = x + single_glyph_width;
5715
5716 /* We want to leave anything reaching TO_X to the caller. */
5717 if ((op & MOVE_TO_X) && new_x > to_x)
5718 {
5719 if (BUFFER_POS_REACHED_P ())
5720 goto buffer_pos_reached;
5721 it->current_x = x;
5722 result = MOVE_X_REACHED;
5723 break;
5724 }
5725 else if (/* Lines are continued. */
5726 !it->truncate_lines_p
5727 && (/* And glyph doesn't fit on the line. */
5728 new_x > it->last_visible_x
5729 /* Or it fits exactly and we're on a window
5730 system frame. */
5731 || (new_x == it->last_visible_x
5732 && FRAME_WINDOW_P (it->f))))
5733 {
5734 if (/* IT->hpos == 0 means the very first glyph
5735 doesn't fit on the line, e.g. a wide image. */
5736 it->hpos == 0
5737 || (new_x == it->last_visible_x
5738 && FRAME_WINDOW_P (it->f)))
5739 {
5740 ++it->hpos;
5741 it->current_x = new_x;
5742 if (i == it->nglyphs - 1)
5743 {
5744 set_iterator_to_next (it, 1);
5745 #ifdef HAVE_WINDOW_SYSTEM
5746 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5747 {
5748 if (!get_next_display_element (it))
5749 {
5750 result = MOVE_POS_MATCH_OR_ZV;
5751 break;
5752 }
5753 if (BUFFER_POS_REACHED_P ())
5754 {
5755 if (ITERATOR_AT_END_OF_LINE_P (it))
5756 result = MOVE_POS_MATCH_OR_ZV;
5757 else
5758 result = MOVE_LINE_CONTINUED;
5759 break;
5760 }
5761 if (ITERATOR_AT_END_OF_LINE_P (it))
5762 {
5763 result = MOVE_NEWLINE_OR_CR;
5764 break;
5765 }
5766 }
5767 #endif /* HAVE_WINDOW_SYSTEM */
5768 }
5769 }
5770 else
5771 {
5772 it->current_x = x;
5773 it->max_ascent = ascent;
5774 it->max_descent = descent;
5775 }
5776
5777 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5778 IT_CHARPOS (*it)));
5779 result = MOVE_LINE_CONTINUED;
5780 break;
5781 }
5782 else if (BUFFER_POS_REACHED_P ())
5783 goto buffer_pos_reached;
5784 else if (new_x > it->first_visible_x)
5785 {
5786 /* Glyph is visible. Increment number of glyphs that
5787 would be displayed. */
5788 ++it->hpos;
5789 }
5790 else
5791 {
5792 /* Glyph is completely off the left margin of the display
5793 area. Nothing to do. */
5794 }
5795 }
5796
5797 if (result != MOVE_UNDEFINED)
5798 break;
5799 }
5800 else if (BUFFER_POS_REACHED_P ())
5801 {
5802 buffer_pos_reached:
5803 it->current_x = x;
5804 it->max_ascent = ascent;
5805 it->max_descent = descent;
5806 result = MOVE_POS_MATCH_OR_ZV;
5807 break;
5808 }
5809 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5810 {
5811 /* Stop when TO_X specified and reached. This check is
5812 necessary here because of lines consisting of a line end,
5813 only. The line end will not produce any glyphs and we
5814 would never get MOVE_X_REACHED. */
5815 xassert (it->nglyphs == 0);
5816 result = MOVE_X_REACHED;
5817 break;
5818 }
5819
5820 /* Is this a line end? If yes, we're done. */
5821 if (ITERATOR_AT_END_OF_LINE_P (it))
5822 {
5823 result = MOVE_NEWLINE_OR_CR;
5824 break;
5825 }
5826
5827 /* The current display element has been consumed. Advance
5828 to the next. */
5829 set_iterator_to_next (it, 1);
5830
5831 /* Stop if lines are truncated and IT's current x-position is
5832 past the right edge of the window now. */
5833 if (it->truncate_lines_p
5834 && it->current_x >= it->last_visible_x)
5835 {
5836 #ifdef HAVE_WINDOW_SYSTEM
5837 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5838 {
5839 if (!get_next_display_element (it)
5840 || BUFFER_POS_REACHED_P ())
5841 {
5842 result = MOVE_POS_MATCH_OR_ZV;
5843 break;
5844 }
5845 if (ITERATOR_AT_END_OF_LINE_P (it))
5846 {
5847 result = MOVE_NEWLINE_OR_CR;
5848 break;
5849 }
5850 }
5851 #endif /* HAVE_WINDOW_SYSTEM */
5852 result = MOVE_LINE_TRUNCATED;
5853 break;
5854 }
5855 }
5856
5857 #undef BUFFER_POS_REACHED_P
5858
5859 /* Restore the iterator settings altered at the beginning of this
5860 function. */
5861 it->glyph_row = saved_glyph_row;
5862 return result;
5863 }
5864
5865
5866 /* Move IT forward until it satisfies one or more of the criteria in
5867 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5868
5869 OP is a bit-mask that specifies where to stop, and in particular,
5870 which of those four position arguments makes a difference. See the
5871 description of enum move_operation_enum.
5872
5873 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5874 screen line, this function will set IT to the next position >
5875 TO_CHARPOS. */
5876
5877 void
5878 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5879 struct it *it;
5880 int to_charpos, to_x, to_y, to_vpos;
5881 int op;
5882 {
5883 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5884 int line_height;
5885 int reached = 0;
5886
5887 for (;;)
5888 {
5889 if (op & MOVE_TO_VPOS)
5890 {
5891 /* If no TO_CHARPOS and no TO_X specified, stop at the
5892 start of the line TO_VPOS. */
5893 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5894 {
5895 if (it->vpos == to_vpos)
5896 {
5897 reached = 1;
5898 break;
5899 }
5900 else
5901 skip = move_it_in_display_line_to (it, -1, -1, 0);
5902 }
5903 else
5904 {
5905 /* TO_VPOS >= 0 means stop at TO_X in the line at
5906 TO_VPOS, or at TO_POS, whichever comes first. */
5907 if (it->vpos == to_vpos)
5908 {
5909 reached = 2;
5910 break;
5911 }
5912
5913 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5914
5915 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5916 {
5917 reached = 3;
5918 break;
5919 }
5920 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5921 {
5922 /* We have reached TO_X but not in the line we want. */
5923 skip = move_it_in_display_line_to (it, to_charpos,
5924 -1, MOVE_TO_POS);
5925 if (skip == MOVE_POS_MATCH_OR_ZV)
5926 {
5927 reached = 4;
5928 break;
5929 }
5930 }
5931 }
5932 }
5933 else if (op & MOVE_TO_Y)
5934 {
5935 struct it it_backup;
5936
5937 /* TO_Y specified means stop at TO_X in the line containing
5938 TO_Y---or at TO_CHARPOS if this is reached first. The
5939 problem is that we can't really tell whether the line
5940 contains TO_Y before we have completely scanned it, and
5941 this may skip past TO_X. What we do is to first scan to
5942 TO_X.
5943
5944 If TO_X is not specified, use a TO_X of zero. The reason
5945 is to make the outcome of this function more predictable.
5946 If we didn't use TO_X == 0, we would stop at the end of
5947 the line which is probably not what a caller would expect
5948 to happen. */
5949 skip = move_it_in_display_line_to (it, to_charpos,
5950 ((op & MOVE_TO_X)
5951 ? to_x : 0),
5952 (MOVE_TO_X
5953 | (op & MOVE_TO_POS)));
5954
5955 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5956 if (skip == MOVE_POS_MATCH_OR_ZV)
5957 {
5958 reached = 5;
5959 break;
5960 }
5961
5962 /* If TO_X was reached, we would like to know whether TO_Y
5963 is in the line. This can only be said if we know the
5964 total line height which requires us to scan the rest of
5965 the line. */
5966 if (skip == MOVE_X_REACHED)
5967 {
5968 it_backup = *it;
5969 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5970 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5971 op & MOVE_TO_POS);
5972 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5973 }
5974
5975 /* Now, decide whether TO_Y is in this line. */
5976 line_height = it->max_ascent + it->max_descent;
5977 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5978
5979 if (to_y >= it->current_y
5980 && to_y < it->current_y + line_height)
5981 {
5982 if (skip == MOVE_X_REACHED)
5983 /* If TO_Y is in this line and TO_X was reached above,
5984 we scanned too far. We have to restore IT's settings
5985 to the ones before skipping. */
5986 *it = it_backup;
5987 reached = 6;
5988 }
5989 else if (skip == MOVE_X_REACHED)
5990 {
5991 skip = skip2;
5992 if (skip == MOVE_POS_MATCH_OR_ZV)
5993 reached = 7;
5994 }
5995
5996 if (reached)
5997 break;
5998 }
5999 else
6000 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6001
6002 switch (skip)
6003 {
6004 case MOVE_POS_MATCH_OR_ZV:
6005 reached = 8;
6006 goto out;
6007
6008 case MOVE_NEWLINE_OR_CR:
6009 set_iterator_to_next (it, 1);
6010 it->continuation_lines_width = 0;
6011 break;
6012
6013 case MOVE_LINE_TRUNCATED:
6014 it->continuation_lines_width = 0;
6015 reseat_at_next_visible_line_start (it, 0);
6016 if ((op & MOVE_TO_POS) != 0
6017 && IT_CHARPOS (*it) > to_charpos)
6018 {
6019 reached = 9;
6020 goto out;
6021 }
6022 break;
6023
6024 case MOVE_LINE_CONTINUED:
6025 it->continuation_lines_width += it->current_x;
6026 break;
6027
6028 default:
6029 abort ();
6030 }
6031
6032 /* Reset/increment for the next run. */
6033 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6034 it->current_x = it->hpos = 0;
6035 it->current_y += it->max_ascent + it->max_descent;
6036 ++it->vpos;
6037 last_height = it->max_ascent + it->max_descent;
6038 last_max_ascent = it->max_ascent;
6039 it->max_ascent = it->max_descent = 0;
6040 }
6041
6042 out:
6043
6044 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6045 }
6046
6047
6048 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6049
6050 If DY > 0, move IT backward at least that many pixels. DY = 0
6051 means move IT backward to the preceding line start or BEGV. This
6052 function may move over more than DY pixels if IT->current_y - DY
6053 ends up in the middle of a line; in this case IT->current_y will be
6054 set to the top of the line moved to. */
6055
6056 void
6057 move_it_vertically_backward (it, dy)
6058 struct it *it;
6059 int dy;
6060 {
6061 int nlines, h;
6062 struct it it2, it3;
6063 int start_pos = IT_CHARPOS (*it);
6064
6065 xassert (dy >= 0);
6066
6067 /* Estimate how many newlines we must move back. */
6068 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6069
6070 /* Set the iterator's position that many lines back. */
6071 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6072 back_to_previous_visible_line_start (it);
6073
6074 /* Reseat the iterator here. When moving backward, we don't want
6075 reseat to skip forward over invisible text, set up the iterator
6076 to deliver from overlay strings at the new position etc. So,
6077 use reseat_1 here. */
6078 reseat_1 (it, it->current.pos, 1);
6079
6080 /* We are now surely at a line start. */
6081 it->current_x = it->hpos = 0;
6082 it->continuation_lines_width = 0;
6083
6084 /* Move forward and see what y-distance we moved. First move to the
6085 start of the next line so that we get its height. We need this
6086 height to be able to tell whether we reached the specified
6087 y-distance. */
6088 it2 = *it;
6089 it2.max_ascent = it2.max_descent = 0;
6090 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6091 MOVE_TO_POS | MOVE_TO_VPOS);
6092 xassert (IT_CHARPOS (*it) >= BEGV);
6093 it3 = it2;
6094
6095 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6096 xassert (IT_CHARPOS (*it) >= BEGV);
6097 /* H is the actual vertical distance from the position in *IT
6098 and the starting position. */
6099 h = it2.current_y - it->current_y;
6100 /* NLINES is the distance in number of lines. */
6101 nlines = it2.vpos - it->vpos;
6102
6103 /* Correct IT's y and vpos position
6104 so that they are relative to the starting point. */
6105 it->vpos -= nlines;
6106 it->current_y -= h;
6107
6108 if (dy == 0)
6109 {
6110 /* DY == 0 means move to the start of the screen line. The
6111 value of nlines is > 0 if continuation lines were involved. */
6112 if (nlines > 0)
6113 move_it_by_lines (it, nlines, 1);
6114 xassert (IT_CHARPOS (*it) <= start_pos);
6115 }
6116 else
6117 {
6118 /* The y-position we try to reach, relative to *IT.
6119 Note that H has been subtracted in front of the if-statement. */
6120 int target_y = it->current_y + h - dy;
6121 int y0 = it3.current_y;
6122 int y1 = line_bottom_y (&it3);
6123 int line_height = y1 - y0;
6124
6125 /* If we did not reach target_y, try to move further backward if
6126 we can. If we moved too far backward, try to move forward. */
6127 if (target_y < it->current_y
6128 /* This is heuristic. In a window that's 3 lines high, with
6129 a line height of 13 pixels each, recentering with point
6130 on the bottom line will try to move -39/2 = 19 pixels
6131 backward. Try to avoid moving into the first line. */
6132 && it->current_y - target_y > line_height / 3 * 2
6133 && IT_CHARPOS (*it) > BEGV)
6134 {
6135 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6136 target_y - it->current_y));
6137 move_it_vertically (it, target_y - it->current_y);
6138 xassert (IT_CHARPOS (*it) >= BEGV);
6139 }
6140 else if (target_y >= it->current_y + line_height
6141 && IT_CHARPOS (*it) < ZV)
6142 {
6143 /* Should move forward by at least one line, maybe more.
6144
6145 Note: Calling move_it_by_lines can be expensive on
6146 terminal frames, where compute_motion is used (via
6147 vmotion) to do the job, when there are very long lines
6148 and truncate-lines is nil. That's the reason for
6149 treating terminal frames specially here. */
6150
6151 if (!FRAME_WINDOW_P (it->f))
6152 move_it_vertically (it, target_y - (it->current_y + line_height));
6153 else
6154 {
6155 do
6156 {
6157 move_it_by_lines (it, 1, 1);
6158 }
6159 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6160 }
6161
6162 xassert (IT_CHARPOS (*it) >= BEGV);
6163 }
6164 }
6165 }
6166
6167
6168 /* Move IT by a specified amount of pixel lines DY. DY negative means
6169 move backwards. DY = 0 means move to start of screen line. At the
6170 end, IT will be on the start of a screen line. */
6171
6172 void
6173 move_it_vertically (it, dy)
6174 struct it *it;
6175 int dy;
6176 {
6177 if (dy <= 0)
6178 move_it_vertically_backward (it, -dy);
6179 else if (dy > 0)
6180 {
6181 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6182 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6183 MOVE_TO_POS | MOVE_TO_Y);
6184 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6185
6186 /* If buffer ends in ZV without a newline, move to the start of
6187 the line to satisfy the post-condition. */
6188 if (IT_CHARPOS (*it) == ZV
6189 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6190 move_it_by_lines (it, 0, 0);
6191 }
6192 }
6193
6194
6195 /* Move iterator IT past the end of the text line it is in. */
6196
6197 void
6198 move_it_past_eol (it)
6199 struct it *it;
6200 {
6201 enum move_it_result rc;
6202
6203 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6204 if (rc == MOVE_NEWLINE_OR_CR)
6205 set_iterator_to_next (it, 0);
6206 }
6207
6208
6209 #if 0 /* Currently not used. */
6210
6211 /* Return non-zero if some text between buffer positions START_CHARPOS
6212 and END_CHARPOS is invisible. IT->window is the window for text
6213 property lookup. */
6214
6215 static int
6216 invisible_text_between_p (it, start_charpos, end_charpos)
6217 struct it *it;
6218 int start_charpos, end_charpos;
6219 {
6220 Lisp_Object prop, limit;
6221 int invisible_found_p;
6222
6223 xassert (it != NULL && start_charpos <= end_charpos);
6224
6225 /* Is text at START invisible? */
6226 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6227 it->window);
6228 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6229 invisible_found_p = 1;
6230 else
6231 {
6232 limit = Fnext_single_char_property_change (make_number (start_charpos),
6233 Qinvisible, Qnil,
6234 make_number (end_charpos));
6235 invisible_found_p = XFASTINT (limit) < end_charpos;
6236 }
6237
6238 return invisible_found_p;
6239 }
6240
6241 #endif /* 0 */
6242
6243
6244 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6245 negative means move up. DVPOS == 0 means move to the start of the
6246 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6247 NEED_Y_P is zero, IT->current_y will be left unchanged.
6248
6249 Further optimization ideas: If we would know that IT->f doesn't use
6250 a face with proportional font, we could be faster for
6251 truncate-lines nil. */
6252
6253 void
6254 move_it_by_lines (it, dvpos, need_y_p)
6255 struct it *it;
6256 int dvpos, need_y_p;
6257 {
6258 struct position pos;
6259
6260 if (!FRAME_WINDOW_P (it->f))
6261 {
6262 struct text_pos textpos;
6263
6264 /* We can use vmotion on frames without proportional fonts. */
6265 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6266 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6267 reseat (it, textpos, 1);
6268 it->vpos += pos.vpos;
6269 it->current_y += pos.vpos;
6270 }
6271 else if (dvpos == 0)
6272 {
6273 /* DVPOS == 0 means move to the start of the screen line. */
6274 move_it_vertically_backward (it, 0);
6275 xassert (it->current_x == 0 && it->hpos == 0);
6276 }
6277 else if (dvpos > 0)
6278 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6279 else
6280 {
6281 struct it it2;
6282 int start_charpos, i;
6283
6284 /* Start at the beginning of the screen line containing IT's
6285 position. */
6286 move_it_vertically_backward (it, 0);
6287
6288 /* Go back -DVPOS visible lines and reseat the iterator there. */
6289 start_charpos = IT_CHARPOS (*it);
6290 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6291 back_to_previous_visible_line_start (it);
6292 reseat (it, it->current.pos, 1);
6293 it->current_x = it->hpos = 0;
6294
6295 /* Above call may have moved too far if continuation lines
6296 are involved. Scan forward and see if it did. */
6297 it2 = *it;
6298 it2.vpos = it2.current_y = 0;
6299 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6300 it->vpos -= it2.vpos;
6301 it->current_y -= it2.current_y;
6302 it->current_x = it->hpos = 0;
6303
6304 /* If we moved too far, move IT some lines forward. */
6305 if (it2.vpos > -dvpos)
6306 {
6307 int delta = it2.vpos + dvpos;
6308 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6309 }
6310 }
6311 }
6312
6313 /* Return 1 if IT points into the middle of a display vector. */
6314
6315 int
6316 in_display_vector_p (it)
6317 struct it *it;
6318 {
6319 return (it->method == next_element_from_display_vector
6320 && it->current.dpvec_index > 0
6321 && it->dpvec + it->current.dpvec_index != it->dpend);
6322 }
6323
6324 \f
6325 /***********************************************************************
6326 Messages
6327 ***********************************************************************/
6328
6329
6330 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6331 to *Messages*. */
6332
6333 void
6334 add_to_log (format, arg1, arg2)
6335 char *format;
6336 Lisp_Object arg1, arg2;
6337 {
6338 Lisp_Object args[3];
6339 Lisp_Object msg, fmt;
6340 char *buffer;
6341 int len;
6342 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6343 USE_SAFE_ALLOCA;
6344
6345 /* Do nothing if called asynchronously. Inserting text into
6346 a buffer may call after-change-functions and alike and
6347 that would means running Lisp asynchronously. */
6348 if (handling_signal)
6349 return;
6350
6351 fmt = msg = Qnil;
6352 GCPRO4 (fmt, msg, arg1, arg2);
6353
6354 args[0] = fmt = build_string (format);
6355 args[1] = arg1;
6356 args[2] = arg2;
6357 msg = Fformat (3, args);
6358
6359 len = SBYTES (msg) + 1;
6360 SAFE_ALLOCA (buffer, char *, len);
6361 bcopy (SDATA (msg), buffer, len);
6362
6363 message_dolog (buffer, len - 1, 1, 0);
6364 SAFE_FREE (len);
6365
6366 UNGCPRO;
6367 }
6368
6369
6370 /* Output a newline in the *Messages* buffer if "needs" one. */
6371
6372 void
6373 message_log_maybe_newline ()
6374 {
6375 if (message_log_need_newline)
6376 message_dolog ("", 0, 1, 0);
6377 }
6378
6379
6380 /* Add a string M of length NBYTES to the message log, optionally
6381 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6382 nonzero, means interpret the contents of M as multibyte. This
6383 function calls low-level routines in order to bypass text property
6384 hooks, etc. which might not be safe to run. */
6385
6386 void
6387 message_dolog (m, nbytes, nlflag, multibyte)
6388 const char *m;
6389 int nbytes, nlflag, multibyte;
6390 {
6391 if (!NILP (Vmemory_full))
6392 return;
6393
6394 if (!NILP (Vmessage_log_max))
6395 {
6396 struct buffer *oldbuf;
6397 Lisp_Object oldpoint, oldbegv, oldzv;
6398 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6399 int point_at_end = 0;
6400 int zv_at_end = 0;
6401 Lisp_Object old_deactivate_mark, tem;
6402 struct gcpro gcpro1;
6403
6404 old_deactivate_mark = Vdeactivate_mark;
6405 oldbuf = current_buffer;
6406 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6407 current_buffer->undo_list = Qt;
6408
6409 oldpoint = message_dolog_marker1;
6410 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6411 oldbegv = message_dolog_marker2;
6412 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6413 oldzv = message_dolog_marker3;
6414 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6415 GCPRO1 (old_deactivate_mark);
6416
6417 if (PT == Z)
6418 point_at_end = 1;
6419 if (ZV == Z)
6420 zv_at_end = 1;
6421
6422 BEGV = BEG;
6423 BEGV_BYTE = BEG_BYTE;
6424 ZV = Z;
6425 ZV_BYTE = Z_BYTE;
6426 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6427
6428 /* Insert the string--maybe converting multibyte to single byte
6429 or vice versa, so that all the text fits the buffer. */
6430 if (multibyte
6431 && NILP (current_buffer->enable_multibyte_characters))
6432 {
6433 int i, c, char_bytes;
6434 unsigned char work[1];
6435
6436 /* Convert a multibyte string to single-byte
6437 for the *Message* buffer. */
6438 for (i = 0; i < nbytes; i += char_bytes)
6439 {
6440 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6441 work[0] = (SINGLE_BYTE_CHAR_P (c)
6442 ? c
6443 : multibyte_char_to_unibyte (c, Qnil));
6444 insert_1_both (work, 1, 1, 1, 0, 0);
6445 }
6446 }
6447 else if (! multibyte
6448 && ! NILP (current_buffer->enable_multibyte_characters))
6449 {
6450 int i, c, char_bytes;
6451 unsigned char *msg = (unsigned char *) m;
6452 unsigned char str[MAX_MULTIBYTE_LENGTH];
6453 /* Convert a single-byte string to multibyte
6454 for the *Message* buffer. */
6455 for (i = 0; i < nbytes; i++)
6456 {
6457 c = unibyte_char_to_multibyte (msg[i]);
6458 char_bytes = CHAR_STRING (c, str);
6459 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6460 }
6461 }
6462 else if (nbytes)
6463 insert_1 (m, nbytes, 1, 0, 0);
6464
6465 if (nlflag)
6466 {
6467 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6468 insert_1 ("\n", 1, 1, 0, 0);
6469
6470 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6471 this_bol = PT;
6472 this_bol_byte = PT_BYTE;
6473
6474 /* See if this line duplicates the previous one.
6475 If so, combine duplicates. */
6476 if (this_bol > BEG)
6477 {
6478 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6479 prev_bol = PT;
6480 prev_bol_byte = PT_BYTE;
6481
6482 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6483 this_bol, this_bol_byte);
6484 if (dup)
6485 {
6486 del_range_both (prev_bol, prev_bol_byte,
6487 this_bol, this_bol_byte, 0);
6488 if (dup > 1)
6489 {
6490 char dupstr[40];
6491 int duplen;
6492
6493 /* If you change this format, don't forget to also
6494 change message_log_check_duplicate. */
6495 sprintf (dupstr, " [%d times]", dup);
6496 duplen = strlen (dupstr);
6497 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6498 insert_1 (dupstr, duplen, 1, 0, 1);
6499 }
6500 }
6501 }
6502
6503 /* If we have more than the desired maximum number of lines
6504 in the *Messages* buffer now, delete the oldest ones.
6505 This is safe because we don't have undo in this buffer. */
6506
6507 if (NATNUMP (Vmessage_log_max))
6508 {
6509 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6510 -XFASTINT (Vmessage_log_max) - 1, 0);
6511 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6512 }
6513 }
6514 BEGV = XMARKER (oldbegv)->charpos;
6515 BEGV_BYTE = marker_byte_position (oldbegv);
6516
6517 if (zv_at_end)
6518 {
6519 ZV = Z;
6520 ZV_BYTE = Z_BYTE;
6521 }
6522 else
6523 {
6524 ZV = XMARKER (oldzv)->charpos;
6525 ZV_BYTE = marker_byte_position (oldzv);
6526 }
6527
6528 if (point_at_end)
6529 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6530 else
6531 /* We can't do Fgoto_char (oldpoint) because it will run some
6532 Lisp code. */
6533 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6534 XMARKER (oldpoint)->bytepos);
6535
6536 UNGCPRO;
6537 unchain_marker (XMARKER (oldpoint));
6538 unchain_marker (XMARKER (oldbegv));
6539 unchain_marker (XMARKER (oldzv));
6540
6541 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6542 set_buffer_internal (oldbuf);
6543 if (NILP (tem))
6544 windows_or_buffers_changed = old_windows_or_buffers_changed;
6545 message_log_need_newline = !nlflag;
6546 Vdeactivate_mark = old_deactivate_mark;
6547 }
6548 }
6549
6550
6551 /* We are at the end of the buffer after just having inserted a newline.
6552 (Note: We depend on the fact we won't be crossing the gap.)
6553 Check to see if the most recent message looks a lot like the previous one.
6554 Return 0 if different, 1 if the new one should just replace it, or a
6555 value N > 1 if we should also append " [N times]". */
6556
6557 static int
6558 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6559 int prev_bol, this_bol;
6560 int prev_bol_byte, this_bol_byte;
6561 {
6562 int i;
6563 int len = Z_BYTE - 1 - this_bol_byte;
6564 int seen_dots = 0;
6565 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6566 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6567
6568 for (i = 0; i < len; i++)
6569 {
6570 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6571 seen_dots = 1;
6572 if (p1[i] != p2[i])
6573 return seen_dots;
6574 }
6575 p1 += len;
6576 if (*p1 == '\n')
6577 return 2;
6578 if (*p1++ == ' ' && *p1++ == '[')
6579 {
6580 int n = 0;
6581 while (*p1 >= '0' && *p1 <= '9')
6582 n = n * 10 + *p1++ - '0';
6583 if (strncmp (p1, " times]\n", 8) == 0)
6584 return n+1;
6585 }
6586 return 0;
6587 }
6588
6589
6590 /* Display an echo area message M with a specified length of NBYTES
6591 bytes. The string may include null characters. If M is 0, clear
6592 out any existing message, and let the mini-buffer text show
6593 through.
6594
6595 The buffer M must continue to exist until after the echo area gets
6596 cleared or some other message gets displayed there. This means do
6597 not pass text that is stored in a Lisp string; do not pass text in
6598 a buffer that was alloca'd. */
6599
6600 void
6601 message2 (m, nbytes, multibyte)
6602 const char *m;
6603 int nbytes;
6604 int multibyte;
6605 {
6606 /* First flush out any partial line written with print. */
6607 message_log_maybe_newline ();
6608 if (m)
6609 message_dolog (m, nbytes, 1, multibyte);
6610 message2_nolog (m, nbytes, multibyte);
6611 }
6612
6613
6614 /* The non-logging counterpart of message2. */
6615
6616 void
6617 message2_nolog (m, nbytes, multibyte)
6618 const char *m;
6619 int nbytes, multibyte;
6620 {
6621 struct frame *sf = SELECTED_FRAME ();
6622 message_enable_multibyte = multibyte;
6623
6624 if (noninteractive)
6625 {
6626 if (noninteractive_need_newline)
6627 putc ('\n', stderr);
6628 noninteractive_need_newline = 0;
6629 if (m)
6630 fwrite (m, nbytes, 1, stderr);
6631 if (cursor_in_echo_area == 0)
6632 fprintf (stderr, "\n");
6633 fflush (stderr);
6634 }
6635 /* A null message buffer means that the frame hasn't really been
6636 initialized yet. Error messages get reported properly by
6637 cmd_error, so this must be just an informative message; toss it. */
6638 else if (INTERACTIVE
6639 && sf->glyphs_initialized_p
6640 && FRAME_MESSAGE_BUF (sf))
6641 {
6642 Lisp_Object mini_window;
6643 struct frame *f;
6644
6645 /* Get the frame containing the mini-buffer
6646 that the selected frame is using. */
6647 mini_window = FRAME_MINIBUF_WINDOW (sf);
6648 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6649
6650 FRAME_SAMPLE_VISIBILITY (f);
6651 if (FRAME_VISIBLE_P (sf)
6652 && ! FRAME_VISIBLE_P (f))
6653 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6654
6655 if (m)
6656 {
6657 set_message (m, Qnil, nbytes, multibyte);
6658 if (minibuffer_auto_raise)
6659 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6660 }
6661 else
6662 clear_message (1, 1);
6663
6664 do_pending_window_change (0);
6665 echo_area_display (1);
6666 do_pending_window_change (0);
6667 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6668 (*frame_up_to_date_hook) (f);
6669 }
6670 }
6671
6672
6673 /* Display an echo area message M with a specified length of NBYTES
6674 bytes. The string may include null characters. If M is not a
6675 string, clear out any existing message, and let the mini-buffer
6676 text show through. */
6677
6678 void
6679 message3 (m, nbytes, multibyte)
6680 Lisp_Object m;
6681 int nbytes;
6682 int multibyte;
6683 {
6684 struct gcpro gcpro1;
6685
6686 GCPRO1 (m);
6687
6688 /* First flush out any partial line written with print. */
6689 message_log_maybe_newline ();
6690 if (STRINGP (m))
6691 message_dolog (SDATA (m), nbytes, 1, multibyte);
6692 message3_nolog (m, nbytes, multibyte);
6693
6694 UNGCPRO;
6695 }
6696
6697
6698 /* The non-logging version of message3. */
6699
6700 void
6701 message3_nolog (m, nbytes, multibyte)
6702 Lisp_Object m;
6703 int nbytes, multibyte;
6704 {
6705 struct frame *sf = SELECTED_FRAME ();
6706 message_enable_multibyte = multibyte;
6707
6708 if (noninteractive)
6709 {
6710 if (noninteractive_need_newline)
6711 putc ('\n', stderr);
6712 noninteractive_need_newline = 0;
6713 if (STRINGP (m))
6714 fwrite (SDATA (m), nbytes, 1, stderr);
6715 if (cursor_in_echo_area == 0)
6716 fprintf (stderr, "\n");
6717 fflush (stderr);
6718 }
6719 /* A null message buffer means that the frame hasn't really been
6720 initialized yet. Error messages get reported properly by
6721 cmd_error, so this must be just an informative message; toss it. */
6722 else if (INTERACTIVE
6723 && sf->glyphs_initialized_p
6724 && FRAME_MESSAGE_BUF (sf))
6725 {
6726 Lisp_Object mini_window;
6727 Lisp_Object frame;
6728 struct frame *f;
6729
6730 /* Get the frame containing the mini-buffer
6731 that the selected frame is using. */
6732 mini_window = FRAME_MINIBUF_WINDOW (sf);
6733 frame = XWINDOW (mini_window)->frame;
6734 f = XFRAME (frame);
6735
6736 FRAME_SAMPLE_VISIBILITY (f);
6737 if (FRAME_VISIBLE_P (sf)
6738 && !FRAME_VISIBLE_P (f))
6739 Fmake_frame_visible (frame);
6740
6741 if (STRINGP (m) && SCHARS (m) > 0)
6742 {
6743 set_message (NULL, m, nbytes, multibyte);
6744 if (minibuffer_auto_raise)
6745 Fraise_frame (frame);
6746 }
6747 else
6748 clear_message (1, 1);
6749
6750 do_pending_window_change (0);
6751 echo_area_display (1);
6752 do_pending_window_change (0);
6753 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6754 (*frame_up_to_date_hook) (f);
6755 }
6756 }
6757
6758
6759 /* Display a null-terminated echo area message M. If M is 0, clear
6760 out any existing message, and let the mini-buffer text show through.
6761
6762 The buffer M must continue to exist until after the echo area gets
6763 cleared or some other message gets displayed there. Do not pass
6764 text that is stored in a Lisp string. Do not pass text in a buffer
6765 that was alloca'd. */
6766
6767 void
6768 message1 (m)
6769 char *m;
6770 {
6771 message2 (m, (m ? strlen (m) : 0), 0);
6772 }
6773
6774
6775 /* The non-logging counterpart of message1. */
6776
6777 void
6778 message1_nolog (m)
6779 char *m;
6780 {
6781 message2_nolog (m, (m ? strlen (m) : 0), 0);
6782 }
6783
6784 /* Display a message M which contains a single %s
6785 which gets replaced with STRING. */
6786
6787 void
6788 message_with_string (m, string, log)
6789 char *m;
6790 Lisp_Object string;
6791 int log;
6792 {
6793 CHECK_STRING (string);
6794
6795 if (noninteractive)
6796 {
6797 if (m)
6798 {
6799 if (noninteractive_need_newline)
6800 putc ('\n', stderr);
6801 noninteractive_need_newline = 0;
6802 fprintf (stderr, m, SDATA (string));
6803 if (cursor_in_echo_area == 0)
6804 fprintf (stderr, "\n");
6805 fflush (stderr);
6806 }
6807 }
6808 else if (INTERACTIVE)
6809 {
6810 /* The frame whose minibuffer we're going to display the message on.
6811 It may be larger than the selected frame, so we need
6812 to use its buffer, not the selected frame's buffer. */
6813 Lisp_Object mini_window;
6814 struct frame *f, *sf = SELECTED_FRAME ();
6815
6816 /* Get the frame containing the minibuffer
6817 that the selected frame is using. */
6818 mini_window = FRAME_MINIBUF_WINDOW (sf);
6819 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6820
6821 /* A null message buffer means that the frame hasn't really been
6822 initialized yet. Error messages get reported properly by
6823 cmd_error, so this must be just an informative message; toss it. */
6824 if (FRAME_MESSAGE_BUF (f))
6825 {
6826 Lisp_Object args[2], message;
6827 struct gcpro gcpro1, gcpro2;
6828
6829 args[0] = build_string (m);
6830 args[1] = message = string;
6831 GCPRO2 (args[0], message);
6832 gcpro1.nvars = 2;
6833
6834 message = Fformat (2, args);
6835
6836 if (log)
6837 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6838 else
6839 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6840
6841 UNGCPRO;
6842
6843 /* Print should start at the beginning of the message
6844 buffer next time. */
6845 message_buf_print = 0;
6846 }
6847 }
6848 }
6849
6850
6851 /* Dump an informative message to the minibuf. If M is 0, clear out
6852 any existing message, and let the mini-buffer text show through. */
6853
6854 /* VARARGS 1 */
6855 void
6856 message (m, a1, a2, a3)
6857 char *m;
6858 EMACS_INT a1, a2, a3;
6859 {
6860 if (noninteractive)
6861 {
6862 if (m)
6863 {
6864 if (noninteractive_need_newline)
6865 putc ('\n', stderr);
6866 noninteractive_need_newline = 0;
6867 fprintf (stderr, m, a1, a2, a3);
6868 if (cursor_in_echo_area == 0)
6869 fprintf (stderr, "\n");
6870 fflush (stderr);
6871 }
6872 }
6873 else if (INTERACTIVE)
6874 {
6875 /* The frame whose mini-buffer we're going to display the message
6876 on. It may be larger than the selected frame, so we need to
6877 use its buffer, not the selected frame's buffer. */
6878 Lisp_Object mini_window;
6879 struct frame *f, *sf = SELECTED_FRAME ();
6880
6881 /* Get the frame containing the mini-buffer
6882 that the selected frame is using. */
6883 mini_window = FRAME_MINIBUF_WINDOW (sf);
6884 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6885
6886 /* A null message buffer means that the frame hasn't really been
6887 initialized yet. Error messages get reported properly by
6888 cmd_error, so this must be just an informative message; toss
6889 it. */
6890 if (FRAME_MESSAGE_BUF (f))
6891 {
6892 if (m)
6893 {
6894 int len;
6895 #ifdef NO_ARG_ARRAY
6896 char *a[3];
6897 a[0] = (char *) a1;
6898 a[1] = (char *) a2;
6899 a[2] = (char *) a3;
6900
6901 len = doprnt (FRAME_MESSAGE_BUF (f),
6902 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6903 #else
6904 len = doprnt (FRAME_MESSAGE_BUF (f),
6905 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6906 (char **) &a1);
6907 #endif /* NO_ARG_ARRAY */
6908
6909 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6910 }
6911 else
6912 message1 (0);
6913
6914 /* Print should start at the beginning of the message
6915 buffer next time. */
6916 message_buf_print = 0;
6917 }
6918 }
6919 }
6920
6921
6922 /* The non-logging version of message. */
6923
6924 void
6925 message_nolog (m, a1, a2, a3)
6926 char *m;
6927 EMACS_INT a1, a2, a3;
6928 {
6929 Lisp_Object old_log_max;
6930 old_log_max = Vmessage_log_max;
6931 Vmessage_log_max = Qnil;
6932 message (m, a1, a2, a3);
6933 Vmessage_log_max = old_log_max;
6934 }
6935
6936
6937 /* Display the current message in the current mini-buffer. This is
6938 only called from error handlers in process.c, and is not time
6939 critical. */
6940
6941 void
6942 update_echo_area ()
6943 {
6944 if (!NILP (echo_area_buffer[0]))
6945 {
6946 Lisp_Object string;
6947 string = Fcurrent_message ();
6948 message3 (string, SBYTES (string),
6949 !NILP (current_buffer->enable_multibyte_characters));
6950 }
6951 }
6952
6953
6954 /* Make sure echo area buffers in `echo_buffers' are live.
6955 If they aren't, make new ones. */
6956
6957 static void
6958 ensure_echo_area_buffers ()
6959 {
6960 int i;
6961
6962 for (i = 0; i < 2; ++i)
6963 if (!BUFFERP (echo_buffer[i])
6964 || NILP (XBUFFER (echo_buffer[i])->name))
6965 {
6966 char name[30];
6967 Lisp_Object old_buffer;
6968 int j;
6969
6970 old_buffer = echo_buffer[i];
6971 sprintf (name, " *Echo Area %d*", i);
6972 echo_buffer[i] = Fget_buffer_create (build_string (name));
6973 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6974
6975 for (j = 0; j < 2; ++j)
6976 if (EQ (old_buffer, echo_area_buffer[j]))
6977 echo_area_buffer[j] = echo_buffer[i];
6978 }
6979 }
6980
6981
6982 /* Call FN with args A1..A4 with either the current or last displayed
6983 echo_area_buffer as current buffer.
6984
6985 WHICH zero means use the current message buffer
6986 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6987 from echo_buffer[] and clear it.
6988
6989 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6990 suitable buffer from echo_buffer[] and clear it.
6991
6992 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6993 that the current message becomes the last displayed one, make
6994 choose a suitable buffer for echo_area_buffer[0], and clear it.
6995
6996 Value is what FN returns. */
6997
6998 static int
6999 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7000 struct window *w;
7001 int which;
7002 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7003 EMACS_INT a1;
7004 Lisp_Object a2;
7005 EMACS_INT a3, a4;
7006 {
7007 Lisp_Object buffer;
7008 int this_one, the_other, clear_buffer_p, rc;
7009 int count = SPECPDL_INDEX ();
7010
7011 /* If buffers aren't live, make new ones. */
7012 ensure_echo_area_buffers ();
7013
7014 clear_buffer_p = 0;
7015
7016 if (which == 0)
7017 this_one = 0, the_other = 1;
7018 else if (which > 0)
7019 this_one = 1, the_other = 0;
7020 else
7021 {
7022 this_one = 0, the_other = 1;
7023 clear_buffer_p = 1;
7024
7025 /* We need a fresh one in case the current echo buffer equals
7026 the one containing the last displayed echo area message. */
7027 if (!NILP (echo_area_buffer[this_one])
7028 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7029 echo_area_buffer[this_one] = Qnil;
7030 }
7031
7032 /* Choose a suitable buffer from echo_buffer[] is we don't
7033 have one. */
7034 if (NILP (echo_area_buffer[this_one]))
7035 {
7036 echo_area_buffer[this_one]
7037 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7038 ? echo_buffer[the_other]
7039 : echo_buffer[this_one]);
7040 clear_buffer_p = 1;
7041 }
7042
7043 buffer = echo_area_buffer[this_one];
7044
7045 /* Don't get confused by reusing the buffer used for echoing
7046 for a different purpose. */
7047 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7048 cancel_echoing ();
7049
7050 record_unwind_protect (unwind_with_echo_area_buffer,
7051 with_echo_area_buffer_unwind_data (w));
7052
7053 /* Make the echo area buffer current. Note that for display
7054 purposes, it is not necessary that the displayed window's buffer
7055 == current_buffer, except for text property lookup. So, let's
7056 only set that buffer temporarily here without doing a full
7057 Fset_window_buffer. We must also change w->pointm, though,
7058 because otherwise an assertions in unshow_buffer fails, and Emacs
7059 aborts. */
7060 set_buffer_internal_1 (XBUFFER (buffer));
7061 if (w)
7062 {
7063 w->buffer = buffer;
7064 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7065 }
7066
7067 current_buffer->undo_list = Qt;
7068 current_buffer->read_only = Qnil;
7069 specbind (Qinhibit_read_only, Qt);
7070 specbind (Qinhibit_modification_hooks, Qt);
7071
7072 if (clear_buffer_p && Z > BEG)
7073 del_range (BEG, Z);
7074
7075 xassert (BEGV >= BEG);
7076 xassert (ZV <= Z && ZV >= BEGV);
7077
7078 rc = fn (a1, a2, a3, a4);
7079
7080 xassert (BEGV >= BEG);
7081 xassert (ZV <= Z && ZV >= BEGV);
7082
7083 unbind_to (count, Qnil);
7084 return rc;
7085 }
7086
7087
7088 /* Save state that should be preserved around the call to the function
7089 FN called in with_echo_area_buffer. */
7090
7091 static Lisp_Object
7092 with_echo_area_buffer_unwind_data (w)
7093 struct window *w;
7094 {
7095 int i = 0;
7096 Lisp_Object vector;
7097
7098 /* Reduce consing by keeping one vector in
7099 Vwith_echo_area_save_vector. */
7100 vector = Vwith_echo_area_save_vector;
7101 Vwith_echo_area_save_vector = Qnil;
7102
7103 if (NILP (vector))
7104 vector = Fmake_vector (make_number (7), Qnil);
7105
7106 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7107 AREF (vector, i) = Vdeactivate_mark, ++i;
7108 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7109
7110 if (w)
7111 {
7112 XSETWINDOW (AREF (vector, i), w); ++i;
7113 AREF (vector, i) = w->buffer; ++i;
7114 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7115 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7116 }
7117 else
7118 {
7119 int end = i + 4;
7120 for (; i < end; ++i)
7121 AREF (vector, i) = Qnil;
7122 }
7123
7124 xassert (i == ASIZE (vector));
7125 return vector;
7126 }
7127
7128
7129 /* Restore global state from VECTOR which was created by
7130 with_echo_area_buffer_unwind_data. */
7131
7132 static Lisp_Object
7133 unwind_with_echo_area_buffer (vector)
7134 Lisp_Object vector;
7135 {
7136 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7137 Vdeactivate_mark = AREF (vector, 1);
7138 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7139
7140 if (WINDOWP (AREF (vector, 3)))
7141 {
7142 struct window *w;
7143 Lisp_Object buffer, charpos, bytepos;
7144
7145 w = XWINDOW (AREF (vector, 3));
7146 buffer = AREF (vector, 4);
7147 charpos = AREF (vector, 5);
7148 bytepos = AREF (vector, 6);
7149
7150 w->buffer = buffer;
7151 set_marker_both (w->pointm, buffer,
7152 XFASTINT (charpos), XFASTINT (bytepos));
7153 }
7154
7155 Vwith_echo_area_save_vector = vector;
7156 return Qnil;
7157 }
7158
7159
7160 /* Set up the echo area for use by print functions. MULTIBYTE_P
7161 non-zero means we will print multibyte. */
7162
7163 void
7164 setup_echo_area_for_printing (multibyte_p)
7165 int multibyte_p;
7166 {
7167 /* If we can't find an echo area any more, exit. */
7168 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7169 Fkill_emacs (Qnil);
7170
7171 ensure_echo_area_buffers ();
7172
7173 if (!message_buf_print)
7174 {
7175 /* A message has been output since the last time we printed.
7176 Choose a fresh echo area buffer. */
7177 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7178 echo_area_buffer[0] = echo_buffer[1];
7179 else
7180 echo_area_buffer[0] = echo_buffer[0];
7181
7182 /* Switch to that buffer and clear it. */
7183 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7184 current_buffer->truncate_lines = Qnil;
7185
7186 if (Z > BEG)
7187 {
7188 int count = SPECPDL_INDEX ();
7189 specbind (Qinhibit_read_only, Qt);
7190 /* Note that undo recording is always disabled. */
7191 del_range (BEG, Z);
7192 unbind_to (count, Qnil);
7193 }
7194 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7195
7196 /* Set up the buffer for the multibyteness we need. */
7197 if (multibyte_p
7198 != !NILP (current_buffer->enable_multibyte_characters))
7199 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7200
7201 /* Raise the frame containing the echo area. */
7202 if (minibuffer_auto_raise)
7203 {
7204 struct frame *sf = SELECTED_FRAME ();
7205 Lisp_Object mini_window;
7206 mini_window = FRAME_MINIBUF_WINDOW (sf);
7207 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7208 }
7209
7210 message_log_maybe_newline ();
7211 message_buf_print = 1;
7212 }
7213 else
7214 {
7215 if (NILP (echo_area_buffer[0]))
7216 {
7217 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7218 echo_area_buffer[0] = echo_buffer[1];
7219 else
7220 echo_area_buffer[0] = echo_buffer[0];
7221 }
7222
7223 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7224 {
7225 /* Someone switched buffers between print requests. */
7226 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7227 current_buffer->truncate_lines = Qnil;
7228 }
7229 }
7230 }
7231
7232
7233 /* Display an echo area message in window W. Value is non-zero if W's
7234 height is changed. If display_last_displayed_message_p is
7235 non-zero, display the message that was last displayed, otherwise
7236 display the current message. */
7237
7238 static int
7239 display_echo_area (w)
7240 struct window *w;
7241 {
7242 int i, no_message_p, window_height_changed_p, count;
7243
7244 /* Temporarily disable garbage collections while displaying the echo
7245 area. This is done because a GC can print a message itself.
7246 That message would modify the echo area buffer's contents while a
7247 redisplay of the buffer is going on, and seriously confuse
7248 redisplay. */
7249 count = inhibit_garbage_collection ();
7250
7251 /* If there is no message, we must call display_echo_area_1
7252 nevertheless because it resizes the window. But we will have to
7253 reset the echo_area_buffer in question to nil at the end because
7254 with_echo_area_buffer will sets it to an empty buffer. */
7255 i = display_last_displayed_message_p ? 1 : 0;
7256 no_message_p = NILP (echo_area_buffer[i]);
7257
7258 window_height_changed_p
7259 = with_echo_area_buffer (w, display_last_displayed_message_p,
7260 display_echo_area_1,
7261 (EMACS_INT) w, Qnil, 0, 0);
7262
7263 if (no_message_p)
7264 echo_area_buffer[i] = Qnil;
7265
7266 unbind_to (count, Qnil);
7267 return window_height_changed_p;
7268 }
7269
7270
7271 /* Helper for display_echo_area. Display the current buffer which
7272 contains the current echo area message in window W, a mini-window,
7273 a pointer to which is passed in A1. A2..A4 are currently not used.
7274 Change the height of W so that all of the message is displayed.
7275 Value is non-zero if height of W was changed. */
7276
7277 static int
7278 display_echo_area_1 (a1, a2, a3, a4)
7279 EMACS_INT a1;
7280 Lisp_Object a2;
7281 EMACS_INT a3, a4;
7282 {
7283 struct window *w = (struct window *) a1;
7284 Lisp_Object window;
7285 struct text_pos start;
7286 int window_height_changed_p = 0;
7287
7288 /* Do this before displaying, so that we have a large enough glyph
7289 matrix for the display. */
7290 window_height_changed_p = resize_mini_window (w, 0);
7291
7292 /* Display. */
7293 clear_glyph_matrix (w->desired_matrix);
7294 XSETWINDOW (window, w);
7295 SET_TEXT_POS (start, BEG, BEG_BYTE);
7296 try_window (window, start);
7297
7298 return window_height_changed_p;
7299 }
7300
7301
7302 /* Resize the echo area window to exactly the size needed for the
7303 currently displayed message, if there is one. If a mini-buffer
7304 is active, don't shrink it. */
7305
7306 void
7307 resize_echo_area_exactly ()
7308 {
7309 if (BUFFERP (echo_area_buffer[0])
7310 && WINDOWP (echo_area_window))
7311 {
7312 struct window *w = XWINDOW (echo_area_window);
7313 int resized_p;
7314 Lisp_Object resize_exactly;
7315
7316 if (minibuf_level == 0)
7317 resize_exactly = Qt;
7318 else
7319 resize_exactly = Qnil;
7320
7321 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7322 (EMACS_INT) w, resize_exactly, 0, 0);
7323 if (resized_p)
7324 {
7325 ++windows_or_buffers_changed;
7326 ++update_mode_lines;
7327 redisplay_internal (0);
7328 }
7329 }
7330 }
7331
7332
7333 /* Callback function for with_echo_area_buffer, when used from
7334 resize_echo_area_exactly. A1 contains a pointer to the window to
7335 resize, EXACTLY non-nil means resize the mini-window exactly to the
7336 size of the text displayed. A3 and A4 are not used. Value is what
7337 resize_mini_window returns. */
7338
7339 static int
7340 resize_mini_window_1 (a1, exactly, a3, a4)
7341 EMACS_INT a1;
7342 Lisp_Object exactly;
7343 EMACS_INT a3, a4;
7344 {
7345 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7346 }
7347
7348
7349 /* Resize mini-window W to fit the size of its contents. EXACT:P
7350 means size the window exactly to the size needed. Otherwise, it's
7351 only enlarged until W's buffer is empty. Value is non-zero if
7352 the window height has been changed. */
7353
7354 int
7355 resize_mini_window (w, exact_p)
7356 struct window *w;
7357 int exact_p;
7358 {
7359 struct frame *f = XFRAME (w->frame);
7360 int window_height_changed_p = 0;
7361
7362 xassert (MINI_WINDOW_P (w));
7363
7364 /* Don't resize windows while redisplaying a window; it would
7365 confuse redisplay functions when the size of the window they are
7366 displaying changes from under them. Such a resizing can happen,
7367 for instance, when which-func prints a long message while
7368 we are running fontification-functions. We're running these
7369 functions with safe_call which binds inhibit-redisplay to t. */
7370 if (!NILP (Vinhibit_redisplay))
7371 return 0;
7372
7373 /* Nil means don't try to resize. */
7374 if (NILP (Vresize_mini_windows)
7375 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7376 return 0;
7377
7378 if (!FRAME_MINIBUF_ONLY_P (f))
7379 {
7380 struct it it;
7381 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7382 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7383 int height, max_height;
7384 int unit = FRAME_LINE_HEIGHT (f);
7385 struct text_pos start;
7386 struct buffer *old_current_buffer = NULL;
7387
7388 if (current_buffer != XBUFFER (w->buffer))
7389 {
7390 old_current_buffer = current_buffer;
7391 set_buffer_internal (XBUFFER (w->buffer));
7392 }
7393
7394 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7395
7396 /* Compute the max. number of lines specified by the user. */
7397 if (FLOATP (Vmax_mini_window_height))
7398 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7399 else if (INTEGERP (Vmax_mini_window_height))
7400 max_height = XINT (Vmax_mini_window_height);
7401 else
7402 max_height = total_height / 4;
7403
7404 /* Correct that max. height if it's bogus. */
7405 max_height = max (1, max_height);
7406 max_height = min (total_height, max_height);
7407
7408 /* Find out the height of the text in the window. */
7409 if (it.truncate_lines_p)
7410 height = 1;
7411 else
7412 {
7413 last_height = 0;
7414 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7415 if (it.max_ascent == 0 && it.max_descent == 0)
7416 height = it.current_y + last_height;
7417 else
7418 height = it.current_y + it.max_ascent + it.max_descent;
7419 height -= it.extra_line_spacing;
7420 height = (height + unit - 1) / unit;
7421 }
7422
7423 /* Compute a suitable window start. */
7424 if (height > max_height)
7425 {
7426 height = max_height;
7427 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7428 move_it_vertically_backward (&it, (height - 1) * unit);
7429 start = it.current.pos;
7430 }
7431 else
7432 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7433 SET_MARKER_FROM_TEXT_POS (w->start, start);
7434
7435 if (EQ (Vresize_mini_windows, Qgrow_only))
7436 {
7437 /* Let it grow only, until we display an empty message, in which
7438 case the window shrinks again. */
7439 if (height > WINDOW_TOTAL_LINES (w))
7440 {
7441 int old_height = WINDOW_TOTAL_LINES (w);
7442 freeze_window_starts (f, 1);
7443 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7444 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7445 }
7446 else if (height < WINDOW_TOTAL_LINES (w)
7447 && (exact_p || BEGV == ZV))
7448 {
7449 int old_height = WINDOW_TOTAL_LINES (w);
7450 freeze_window_starts (f, 0);
7451 shrink_mini_window (w);
7452 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7453 }
7454 }
7455 else
7456 {
7457 /* Always resize to exact size needed. */
7458 if (height > WINDOW_TOTAL_LINES (w))
7459 {
7460 int old_height = WINDOW_TOTAL_LINES (w);
7461 freeze_window_starts (f, 1);
7462 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7463 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7464 }
7465 else if (height < WINDOW_TOTAL_LINES (w))
7466 {
7467 int old_height = WINDOW_TOTAL_LINES (w);
7468 freeze_window_starts (f, 0);
7469 shrink_mini_window (w);
7470
7471 if (height)
7472 {
7473 freeze_window_starts (f, 1);
7474 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7475 }
7476
7477 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7478 }
7479 }
7480
7481 if (old_current_buffer)
7482 set_buffer_internal (old_current_buffer);
7483 }
7484
7485 return window_height_changed_p;
7486 }
7487
7488
7489 /* Value is the current message, a string, or nil if there is no
7490 current message. */
7491
7492 Lisp_Object
7493 current_message ()
7494 {
7495 Lisp_Object msg;
7496
7497 if (NILP (echo_area_buffer[0]))
7498 msg = Qnil;
7499 else
7500 {
7501 with_echo_area_buffer (0, 0, current_message_1,
7502 (EMACS_INT) &msg, Qnil, 0, 0);
7503 if (NILP (msg))
7504 echo_area_buffer[0] = Qnil;
7505 }
7506
7507 return msg;
7508 }
7509
7510
7511 static int
7512 current_message_1 (a1, a2, a3, a4)
7513 EMACS_INT a1;
7514 Lisp_Object a2;
7515 EMACS_INT a3, a4;
7516 {
7517 Lisp_Object *msg = (Lisp_Object *) a1;
7518
7519 if (Z > BEG)
7520 *msg = make_buffer_string (BEG, Z, 1);
7521 else
7522 *msg = Qnil;
7523 return 0;
7524 }
7525
7526
7527 /* Push the current message on Vmessage_stack for later restauration
7528 by restore_message. Value is non-zero if the current message isn't
7529 empty. This is a relatively infrequent operation, so it's not
7530 worth optimizing. */
7531
7532 int
7533 push_message ()
7534 {
7535 Lisp_Object msg;
7536 msg = current_message ();
7537 Vmessage_stack = Fcons (msg, Vmessage_stack);
7538 return STRINGP (msg);
7539 }
7540
7541
7542 /* Restore message display from the top of Vmessage_stack. */
7543
7544 void
7545 restore_message ()
7546 {
7547 Lisp_Object msg;
7548
7549 xassert (CONSP (Vmessage_stack));
7550 msg = XCAR (Vmessage_stack);
7551 if (STRINGP (msg))
7552 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7553 else
7554 message3_nolog (msg, 0, 0);
7555 }
7556
7557
7558 /* Handler for record_unwind_protect calling pop_message. */
7559
7560 Lisp_Object
7561 pop_message_unwind (dummy)
7562 Lisp_Object dummy;
7563 {
7564 pop_message ();
7565 return Qnil;
7566 }
7567
7568 /* Pop the top-most entry off Vmessage_stack. */
7569
7570 void
7571 pop_message ()
7572 {
7573 xassert (CONSP (Vmessage_stack));
7574 Vmessage_stack = XCDR (Vmessage_stack);
7575 }
7576
7577
7578 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7579 exits. If the stack is not empty, we have a missing pop_message
7580 somewhere. */
7581
7582 void
7583 check_message_stack ()
7584 {
7585 if (!NILP (Vmessage_stack))
7586 abort ();
7587 }
7588
7589
7590 /* Truncate to NCHARS what will be displayed in the echo area the next
7591 time we display it---but don't redisplay it now. */
7592
7593 void
7594 truncate_echo_area (nchars)
7595 int nchars;
7596 {
7597 if (nchars == 0)
7598 echo_area_buffer[0] = Qnil;
7599 /* A null message buffer means that the frame hasn't really been
7600 initialized yet. Error messages get reported properly by
7601 cmd_error, so this must be just an informative message; toss it. */
7602 else if (!noninteractive
7603 && INTERACTIVE
7604 && !NILP (echo_area_buffer[0]))
7605 {
7606 struct frame *sf = SELECTED_FRAME ();
7607 if (FRAME_MESSAGE_BUF (sf))
7608 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7609 }
7610 }
7611
7612
7613 /* Helper function for truncate_echo_area. Truncate the current
7614 message to at most NCHARS characters. */
7615
7616 static int
7617 truncate_message_1 (nchars, a2, a3, a4)
7618 EMACS_INT nchars;
7619 Lisp_Object a2;
7620 EMACS_INT a3, a4;
7621 {
7622 if (BEG + nchars < Z)
7623 del_range (BEG + nchars, Z);
7624 if (Z == BEG)
7625 echo_area_buffer[0] = Qnil;
7626 return 0;
7627 }
7628
7629
7630 /* Set the current message to a substring of S or STRING.
7631
7632 If STRING is a Lisp string, set the message to the first NBYTES
7633 bytes from STRING. NBYTES zero means use the whole string. If
7634 STRING is multibyte, the message will be displayed multibyte.
7635
7636 If S is not null, set the message to the first LEN bytes of S. LEN
7637 zero means use the whole string. MULTIBYTE_P non-zero means S is
7638 multibyte. Display the message multibyte in that case. */
7639
7640 void
7641 set_message (s, string, nbytes, multibyte_p)
7642 const char *s;
7643 Lisp_Object string;
7644 int nbytes, multibyte_p;
7645 {
7646 message_enable_multibyte
7647 = ((s && multibyte_p)
7648 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7649
7650 with_echo_area_buffer (0, -1, set_message_1,
7651 (EMACS_INT) s, string, nbytes, multibyte_p);
7652 message_buf_print = 0;
7653 help_echo_showing_p = 0;
7654 }
7655
7656
7657 /* Helper function for set_message. Arguments have the same meaning
7658 as there, with A1 corresponding to S and A2 corresponding to STRING
7659 This function is called with the echo area buffer being
7660 current. */
7661
7662 static int
7663 set_message_1 (a1, a2, nbytes, multibyte_p)
7664 EMACS_INT a1;
7665 Lisp_Object a2;
7666 EMACS_INT nbytes, multibyte_p;
7667 {
7668 const char *s = (const char *) a1;
7669 Lisp_Object string = a2;
7670
7671 xassert (BEG == Z);
7672
7673 /* Change multibyteness of the echo buffer appropriately. */
7674 if (message_enable_multibyte
7675 != !NILP (current_buffer->enable_multibyte_characters))
7676 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7677
7678 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7679
7680 /* Insert new message at BEG. */
7681 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7682
7683 if (STRINGP (string))
7684 {
7685 int nchars;
7686
7687 if (nbytes == 0)
7688 nbytes = SBYTES (string);
7689 nchars = string_byte_to_char (string, nbytes);
7690
7691 /* This function takes care of single/multibyte conversion. We
7692 just have to ensure that the echo area buffer has the right
7693 setting of enable_multibyte_characters. */
7694 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7695 }
7696 else if (s)
7697 {
7698 if (nbytes == 0)
7699 nbytes = strlen (s);
7700
7701 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7702 {
7703 /* Convert from multi-byte to single-byte. */
7704 int i, c, n;
7705 unsigned char work[1];
7706
7707 /* Convert a multibyte string to single-byte. */
7708 for (i = 0; i < nbytes; i += n)
7709 {
7710 c = string_char_and_length (s + i, nbytes - i, &n);
7711 work[0] = (SINGLE_BYTE_CHAR_P (c)
7712 ? c
7713 : multibyte_char_to_unibyte (c, Qnil));
7714 insert_1_both (work, 1, 1, 1, 0, 0);
7715 }
7716 }
7717 else if (!multibyte_p
7718 && !NILP (current_buffer->enable_multibyte_characters))
7719 {
7720 /* Convert from single-byte to multi-byte. */
7721 int i, c, n;
7722 const unsigned char *msg = (const unsigned char *) s;
7723 unsigned char str[MAX_MULTIBYTE_LENGTH];
7724
7725 /* Convert a single-byte string to multibyte. */
7726 for (i = 0; i < nbytes; i++)
7727 {
7728 c = unibyte_char_to_multibyte (msg[i]);
7729 n = CHAR_STRING (c, str);
7730 insert_1_both (str, 1, n, 1, 0, 0);
7731 }
7732 }
7733 else
7734 insert_1 (s, nbytes, 1, 0, 0);
7735 }
7736
7737 return 0;
7738 }
7739
7740
7741 /* Clear messages. CURRENT_P non-zero means clear the current
7742 message. LAST_DISPLAYED_P non-zero means clear the message
7743 last displayed. */
7744
7745 void
7746 clear_message (current_p, last_displayed_p)
7747 int current_p, last_displayed_p;
7748 {
7749 if (current_p)
7750 {
7751 echo_area_buffer[0] = Qnil;
7752 message_cleared_p = 1;
7753 }
7754
7755 if (last_displayed_p)
7756 echo_area_buffer[1] = Qnil;
7757
7758 message_buf_print = 0;
7759 }
7760
7761 /* Clear garbaged frames.
7762
7763 This function is used where the old redisplay called
7764 redraw_garbaged_frames which in turn called redraw_frame which in
7765 turn called clear_frame. The call to clear_frame was a source of
7766 flickering. I believe a clear_frame is not necessary. It should
7767 suffice in the new redisplay to invalidate all current matrices,
7768 and ensure a complete redisplay of all windows. */
7769
7770 static void
7771 clear_garbaged_frames ()
7772 {
7773 if (frame_garbaged)
7774 {
7775 Lisp_Object tail, frame;
7776 int changed_count = 0;
7777
7778 FOR_EACH_FRAME (tail, frame)
7779 {
7780 struct frame *f = XFRAME (frame);
7781
7782 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7783 {
7784 if (f->resized_p)
7785 {
7786 Fredraw_frame (frame);
7787 f->force_flush_display_p = 1;
7788 }
7789 clear_current_matrices (f);
7790 changed_count++;
7791 f->garbaged = 0;
7792 f->resized_p = 0;
7793 }
7794 }
7795
7796 frame_garbaged = 0;
7797 if (changed_count)
7798 ++windows_or_buffers_changed;
7799 }
7800 }
7801
7802
7803 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7804 is non-zero update selected_frame. Value is non-zero if the
7805 mini-windows height has been changed. */
7806
7807 static int
7808 echo_area_display (update_frame_p)
7809 int update_frame_p;
7810 {
7811 Lisp_Object mini_window;
7812 struct window *w;
7813 struct frame *f;
7814 int window_height_changed_p = 0;
7815 struct frame *sf = SELECTED_FRAME ();
7816
7817 mini_window = FRAME_MINIBUF_WINDOW (sf);
7818 w = XWINDOW (mini_window);
7819 f = XFRAME (WINDOW_FRAME (w));
7820
7821 /* Don't display if frame is invisible or not yet initialized. */
7822 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7823 return 0;
7824
7825 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7826 #ifndef MAC_OS8
7827 #ifdef HAVE_WINDOW_SYSTEM
7828 /* When Emacs starts, selected_frame may be a visible terminal
7829 frame, even if we run under a window system. If we let this
7830 through, a message would be displayed on the terminal. */
7831 if (EQ (selected_frame, Vterminal_frame)
7832 && !NILP (Vwindow_system))
7833 return 0;
7834 #endif /* HAVE_WINDOW_SYSTEM */
7835 #endif
7836
7837 /* Redraw garbaged frames. */
7838 if (frame_garbaged)
7839 clear_garbaged_frames ();
7840
7841 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7842 {
7843 echo_area_window = mini_window;
7844 window_height_changed_p = display_echo_area (w);
7845 w->must_be_updated_p = 1;
7846
7847 /* Update the display, unless called from redisplay_internal.
7848 Also don't update the screen during redisplay itself. The
7849 update will happen at the end of redisplay, and an update
7850 here could cause confusion. */
7851 if (update_frame_p && !redisplaying_p)
7852 {
7853 int n = 0;
7854
7855 /* If the display update has been interrupted by pending
7856 input, update mode lines in the frame. Due to the
7857 pending input, it might have been that redisplay hasn't
7858 been called, so that mode lines above the echo area are
7859 garbaged. This looks odd, so we prevent it here. */
7860 if (!display_completed)
7861 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7862
7863 if (window_height_changed_p
7864 /* Don't do this if Emacs is shutting down. Redisplay
7865 needs to run hooks. */
7866 && !NILP (Vrun_hooks))
7867 {
7868 /* Must update other windows. Likewise as in other
7869 cases, don't let this update be interrupted by
7870 pending input. */
7871 int count = SPECPDL_INDEX ();
7872 specbind (Qredisplay_dont_pause, Qt);
7873 windows_or_buffers_changed = 1;
7874 redisplay_internal (0);
7875 unbind_to (count, Qnil);
7876 }
7877 else if (FRAME_WINDOW_P (f) && n == 0)
7878 {
7879 /* Window configuration is the same as before.
7880 Can do with a display update of the echo area,
7881 unless we displayed some mode lines. */
7882 update_single_window (w, 1);
7883 rif->flush_display (f);
7884 }
7885 else
7886 update_frame (f, 1, 1);
7887
7888 /* If cursor is in the echo area, make sure that the next
7889 redisplay displays the minibuffer, so that the cursor will
7890 be replaced with what the minibuffer wants. */
7891 if (cursor_in_echo_area)
7892 ++windows_or_buffers_changed;
7893 }
7894 }
7895 else if (!EQ (mini_window, selected_window))
7896 windows_or_buffers_changed++;
7897
7898 /* Last displayed message is now the current message. */
7899 echo_area_buffer[1] = echo_area_buffer[0];
7900
7901 /* Prevent redisplay optimization in redisplay_internal by resetting
7902 this_line_start_pos. This is done because the mini-buffer now
7903 displays the message instead of its buffer text. */
7904 if (EQ (mini_window, selected_window))
7905 CHARPOS (this_line_start_pos) = 0;
7906
7907 return window_height_changed_p;
7908 }
7909
7910
7911 \f
7912 /***********************************************************************
7913 Frame Titles
7914 ***********************************************************************/
7915
7916
7917 /* The frame title buffering code is also used by Fformat_mode_line.
7918 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7919
7920 /* A buffer for constructing frame titles in it; allocated from the
7921 heap in init_xdisp and resized as needed in store_frame_title_char. */
7922
7923 static char *frame_title_buf;
7924
7925 /* The buffer's end, and a current output position in it. */
7926
7927 static char *frame_title_buf_end;
7928 static char *frame_title_ptr;
7929
7930
7931 /* Store a single character C for the frame title in frame_title_buf.
7932 Re-allocate frame_title_buf if necessary. */
7933
7934 static void
7935 #ifdef PROTOTYPES
7936 store_frame_title_char (char c)
7937 #else
7938 store_frame_title_char (c)
7939 char c;
7940 #endif
7941 {
7942 /* If output position has reached the end of the allocated buffer,
7943 double the buffer's size. */
7944 if (frame_title_ptr == frame_title_buf_end)
7945 {
7946 int len = frame_title_ptr - frame_title_buf;
7947 int new_size = 2 * len * sizeof *frame_title_buf;
7948 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7949 frame_title_buf_end = frame_title_buf + new_size;
7950 frame_title_ptr = frame_title_buf + len;
7951 }
7952
7953 *frame_title_ptr++ = c;
7954 }
7955
7956
7957 /* Store part of a frame title in frame_title_buf, beginning at
7958 frame_title_ptr. STR is the string to store. Do not copy
7959 characters that yield more columns than PRECISION; PRECISION <= 0
7960 means copy the whole string. Pad with spaces until FIELD_WIDTH
7961 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7962 pad. Called from display_mode_element when it is used to build a
7963 frame title. */
7964
7965 static int
7966 store_frame_title (str, field_width, precision)
7967 const unsigned char *str;
7968 int field_width, precision;
7969 {
7970 int n = 0;
7971 int dummy, nbytes;
7972
7973 /* Copy at most PRECISION chars from STR. */
7974 nbytes = strlen (str);
7975 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7976 while (nbytes--)
7977 store_frame_title_char (*str++);
7978
7979 /* Fill up with spaces until FIELD_WIDTH reached. */
7980 while (field_width > 0
7981 && n < field_width)
7982 {
7983 store_frame_title_char (' ');
7984 ++n;
7985 }
7986
7987 return n;
7988 }
7989
7990 #ifdef HAVE_WINDOW_SYSTEM
7991
7992 /* Set the title of FRAME, if it has changed. The title format is
7993 Vicon_title_format if FRAME is iconified, otherwise it is
7994 frame_title_format. */
7995
7996 static void
7997 x_consider_frame_title (frame)
7998 Lisp_Object frame;
7999 {
8000 struct frame *f = XFRAME (frame);
8001
8002 if (FRAME_WINDOW_P (f)
8003 || FRAME_MINIBUF_ONLY_P (f)
8004 || f->explicit_name)
8005 {
8006 /* Do we have more than one visible frame on this X display? */
8007 Lisp_Object tail;
8008 Lisp_Object fmt;
8009 struct buffer *obuf;
8010 int len;
8011 struct it it;
8012
8013 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8014 {
8015 Lisp_Object other_frame = XCAR (tail);
8016 struct frame *tf = XFRAME (other_frame);
8017
8018 if (tf != f
8019 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8020 && !FRAME_MINIBUF_ONLY_P (tf)
8021 && !EQ (other_frame, tip_frame)
8022 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8023 break;
8024 }
8025
8026 /* Set global variable indicating that multiple frames exist. */
8027 multiple_frames = CONSP (tail);
8028
8029 /* Switch to the buffer of selected window of the frame. Set up
8030 frame_title_ptr so that display_mode_element will output into it;
8031 then display the title. */
8032 obuf = current_buffer;
8033 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8034 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8035 frame_title_ptr = frame_title_buf;
8036 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8037 NULL, DEFAULT_FACE_ID);
8038 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8039 len = frame_title_ptr - frame_title_buf;
8040 frame_title_ptr = NULL;
8041 set_buffer_internal_1 (obuf);
8042
8043 /* Set the title only if it's changed. This avoids consing in
8044 the common case where it hasn't. (If it turns out that we've
8045 already wasted too much time by walking through the list with
8046 display_mode_element, then we might need to optimize at a
8047 higher level than this.) */
8048 if (! STRINGP (f->name)
8049 || SBYTES (f->name) != len
8050 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8051 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8052 }
8053 }
8054
8055 #endif /* not HAVE_WINDOW_SYSTEM */
8056
8057
8058
8059 \f
8060 /***********************************************************************
8061 Menu Bars
8062 ***********************************************************************/
8063
8064
8065 /* Prepare for redisplay by updating menu-bar item lists when
8066 appropriate. This can call eval. */
8067
8068 void
8069 prepare_menu_bars ()
8070 {
8071 int all_windows;
8072 struct gcpro gcpro1, gcpro2;
8073 struct frame *f;
8074 Lisp_Object tooltip_frame;
8075
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 tooltip_frame = tip_frame;
8078 #else
8079 tooltip_frame = Qnil;
8080 #endif
8081
8082 /* Update all frame titles based on their buffer names, etc. We do
8083 this before the menu bars so that the buffer-menu will show the
8084 up-to-date frame titles. */
8085 #ifdef HAVE_WINDOW_SYSTEM
8086 if (windows_or_buffers_changed || update_mode_lines)
8087 {
8088 Lisp_Object tail, frame;
8089
8090 FOR_EACH_FRAME (tail, frame)
8091 {
8092 f = XFRAME (frame);
8093 if (!EQ (frame, tooltip_frame)
8094 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8095 x_consider_frame_title (frame);
8096 }
8097 }
8098 #endif /* HAVE_WINDOW_SYSTEM */
8099
8100 /* Update the menu bar item lists, if appropriate. This has to be
8101 done before any actual redisplay or generation of display lines. */
8102 all_windows = (update_mode_lines
8103 || buffer_shared > 1
8104 || windows_or_buffers_changed);
8105 if (all_windows)
8106 {
8107 Lisp_Object tail, frame;
8108 int count = SPECPDL_INDEX ();
8109
8110 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8111
8112 FOR_EACH_FRAME (tail, frame)
8113 {
8114 f = XFRAME (frame);
8115
8116 /* Ignore tooltip frame. */
8117 if (EQ (frame, tooltip_frame))
8118 continue;
8119
8120 /* If a window on this frame changed size, report that to
8121 the user and clear the size-change flag. */
8122 if (FRAME_WINDOW_SIZES_CHANGED (f))
8123 {
8124 Lisp_Object functions;
8125
8126 /* Clear flag first in case we get an error below. */
8127 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8128 functions = Vwindow_size_change_functions;
8129 GCPRO2 (tail, functions);
8130
8131 while (CONSP (functions))
8132 {
8133 call1 (XCAR (functions), frame);
8134 functions = XCDR (functions);
8135 }
8136 UNGCPRO;
8137 }
8138
8139 GCPRO1 (tail);
8140 update_menu_bar (f, 0);
8141 #ifdef HAVE_WINDOW_SYSTEM
8142 update_tool_bar (f, 0);
8143 #endif
8144 UNGCPRO;
8145 }
8146
8147 unbind_to (count, Qnil);
8148 }
8149 else
8150 {
8151 struct frame *sf = SELECTED_FRAME ();
8152 update_menu_bar (sf, 1);
8153 #ifdef HAVE_WINDOW_SYSTEM
8154 update_tool_bar (sf, 1);
8155 #endif
8156 }
8157
8158 /* Motif needs this. See comment in xmenu.c. Turn it off when
8159 pending_menu_activation is not defined. */
8160 #ifdef USE_X_TOOLKIT
8161 pending_menu_activation = 0;
8162 #endif
8163 }
8164
8165
8166 /* Update the menu bar item list for frame F. This has to be done
8167 before we start to fill in any display lines, because it can call
8168 eval.
8169
8170 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8171
8172 static void
8173 update_menu_bar (f, save_match_data)
8174 struct frame *f;
8175 int save_match_data;
8176 {
8177 Lisp_Object window;
8178 register struct window *w;
8179
8180 /* If called recursively during a menu update, do nothing. This can
8181 happen when, for instance, an activate-menubar-hook causes a
8182 redisplay. */
8183 if (inhibit_menubar_update)
8184 return;
8185
8186 window = FRAME_SELECTED_WINDOW (f);
8187 w = XWINDOW (window);
8188
8189 #if 0 /* The if statement below this if statement used to include the
8190 condition !NILP (w->update_mode_line), rather than using
8191 update_mode_lines directly, and this if statement may have
8192 been added to make that condition work. Now the if
8193 statement below matches its comment, this isn't needed. */
8194 if (update_mode_lines)
8195 w->update_mode_line = Qt;
8196 #endif
8197
8198 if (FRAME_WINDOW_P (f)
8199 ?
8200 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8201 || defined (USE_GTK)
8202 FRAME_EXTERNAL_MENU_BAR (f)
8203 #else
8204 FRAME_MENU_BAR_LINES (f) > 0
8205 #endif
8206 : FRAME_MENU_BAR_LINES (f) > 0)
8207 {
8208 /* If the user has switched buffers or windows, we need to
8209 recompute to reflect the new bindings. But we'll
8210 recompute when update_mode_lines is set too; that means
8211 that people can use force-mode-line-update to request
8212 that the menu bar be recomputed. The adverse effect on
8213 the rest of the redisplay algorithm is about the same as
8214 windows_or_buffers_changed anyway. */
8215 if (windows_or_buffers_changed
8216 /* This used to test w->update_mode_line, but we believe
8217 there is no need to recompute the menu in that case. */
8218 || update_mode_lines
8219 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8220 < BUF_MODIFF (XBUFFER (w->buffer)))
8221 != !NILP (w->last_had_star))
8222 || ((!NILP (Vtransient_mark_mode)
8223 && !NILP (XBUFFER (w->buffer)->mark_active))
8224 != !NILP (w->region_showing)))
8225 {
8226 struct buffer *prev = current_buffer;
8227 int count = SPECPDL_INDEX ();
8228
8229 specbind (Qinhibit_menubar_update, Qt);
8230
8231 set_buffer_internal_1 (XBUFFER (w->buffer));
8232 if (save_match_data)
8233 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8234 if (NILP (Voverriding_local_map_menu_flag))
8235 {
8236 specbind (Qoverriding_terminal_local_map, Qnil);
8237 specbind (Qoverriding_local_map, Qnil);
8238 }
8239
8240 /* Run the Lucid hook. */
8241 safe_run_hooks (Qactivate_menubar_hook);
8242
8243 /* If it has changed current-menubar from previous value,
8244 really recompute the menu-bar from the value. */
8245 if (! NILP (Vlucid_menu_bar_dirty_flag))
8246 call0 (Qrecompute_lucid_menubar);
8247
8248 safe_run_hooks (Qmenu_bar_update_hook);
8249 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8250
8251 /* Redisplay the menu bar in case we changed it. */
8252 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8253 || defined (USE_GTK)
8254 if (FRAME_WINDOW_P (f)
8255 #if defined (MAC_OS)
8256 /* All frames on Mac OS share the same menubar. So only the
8257 selected frame should be allowed to set it. */
8258 && f == SELECTED_FRAME ()
8259 #endif
8260 )
8261 set_frame_menubar (f, 0, 0);
8262 else
8263 /* On a terminal screen, the menu bar is an ordinary screen
8264 line, and this makes it get updated. */
8265 w->update_mode_line = Qt;
8266 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8267 /* In the non-toolkit version, the menu bar is an ordinary screen
8268 line, and this makes it get updated. */
8269 w->update_mode_line = Qt;
8270 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8271
8272 unbind_to (count, Qnil);
8273 set_buffer_internal_1 (prev);
8274 }
8275 }
8276 }
8277
8278
8279 \f
8280 /***********************************************************************
8281 Output Cursor
8282 ***********************************************************************/
8283
8284 #ifdef HAVE_WINDOW_SYSTEM
8285
8286 /* EXPORT:
8287 Nominal cursor position -- where to draw output.
8288 HPOS and VPOS are window relative glyph matrix coordinates.
8289 X and Y are window relative pixel coordinates. */
8290
8291 struct cursor_pos output_cursor;
8292
8293
8294 /* EXPORT:
8295 Set the global variable output_cursor to CURSOR. All cursor
8296 positions are relative to updated_window. */
8297
8298 void
8299 set_output_cursor (cursor)
8300 struct cursor_pos *cursor;
8301 {
8302 output_cursor.hpos = cursor->hpos;
8303 output_cursor.vpos = cursor->vpos;
8304 output_cursor.x = cursor->x;
8305 output_cursor.y = cursor->y;
8306 }
8307
8308
8309 /* EXPORT for RIF:
8310 Set a nominal cursor position.
8311
8312 HPOS and VPOS are column/row positions in a window glyph matrix. X
8313 and Y are window text area relative pixel positions.
8314
8315 If this is done during an update, updated_window will contain the
8316 window that is being updated and the position is the future output
8317 cursor position for that window. If updated_window is null, use
8318 selected_window and display the cursor at the given position. */
8319
8320 void
8321 x_cursor_to (vpos, hpos, y, x)
8322 int vpos, hpos, y, x;
8323 {
8324 struct window *w;
8325
8326 /* If updated_window is not set, work on selected_window. */
8327 if (updated_window)
8328 w = updated_window;
8329 else
8330 w = XWINDOW (selected_window);
8331
8332 /* Set the output cursor. */
8333 output_cursor.hpos = hpos;
8334 output_cursor.vpos = vpos;
8335 output_cursor.x = x;
8336 output_cursor.y = y;
8337
8338 /* If not called as part of an update, really display the cursor.
8339 This will also set the cursor position of W. */
8340 if (updated_window == NULL)
8341 {
8342 BLOCK_INPUT;
8343 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8344 if (rif->flush_display_optional)
8345 rif->flush_display_optional (SELECTED_FRAME ());
8346 UNBLOCK_INPUT;
8347 }
8348 }
8349
8350 #endif /* HAVE_WINDOW_SYSTEM */
8351
8352 \f
8353 /***********************************************************************
8354 Tool-bars
8355 ***********************************************************************/
8356
8357 #ifdef HAVE_WINDOW_SYSTEM
8358
8359 /* Where the mouse was last time we reported a mouse event. */
8360
8361 FRAME_PTR last_mouse_frame;
8362
8363 /* Tool-bar item index of the item on which a mouse button was pressed
8364 or -1. */
8365
8366 int last_tool_bar_item;
8367
8368
8369 /* Update the tool-bar item list for frame F. This has to be done
8370 before we start to fill in any display lines. Called from
8371 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8372 and restore it here. */
8373
8374 static void
8375 update_tool_bar (f, save_match_data)
8376 struct frame *f;
8377 int save_match_data;
8378 {
8379 #ifdef USE_GTK
8380 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8381 #else
8382 int do_update = WINDOWP (f->tool_bar_window)
8383 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8384 #endif
8385
8386 if (do_update)
8387 {
8388 Lisp_Object window;
8389 struct window *w;
8390
8391 window = FRAME_SELECTED_WINDOW (f);
8392 w = XWINDOW (window);
8393
8394 /* If the user has switched buffers or windows, we need to
8395 recompute to reflect the new bindings. But we'll
8396 recompute when update_mode_lines is set too; that means
8397 that people can use force-mode-line-update to request
8398 that the menu bar be recomputed. The adverse effect on
8399 the rest of the redisplay algorithm is about the same as
8400 windows_or_buffers_changed anyway. */
8401 if (windows_or_buffers_changed
8402 || !NILP (w->update_mode_line)
8403 || update_mode_lines
8404 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8405 < BUF_MODIFF (XBUFFER (w->buffer)))
8406 != !NILP (w->last_had_star))
8407 || ((!NILP (Vtransient_mark_mode)
8408 && !NILP (XBUFFER (w->buffer)->mark_active))
8409 != !NILP (w->region_showing)))
8410 {
8411 struct buffer *prev = current_buffer;
8412 int count = SPECPDL_INDEX ();
8413 Lisp_Object old_tool_bar;
8414 struct gcpro gcpro1;
8415
8416 /* Set current_buffer to the buffer of the selected
8417 window of the frame, so that we get the right local
8418 keymaps. */
8419 set_buffer_internal_1 (XBUFFER (w->buffer));
8420
8421 /* Save match data, if we must. */
8422 if (save_match_data)
8423 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8424
8425 /* Make sure that we don't accidentally use bogus keymaps. */
8426 if (NILP (Voverriding_local_map_menu_flag))
8427 {
8428 specbind (Qoverriding_terminal_local_map, Qnil);
8429 specbind (Qoverriding_local_map, Qnil);
8430 }
8431
8432 old_tool_bar = f->tool_bar_items;
8433 GCPRO1 (old_tool_bar);
8434
8435 /* Build desired tool-bar items from keymaps. */
8436 BLOCK_INPUT;
8437 f->tool_bar_items
8438 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8439 UNBLOCK_INPUT;
8440
8441 /* Redisplay the tool-bar if we changed it. */
8442 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8443 w->update_mode_line = Qt;
8444
8445 UNGCPRO;
8446
8447 unbind_to (count, Qnil);
8448 set_buffer_internal_1 (prev);
8449 }
8450 }
8451 }
8452
8453
8454 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8455 F's desired tool-bar contents. F->tool_bar_items must have
8456 been set up previously by calling prepare_menu_bars. */
8457
8458 static void
8459 build_desired_tool_bar_string (f)
8460 struct frame *f;
8461 {
8462 int i, size, size_needed;
8463 struct gcpro gcpro1, gcpro2, gcpro3;
8464 Lisp_Object image, plist, props;
8465
8466 image = plist = props = Qnil;
8467 GCPRO3 (image, plist, props);
8468
8469 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8470 Otherwise, make a new string. */
8471
8472 /* The size of the string we might be able to reuse. */
8473 size = (STRINGP (f->desired_tool_bar_string)
8474 ? SCHARS (f->desired_tool_bar_string)
8475 : 0);
8476
8477 /* We need one space in the string for each image. */
8478 size_needed = f->n_tool_bar_items;
8479
8480 /* Reuse f->desired_tool_bar_string, if possible. */
8481 if (size < size_needed || NILP (f->desired_tool_bar_string))
8482 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8483 make_number (' '));
8484 else
8485 {
8486 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8487 Fremove_text_properties (make_number (0), make_number (size),
8488 props, f->desired_tool_bar_string);
8489 }
8490
8491 /* Put a `display' property on the string for the images to display,
8492 put a `menu_item' property on tool-bar items with a value that
8493 is the index of the item in F's tool-bar item vector. */
8494 for (i = 0; i < f->n_tool_bar_items; ++i)
8495 {
8496 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8497
8498 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8499 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8500 int hmargin, vmargin, relief, idx, end;
8501 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8502
8503 /* If image is a vector, choose the image according to the
8504 button state. */
8505 image = PROP (TOOL_BAR_ITEM_IMAGES);
8506 if (VECTORP (image))
8507 {
8508 if (enabled_p)
8509 idx = (selected_p
8510 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8511 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8512 else
8513 idx = (selected_p
8514 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8515 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8516
8517 xassert (ASIZE (image) >= idx);
8518 image = AREF (image, idx);
8519 }
8520 else
8521 idx = -1;
8522
8523 /* Ignore invalid image specifications. */
8524 if (!valid_image_p (image))
8525 continue;
8526
8527 /* Display the tool-bar button pressed, or depressed. */
8528 plist = Fcopy_sequence (XCDR (image));
8529
8530 /* Compute margin and relief to draw. */
8531 relief = (tool_bar_button_relief >= 0
8532 ? tool_bar_button_relief
8533 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8534 hmargin = vmargin = relief;
8535
8536 if (INTEGERP (Vtool_bar_button_margin)
8537 && XINT (Vtool_bar_button_margin) > 0)
8538 {
8539 hmargin += XFASTINT (Vtool_bar_button_margin);
8540 vmargin += XFASTINT (Vtool_bar_button_margin);
8541 }
8542 else if (CONSP (Vtool_bar_button_margin))
8543 {
8544 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8545 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8546 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8547
8548 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8549 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8550 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8551 }
8552
8553 if (auto_raise_tool_bar_buttons_p)
8554 {
8555 /* Add a `:relief' property to the image spec if the item is
8556 selected. */
8557 if (selected_p)
8558 {
8559 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8560 hmargin -= relief;
8561 vmargin -= relief;
8562 }
8563 }
8564 else
8565 {
8566 /* If image is selected, display it pressed, i.e. with a
8567 negative relief. If it's not selected, display it with a
8568 raised relief. */
8569 plist = Fplist_put (plist, QCrelief,
8570 (selected_p
8571 ? make_number (-relief)
8572 : make_number (relief)));
8573 hmargin -= relief;
8574 vmargin -= relief;
8575 }
8576
8577 /* Put a margin around the image. */
8578 if (hmargin || vmargin)
8579 {
8580 if (hmargin == vmargin)
8581 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8582 else
8583 plist = Fplist_put (plist, QCmargin,
8584 Fcons (make_number (hmargin),
8585 make_number (vmargin)));
8586 }
8587
8588 /* If button is not enabled, and we don't have special images
8589 for the disabled state, make the image appear disabled by
8590 applying an appropriate algorithm to it. */
8591 if (!enabled_p && idx < 0)
8592 plist = Fplist_put (plist, QCconversion, Qdisabled);
8593
8594 /* Put a `display' text property on the string for the image to
8595 display. Put a `menu-item' property on the string that gives
8596 the start of this item's properties in the tool-bar items
8597 vector. */
8598 image = Fcons (Qimage, plist);
8599 props = list4 (Qdisplay, image,
8600 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8601
8602 /* Let the last image hide all remaining spaces in the tool bar
8603 string. The string can be longer than needed when we reuse a
8604 previous string. */
8605 if (i + 1 == f->n_tool_bar_items)
8606 end = SCHARS (f->desired_tool_bar_string);
8607 else
8608 end = i + 1;
8609 Fadd_text_properties (make_number (i), make_number (end),
8610 props, f->desired_tool_bar_string);
8611 #undef PROP
8612 }
8613
8614 UNGCPRO;
8615 }
8616
8617
8618 /* Display one line of the tool-bar of frame IT->f. */
8619
8620 static void
8621 display_tool_bar_line (it)
8622 struct it *it;
8623 {
8624 struct glyph_row *row = it->glyph_row;
8625 int max_x = it->last_visible_x;
8626 struct glyph *last;
8627
8628 prepare_desired_row (row);
8629 row->y = it->current_y;
8630
8631 /* Note that this isn't made use of if the face hasn't a box,
8632 so there's no need to check the face here. */
8633 it->start_of_box_run_p = 1;
8634
8635 while (it->current_x < max_x)
8636 {
8637 int x_before, x, n_glyphs_before, i, nglyphs;
8638
8639 /* Get the next display element. */
8640 if (!get_next_display_element (it))
8641 break;
8642
8643 /* Produce glyphs. */
8644 x_before = it->current_x;
8645 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8646 PRODUCE_GLYPHS (it);
8647
8648 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8649 i = 0;
8650 x = x_before;
8651 while (i < nglyphs)
8652 {
8653 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8654
8655 if (x + glyph->pixel_width > max_x)
8656 {
8657 /* Glyph doesn't fit on line. */
8658 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8659 it->current_x = x;
8660 goto out;
8661 }
8662
8663 ++it->hpos;
8664 x += glyph->pixel_width;
8665 ++i;
8666 }
8667
8668 /* Stop at line ends. */
8669 if (ITERATOR_AT_END_OF_LINE_P (it))
8670 break;
8671
8672 set_iterator_to_next (it, 1);
8673 }
8674
8675 out:;
8676
8677 row->displays_text_p = row->used[TEXT_AREA] != 0;
8678 extend_face_to_end_of_line (it);
8679 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8680 last->right_box_line_p = 1;
8681 if (last == row->glyphs[TEXT_AREA])
8682 last->left_box_line_p = 1;
8683 compute_line_metrics (it);
8684
8685 /* If line is empty, make it occupy the rest of the tool-bar. */
8686 if (!row->displays_text_p)
8687 {
8688 row->height = row->phys_height = it->last_visible_y - row->y;
8689 row->ascent = row->phys_ascent = 0;
8690 }
8691
8692 row->full_width_p = 1;
8693 row->continued_p = 0;
8694 row->truncated_on_left_p = 0;
8695 row->truncated_on_right_p = 0;
8696
8697 it->current_x = it->hpos = 0;
8698 it->current_y += row->height;
8699 ++it->vpos;
8700 ++it->glyph_row;
8701 }
8702
8703
8704 /* Value is the number of screen lines needed to make all tool-bar
8705 items of frame F visible. */
8706
8707 static int
8708 tool_bar_lines_needed (f)
8709 struct frame *f;
8710 {
8711 struct window *w = XWINDOW (f->tool_bar_window);
8712 struct it it;
8713
8714 /* Initialize an iterator for iteration over
8715 F->desired_tool_bar_string in the tool-bar window of frame F. */
8716 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8717 it.first_visible_x = 0;
8718 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8719 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8720
8721 while (!ITERATOR_AT_END_P (&it))
8722 {
8723 it.glyph_row = w->desired_matrix->rows;
8724 clear_glyph_row (it.glyph_row);
8725 display_tool_bar_line (&it);
8726 }
8727
8728 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8729 }
8730
8731
8732 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8733 0, 1, 0,
8734 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8735 (frame)
8736 Lisp_Object frame;
8737 {
8738 struct frame *f;
8739 struct window *w;
8740 int nlines = 0;
8741
8742 if (NILP (frame))
8743 frame = selected_frame;
8744 else
8745 CHECK_FRAME (frame);
8746 f = XFRAME (frame);
8747
8748 if (WINDOWP (f->tool_bar_window)
8749 || (w = XWINDOW (f->tool_bar_window),
8750 WINDOW_TOTAL_LINES (w) > 0))
8751 {
8752 update_tool_bar (f, 1);
8753 if (f->n_tool_bar_items)
8754 {
8755 build_desired_tool_bar_string (f);
8756 nlines = tool_bar_lines_needed (f);
8757 }
8758 }
8759
8760 return make_number (nlines);
8761 }
8762
8763
8764 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8765 height should be changed. */
8766
8767 static int
8768 redisplay_tool_bar (f)
8769 struct frame *f;
8770 {
8771 struct window *w;
8772 struct it it;
8773 struct glyph_row *row;
8774 int change_height_p = 0;
8775
8776 #ifdef USE_GTK
8777 if (FRAME_EXTERNAL_TOOL_BAR (f))
8778 update_frame_tool_bar (f);
8779 return 0;
8780 #endif
8781
8782 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8783 do anything. This means you must start with tool-bar-lines
8784 non-zero to get the auto-sizing effect. Or in other words, you
8785 can turn off tool-bars by specifying tool-bar-lines zero. */
8786 if (!WINDOWP (f->tool_bar_window)
8787 || (w = XWINDOW (f->tool_bar_window),
8788 WINDOW_TOTAL_LINES (w) == 0))
8789 return 0;
8790
8791 /* Set up an iterator for the tool-bar window. */
8792 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8793 it.first_visible_x = 0;
8794 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8795 row = it.glyph_row;
8796
8797 /* Build a string that represents the contents of the tool-bar. */
8798 build_desired_tool_bar_string (f);
8799 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8800
8801 /* Display as many lines as needed to display all tool-bar items. */
8802 while (it.current_y < it.last_visible_y)
8803 display_tool_bar_line (&it);
8804
8805 /* It doesn't make much sense to try scrolling in the tool-bar
8806 window, so don't do it. */
8807 w->desired_matrix->no_scrolling_p = 1;
8808 w->must_be_updated_p = 1;
8809
8810 if (auto_resize_tool_bars_p)
8811 {
8812 int nlines;
8813
8814 /* If we couldn't display everything, change the tool-bar's
8815 height. */
8816 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8817 change_height_p = 1;
8818
8819 /* If there are blank lines at the end, except for a partially
8820 visible blank line at the end that is smaller than
8821 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8822 row = it.glyph_row - 1;
8823 if (!row->displays_text_p
8824 && row->height >= FRAME_LINE_HEIGHT (f))
8825 change_height_p = 1;
8826
8827 /* If row displays tool-bar items, but is partially visible,
8828 change the tool-bar's height. */
8829 if (row->displays_text_p
8830 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8831 change_height_p = 1;
8832
8833 /* Resize windows as needed by changing the `tool-bar-lines'
8834 frame parameter. */
8835 if (change_height_p
8836 && (nlines = tool_bar_lines_needed (f),
8837 nlines != WINDOW_TOTAL_LINES (w)))
8838 {
8839 extern Lisp_Object Qtool_bar_lines;
8840 Lisp_Object frame;
8841 int old_height = WINDOW_TOTAL_LINES (w);
8842
8843 XSETFRAME (frame, f);
8844 clear_glyph_matrix (w->desired_matrix);
8845 Fmodify_frame_parameters (frame,
8846 Fcons (Fcons (Qtool_bar_lines,
8847 make_number (nlines)),
8848 Qnil));
8849 if (WINDOW_TOTAL_LINES (w) != old_height)
8850 fonts_changed_p = 1;
8851 }
8852 }
8853
8854 return change_height_p;
8855 }
8856
8857
8858 /* Get information about the tool-bar item which is displayed in GLYPH
8859 on frame F. Return in *PROP_IDX the index where tool-bar item
8860 properties start in F->tool_bar_items. Value is zero if
8861 GLYPH doesn't display a tool-bar item. */
8862
8863 static int
8864 tool_bar_item_info (f, glyph, prop_idx)
8865 struct frame *f;
8866 struct glyph *glyph;
8867 int *prop_idx;
8868 {
8869 Lisp_Object prop;
8870 int success_p;
8871 int charpos;
8872
8873 /* This function can be called asynchronously, which means we must
8874 exclude any possibility that Fget_text_property signals an
8875 error. */
8876 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8877 charpos = max (0, charpos);
8878
8879 /* Get the text property `menu-item' at pos. The value of that
8880 property is the start index of this item's properties in
8881 F->tool_bar_items. */
8882 prop = Fget_text_property (make_number (charpos),
8883 Qmenu_item, f->current_tool_bar_string);
8884 if (INTEGERP (prop))
8885 {
8886 *prop_idx = XINT (prop);
8887 success_p = 1;
8888 }
8889 else
8890 success_p = 0;
8891
8892 return success_p;
8893 }
8894
8895 \f
8896 /* Get information about the tool-bar item at position X/Y on frame F.
8897 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8898 the current matrix of the tool-bar window of F, or NULL if not
8899 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8900 item in F->tool_bar_items. Value is
8901
8902 -1 if X/Y is not on a tool-bar item
8903 0 if X/Y is on the same item that was highlighted before.
8904 1 otherwise. */
8905
8906 static int
8907 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8908 struct frame *f;
8909 int x, y;
8910 struct glyph **glyph;
8911 int *hpos, *vpos, *prop_idx;
8912 {
8913 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8914 struct window *w = XWINDOW (f->tool_bar_window);
8915 int area;
8916
8917 /* Find the glyph under X/Y. */
8918 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8919 if (*glyph == NULL)
8920 return -1;
8921
8922 /* Get the start of this tool-bar item's properties in
8923 f->tool_bar_items. */
8924 if (!tool_bar_item_info (f, *glyph, prop_idx))
8925 return -1;
8926
8927 /* Is mouse on the highlighted item? */
8928 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8929 && *vpos >= dpyinfo->mouse_face_beg_row
8930 && *vpos <= dpyinfo->mouse_face_end_row
8931 && (*vpos > dpyinfo->mouse_face_beg_row
8932 || *hpos >= dpyinfo->mouse_face_beg_col)
8933 && (*vpos < dpyinfo->mouse_face_end_row
8934 || *hpos < dpyinfo->mouse_face_end_col
8935 || dpyinfo->mouse_face_past_end))
8936 return 0;
8937
8938 return 1;
8939 }
8940
8941
8942 /* EXPORT:
8943 Handle mouse button event on the tool-bar of frame F, at
8944 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8945 0 for button release. MODIFIERS is event modifiers for button
8946 release. */
8947
8948 void
8949 handle_tool_bar_click (f, x, y, down_p, modifiers)
8950 struct frame *f;
8951 int x, y, down_p;
8952 unsigned int modifiers;
8953 {
8954 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8955 struct window *w = XWINDOW (f->tool_bar_window);
8956 int hpos, vpos, prop_idx;
8957 struct glyph *glyph;
8958 Lisp_Object enabled_p;
8959
8960 /* If not on the highlighted tool-bar item, return. */
8961 frame_to_window_pixel_xy (w, &x, &y);
8962 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8963 return;
8964
8965 /* If item is disabled, do nothing. */
8966 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8967 if (NILP (enabled_p))
8968 return;
8969
8970 if (down_p)
8971 {
8972 /* Show item in pressed state. */
8973 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8974 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8975 last_tool_bar_item = prop_idx;
8976 }
8977 else
8978 {
8979 Lisp_Object key, frame;
8980 struct input_event event;
8981 EVENT_INIT (event);
8982
8983 /* Show item in released state. */
8984 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8985 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8986
8987 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8988
8989 XSETFRAME (frame, f);
8990 event.kind = TOOL_BAR_EVENT;
8991 event.frame_or_window = frame;
8992 event.arg = frame;
8993 kbd_buffer_store_event (&event);
8994
8995 event.kind = TOOL_BAR_EVENT;
8996 event.frame_or_window = frame;
8997 event.arg = key;
8998 event.modifiers = modifiers;
8999 kbd_buffer_store_event (&event);
9000 last_tool_bar_item = -1;
9001 }
9002 }
9003
9004
9005 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9006 tool-bar window-relative coordinates X/Y. Called from
9007 note_mouse_highlight. */
9008
9009 static void
9010 note_tool_bar_highlight (f, x, y)
9011 struct frame *f;
9012 int x, y;
9013 {
9014 Lisp_Object window = f->tool_bar_window;
9015 struct window *w = XWINDOW (window);
9016 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9017 int hpos, vpos;
9018 struct glyph *glyph;
9019 struct glyph_row *row;
9020 int i;
9021 Lisp_Object enabled_p;
9022 int prop_idx;
9023 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9024 int mouse_down_p, rc;
9025
9026 /* Function note_mouse_highlight is called with negative x(y
9027 values when mouse moves outside of the frame. */
9028 if (x <= 0 || y <= 0)
9029 {
9030 clear_mouse_face (dpyinfo);
9031 return;
9032 }
9033
9034 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9035 if (rc < 0)
9036 {
9037 /* Not on tool-bar item. */
9038 clear_mouse_face (dpyinfo);
9039 return;
9040 }
9041 else if (rc == 0)
9042 /* On same tool-bar item as before. */
9043 goto set_help_echo;
9044
9045 clear_mouse_face (dpyinfo);
9046
9047 /* Mouse is down, but on different tool-bar item? */
9048 mouse_down_p = (dpyinfo->grabbed
9049 && f == last_mouse_frame
9050 && FRAME_LIVE_P (f));
9051 if (mouse_down_p
9052 && last_tool_bar_item != prop_idx)
9053 return;
9054
9055 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9056 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9057
9058 /* If tool-bar item is not enabled, don't highlight it. */
9059 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9060 if (!NILP (enabled_p))
9061 {
9062 /* Compute the x-position of the glyph. In front and past the
9063 image is a space. We include this in the highlighted area. */
9064 row = MATRIX_ROW (w->current_matrix, vpos);
9065 for (i = x = 0; i < hpos; ++i)
9066 x += row->glyphs[TEXT_AREA][i].pixel_width;
9067
9068 /* Record this as the current active region. */
9069 dpyinfo->mouse_face_beg_col = hpos;
9070 dpyinfo->mouse_face_beg_row = vpos;
9071 dpyinfo->mouse_face_beg_x = x;
9072 dpyinfo->mouse_face_beg_y = row->y;
9073 dpyinfo->mouse_face_past_end = 0;
9074
9075 dpyinfo->mouse_face_end_col = hpos + 1;
9076 dpyinfo->mouse_face_end_row = vpos;
9077 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9078 dpyinfo->mouse_face_end_y = row->y;
9079 dpyinfo->mouse_face_window = window;
9080 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9081
9082 /* Display it as active. */
9083 show_mouse_face (dpyinfo, draw);
9084 dpyinfo->mouse_face_image_state = draw;
9085 }
9086
9087 set_help_echo:
9088
9089 /* Set help_echo_string to a help string to display for this tool-bar item.
9090 XTread_socket does the rest. */
9091 help_echo_object = help_echo_window = Qnil;
9092 help_echo_pos = -1;
9093 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9094 if (NILP (help_echo_string))
9095 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9096 }
9097
9098 #endif /* HAVE_WINDOW_SYSTEM */
9099
9100
9101 \f
9102 /************************************************************************
9103 Horizontal scrolling
9104 ************************************************************************/
9105
9106 static int hscroll_window_tree P_ ((Lisp_Object));
9107 static int hscroll_windows P_ ((Lisp_Object));
9108
9109 /* For all leaf windows in the window tree rooted at WINDOW, set their
9110 hscroll value so that PT is (i) visible in the window, and (ii) so
9111 that it is not within a certain margin at the window's left and
9112 right border. Value is non-zero if any window's hscroll has been
9113 changed. */
9114
9115 static int
9116 hscroll_window_tree (window)
9117 Lisp_Object window;
9118 {
9119 int hscrolled_p = 0;
9120 int hscroll_relative_p = FLOATP (Vhscroll_step);
9121 int hscroll_step_abs = 0;
9122 double hscroll_step_rel = 0;
9123
9124 if (hscroll_relative_p)
9125 {
9126 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9127 if (hscroll_step_rel < 0)
9128 {
9129 hscroll_relative_p = 0;
9130 hscroll_step_abs = 0;
9131 }
9132 }
9133 else if (INTEGERP (Vhscroll_step))
9134 {
9135 hscroll_step_abs = XINT (Vhscroll_step);
9136 if (hscroll_step_abs < 0)
9137 hscroll_step_abs = 0;
9138 }
9139 else
9140 hscroll_step_abs = 0;
9141
9142 while (WINDOWP (window))
9143 {
9144 struct window *w = XWINDOW (window);
9145
9146 if (WINDOWP (w->hchild))
9147 hscrolled_p |= hscroll_window_tree (w->hchild);
9148 else if (WINDOWP (w->vchild))
9149 hscrolled_p |= hscroll_window_tree (w->vchild);
9150 else if (w->cursor.vpos >= 0)
9151 {
9152 int h_margin;
9153 int text_area_width;
9154 struct glyph_row *current_cursor_row
9155 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9156 struct glyph_row *desired_cursor_row
9157 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9158 struct glyph_row *cursor_row
9159 = (desired_cursor_row->enabled_p
9160 ? desired_cursor_row
9161 : current_cursor_row);
9162
9163 text_area_width = window_box_width (w, TEXT_AREA);
9164
9165 /* Scroll when cursor is inside this scroll margin. */
9166 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9167
9168 if ((XFASTINT (w->hscroll)
9169 && w->cursor.x <= h_margin)
9170 || (cursor_row->enabled_p
9171 && cursor_row->truncated_on_right_p
9172 && (w->cursor.x >= text_area_width - h_margin)))
9173 {
9174 struct it it;
9175 int hscroll;
9176 struct buffer *saved_current_buffer;
9177 int pt;
9178 int wanted_x;
9179
9180 /* Find point in a display of infinite width. */
9181 saved_current_buffer = current_buffer;
9182 current_buffer = XBUFFER (w->buffer);
9183
9184 if (w == XWINDOW (selected_window))
9185 pt = BUF_PT (current_buffer);
9186 else
9187 {
9188 pt = marker_position (w->pointm);
9189 pt = max (BEGV, pt);
9190 pt = min (ZV, pt);
9191 }
9192
9193 /* Move iterator to pt starting at cursor_row->start in
9194 a line with infinite width. */
9195 init_to_row_start (&it, w, cursor_row);
9196 it.last_visible_x = INFINITY;
9197 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9198 current_buffer = saved_current_buffer;
9199
9200 /* Position cursor in window. */
9201 if (!hscroll_relative_p && hscroll_step_abs == 0)
9202 hscroll = max (0, (it.current_x
9203 - (ITERATOR_AT_END_OF_LINE_P (&it)
9204 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9205 : (text_area_width / 2))))
9206 / FRAME_COLUMN_WIDTH (it.f);
9207 else if (w->cursor.x >= text_area_width - h_margin)
9208 {
9209 if (hscroll_relative_p)
9210 wanted_x = text_area_width * (1 - hscroll_step_rel)
9211 - h_margin;
9212 else
9213 wanted_x = text_area_width
9214 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9215 - h_margin;
9216 hscroll
9217 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9218 }
9219 else
9220 {
9221 if (hscroll_relative_p)
9222 wanted_x = text_area_width * hscroll_step_rel
9223 + h_margin;
9224 else
9225 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9226 + h_margin;
9227 hscroll
9228 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9229 }
9230 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9231
9232 /* Don't call Fset_window_hscroll if value hasn't
9233 changed because it will prevent redisplay
9234 optimizations. */
9235 if (XFASTINT (w->hscroll) != hscroll)
9236 {
9237 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9238 w->hscroll = make_number (hscroll);
9239 hscrolled_p = 1;
9240 }
9241 }
9242 }
9243
9244 window = w->next;
9245 }
9246
9247 /* Value is non-zero if hscroll of any leaf window has been changed. */
9248 return hscrolled_p;
9249 }
9250
9251
9252 /* Set hscroll so that cursor is visible and not inside horizontal
9253 scroll margins for all windows in the tree rooted at WINDOW. See
9254 also hscroll_window_tree above. Value is non-zero if any window's
9255 hscroll has been changed. If it has, desired matrices on the frame
9256 of WINDOW are cleared. */
9257
9258 static int
9259 hscroll_windows (window)
9260 Lisp_Object window;
9261 {
9262 int hscrolled_p;
9263
9264 if (automatic_hscrolling_p)
9265 {
9266 hscrolled_p = hscroll_window_tree (window);
9267 if (hscrolled_p)
9268 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9269 }
9270 else
9271 hscrolled_p = 0;
9272 return hscrolled_p;
9273 }
9274
9275
9276 \f
9277 /************************************************************************
9278 Redisplay
9279 ************************************************************************/
9280
9281 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9282 to a non-zero value. This is sometimes handy to have in a debugger
9283 session. */
9284
9285 #if GLYPH_DEBUG
9286
9287 /* First and last unchanged row for try_window_id. */
9288
9289 int debug_first_unchanged_at_end_vpos;
9290 int debug_last_unchanged_at_beg_vpos;
9291
9292 /* Delta vpos and y. */
9293
9294 int debug_dvpos, debug_dy;
9295
9296 /* Delta in characters and bytes for try_window_id. */
9297
9298 int debug_delta, debug_delta_bytes;
9299
9300 /* Values of window_end_pos and window_end_vpos at the end of
9301 try_window_id. */
9302
9303 EMACS_INT debug_end_pos, debug_end_vpos;
9304
9305 /* Append a string to W->desired_matrix->method. FMT is a printf
9306 format string. A1...A9 are a supplement for a variable-length
9307 argument list. If trace_redisplay_p is non-zero also printf the
9308 resulting string to stderr. */
9309
9310 static void
9311 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9312 struct window *w;
9313 char *fmt;
9314 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9315 {
9316 char buffer[512];
9317 char *method = w->desired_matrix->method;
9318 int len = strlen (method);
9319 int size = sizeof w->desired_matrix->method;
9320 int remaining = size - len - 1;
9321
9322 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9323 if (len && remaining)
9324 {
9325 method[len] = '|';
9326 --remaining, ++len;
9327 }
9328
9329 strncpy (method + len, buffer, remaining);
9330
9331 if (trace_redisplay_p)
9332 fprintf (stderr, "%p (%s): %s\n",
9333 w,
9334 ((BUFFERP (w->buffer)
9335 && STRINGP (XBUFFER (w->buffer)->name))
9336 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9337 : "no buffer"),
9338 buffer);
9339 }
9340
9341 #endif /* GLYPH_DEBUG */
9342
9343
9344 /* Value is non-zero if all changes in window W, which displays
9345 current_buffer, are in the text between START and END. START is a
9346 buffer position, END is given as a distance from Z. Used in
9347 redisplay_internal for display optimization. */
9348
9349 static INLINE int
9350 text_outside_line_unchanged_p (w, start, end)
9351 struct window *w;
9352 int start, end;
9353 {
9354 int unchanged_p = 1;
9355
9356 /* If text or overlays have changed, see where. */
9357 if (XFASTINT (w->last_modified) < MODIFF
9358 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9359 {
9360 /* Gap in the line? */
9361 if (GPT < start || Z - GPT < end)
9362 unchanged_p = 0;
9363
9364 /* Changes start in front of the line, or end after it? */
9365 if (unchanged_p
9366 && (BEG_UNCHANGED < start - 1
9367 || END_UNCHANGED < end))
9368 unchanged_p = 0;
9369
9370 /* If selective display, can't optimize if changes start at the
9371 beginning of the line. */
9372 if (unchanged_p
9373 && INTEGERP (current_buffer->selective_display)
9374 && XINT (current_buffer->selective_display) > 0
9375 && (BEG_UNCHANGED < start || GPT <= start))
9376 unchanged_p = 0;
9377
9378 /* If there are overlays at the start or end of the line, these
9379 may have overlay strings with newlines in them. A change at
9380 START, for instance, may actually concern the display of such
9381 overlay strings as well, and they are displayed on different
9382 lines. So, quickly rule out this case. (For the future, it
9383 might be desirable to implement something more telling than
9384 just BEG/END_UNCHANGED.) */
9385 if (unchanged_p)
9386 {
9387 if (BEG + BEG_UNCHANGED == start
9388 && overlay_touches_p (start))
9389 unchanged_p = 0;
9390 if (END_UNCHANGED == end
9391 && overlay_touches_p (Z - end))
9392 unchanged_p = 0;
9393 }
9394 }
9395
9396 return unchanged_p;
9397 }
9398
9399
9400 /* Do a frame update, taking possible shortcuts into account. This is
9401 the main external entry point for redisplay.
9402
9403 If the last redisplay displayed an echo area message and that message
9404 is no longer requested, we clear the echo area or bring back the
9405 mini-buffer if that is in use. */
9406
9407 void
9408 redisplay ()
9409 {
9410 redisplay_internal (0);
9411 }
9412
9413
9414 static Lisp_Object
9415 overlay_arrow_string_or_property (var, pbitmap)
9416 Lisp_Object var;
9417 int *pbitmap;
9418 {
9419 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9420 Lisp_Object bitmap;
9421
9422 if (pbitmap)
9423 {
9424 *pbitmap = 0;
9425 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9426 *pbitmap = XINT (bitmap);
9427 }
9428
9429 if (!NILP (pstr))
9430 return pstr;
9431 return Voverlay_arrow_string;
9432 }
9433
9434 /* Return 1 if there are any overlay-arrows in current_buffer. */
9435 static int
9436 overlay_arrow_in_current_buffer_p ()
9437 {
9438 Lisp_Object vlist;
9439
9440 for (vlist = Voverlay_arrow_variable_list;
9441 CONSP (vlist);
9442 vlist = XCDR (vlist))
9443 {
9444 Lisp_Object var = XCAR (vlist);
9445 Lisp_Object val;
9446
9447 if (!SYMBOLP (var))
9448 continue;
9449 val = find_symbol_value (var);
9450 if (MARKERP (val)
9451 && current_buffer == XMARKER (val)->buffer)
9452 return 1;
9453 }
9454 return 0;
9455 }
9456
9457
9458 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9459 has changed. */
9460
9461 static int
9462 overlay_arrows_changed_p ()
9463 {
9464 Lisp_Object vlist;
9465
9466 for (vlist = Voverlay_arrow_variable_list;
9467 CONSP (vlist);
9468 vlist = XCDR (vlist))
9469 {
9470 Lisp_Object var = XCAR (vlist);
9471 Lisp_Object val, pstr;
9472
9473 if (!SYMBOLP (var))
9474 continue;
9475 val = find_symbol_value (var);
9476 if (!MARKERP (val))
9477 continue;
9478 if (! EQ (COERCE_MARKER (val),
9479 Fget (var, Qlast_arrow_position))
9480 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9481 EQ (pstr, Fget (var, Qlast_arrow_string))))
9482 return 1;
9483 }
9484 return 0;
9485 }
9486
9487 /* Mark overlay arrows to be updated on next redisplay. */
9488
9489 static void
9490 update_overlay_arrows (up_to_date)
9491 int up_to_date;
9492 {
9493 Lisp_Object vlist;
9494
9495 for (vlist = Voverlay_arrow_variable_list;
9496 CONSP (vlist);
9497 vlist = XCDR (vlist))
9498 {
9499 Lisp_Object var = XCAR (vlist);
9500
9501 if (!SYMBOLP (var))
9502 continue;
9503
9504 if (up_to_date > 0)
9505 {
9506 Lisp_Object val = find_symbol_value (var);
9507 Fput (var, Qlast_arrow_position,
9508 COERCE_MARKER (val));
9509 Fput (var, Qlast_arrow_string,
9510 overlay_arrow_string_or_property (var, 0));
9511 }
9512 else if (up_to_date < 0
9513 || !NILP (Fget (var, Qlast_arrow_position)))
9514 {
9515 Fput (var, Qlast_arrow_position, Qt);
9516 Fput (var, Qlast_arrow_string, Qt);
9517 }
9518 }
9519 }
9520
9521
9522 /* Return overlay arrow string at row, or nil. */
9523
9524 static Lisp_Object
9525 overlay_arrow_at_row (f, row, pbitmap)
9526 struct frame *f;
9527 struct glyph_row *row;
9528 int *pbitmap;
9529 {
9530 Lisp_Object vlist;
9531
9532 for (vlist = Voverlay_arrow_variable_list;
9533 CONSP (vlist);
9534 vlist = XCDR (vlist))
9535 {
9536 Lisp_Object var = XCAR (vlist);
9537 Lisp_Object val;
9538
9539 if (!SYMBOLP (var))
9540 continue;
9541
9542 val = find_symbol_value (var);
9543
9544 if (MARKERP (val)
9545 && current_buffer == XMARKER (val)->buffer
9546 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9547 {
9548 val = overlay_arrow_string_or_property (var, pbitmap);
9549 if (FRAME_WINDOW_P (f))
9550 return Qt;
9551 else if (STRINGP (val))
9552 return val;
9553 break;
9554 }
9555 }
9556
9557 *pbitmap = 0;
9558 return Qnil;
9559 }
9560
9561 /* Return 1 if point moved out of or into a composition. Otherwise
9562 return 0. PREV_BUF and PREV_PT are the last point buffer and
9563 position. BUF and PT are the current point buffer and position. */
9564
9565 int
9566 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9567 struct buffer *prev_buf, *buf;
9568 int prev_pt, pt;
9569 {
9570 int start, end;
9571 Lisp_Object prop;
9572 Lisp_Object buffer;
9573
9574 XSETBUFFER (buffer, buf);
9575 /* Check a composition at the last point if point moved within the
9576 same buffer. */
9577 if (prev_buf == buf)
9578 {
9579 if (prev_pt == pt)
9580 /* Point didn't move. */
9581 return 0;
9582
9583 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9584 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9585 && COMPOSITION_VALID_P (start, end, prop)
9586 && start < prev_pt && end > prev_pt)
9587 /* The last point was within the composition. Return 1 iff
9588 point moved out of the composition. */
9589 return (pt <= start || pt >= end);
9590 }
9591
9592 /* Check a composition at the current point. */
9593 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9594 && find_composition (pt, -1, &start, &end, &prop, buffer)
9595 && COMPOSITION_VALID_P (start, end, prop)
9596 && start < pt && end > pt);
9597 }
9598
9599
9600 /* Reconsider the setting of B->clip_changed which is displayed
9601 in window W. */
9602
9603 static INLINE void
9604 reconsider_clip_changes (w, b)
9605 struct window *w;
9606 struct buffer *b;
9607 {
9608 if (b->clip_changed
9609 && !NILP (w->window_end_valid)
9610 && w->current_matrix->buffer == b
9611 && w->current_matrix->zv == BUF_ZV (b)
9612 && w->current_matrix->begv == BUF_BEGV (b))
9613 b->clip_changed = 0;
9614
9615 /* If display wasn't paused, and W is not a tool bar window, see if
9616 point has been moved into or out of a composition. In that case,
9617 we set b->clip_changed to 1 to force updating the screen. If
9618 b->clip_changed has already been set to 1, we can skip this
9619 check. */
9620 if (!b->clip_changed
9621 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9622 {
9623 int pt;
9624
9625 if (w == XWINDOW (selected_window))
9626 pt = BUF_PT (current_buffer);
9627 else
9628 pt = marker_position (w->pointm);
9629
9630 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9631 || pt != XINT (w->last_point))
9632 && check_point_in_composition (w->current_matrix->buffer,
9633 XINT (w->last_point),
9634 XBUFFER (w->buffer), pt))
9635 b->clip_changed = 1;
9636 }
9637 }
9638 \f
9639
9640 /* Select FRAME to forward the values of frame-local variables into C
9641 variables so that the redisplay routines can access those values
9642 directly. */
9643
9644 static void
9645 select_frame_for_redisplay (frame)
9646 Lisp_Object frame;
9647 {
9648 Lisp_Object tail, sym, val;
9649 Lisp_Object old = selected_frame;
9650
9651 selected_frame = frame;
9652
9653 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9654 if (CONSP (XCAR (tail))
9655 && (sym = XCAR (XCAR (tail)),
9656 SYMBOLP (sym))
9657 && (sym = indirect_variable (sym),
9658 val = SYMBOL_VALUE (sym),
9659 (BUFFER_LOCAL_VALUEP (val)
9660 || SOME_BUFFER_LOCAL_VALUEP (val)))
9661 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9662 Fsymbol_value (sym);
9663
9664 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9665 if (CONSP (XCAR (tail))
9666 && (sym = XCAR (XCAR (tail)),
9667 SYMBOLP (sym))
9668 && (sym = indirect_variable (sym),
9669 val = SYMBOL_VALUE (sym),
9670 (BUFFER_LOCAL_VALUEP (val)
9671 || SOME_BUFFER_LOCAL_VALUEP (val)))
9672 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9673 Fsymbol_value (sym);
9674 }
9675
9676
9677 #define STOP_POLLING \
9678 do { if (! polling_stopped_here) stop_polling (); \
9679 polling_stopped_here = 1; } while (0)
9680
9681 #define RESUME_POLLING \
9682 do { if (polling_stopped_here) start_polling (); \
9683 polling_stopped_here = 0; } while (0)
9684
9685
9686 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9687 response to any user action; therefore, we should preserve the echo
9688 area. (Actually, our caller does that job.) Perhaps in the future
9689 avoid recentering windows if it is not necessary; currently that
9690 causes some problems. */
9691
9692 static void
9693 redisplay_internal (preserve_echo_area)
9694 int preserve_echo_area;
9695 {
9696 struct window *w = XWINDOW (selected_window);
9697 struct frame *f = XFRAME (w->frame);
9698 int pause;
9699 int must_finish = 0;
9700 struct text_pos tlbufpos, tlendpos;
9701 int number_of_visible_frames;
9702 int count;
9703 struct frame *sf = SELECTED_FRAME ();
9704 int polling_stopped_here = 0;
9705
9706 /* Non-zero means redisplay has to consider all windows on all
9707 frames. Zero means, only selected_window is considered. */
9708 int consider_all_windows_p;
9709
9710 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9711
9712 /* No redisplay if running in batch mode or frame is not yet fully
9713 initialized, or redisplay is explicitly turned off by setting
9714 Vinhibit_redisplay. */
9715 if (noninteractive
9716 || !NILP (Vinhibit_redisplay)
9717 || !f->glyphs_initialized_p)
9718 return;
9719
9720 /* The flag redisplay_performed_directly_p is set by
9721 direct_output_for_insert when it already did the whole screen
9722 update necessary. */
9723 if (redisplay_performed_directly_p)
9724 {
9725 redisplay_performed_directly_p = 0;
9726 if (!hscroll_windows (selected_window))
9727 return;
9728 }
9729
9730 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9731 if (popup_activated ())
9732 return;
9733 #endif
9734
9735 /* I don't think this happens but let's be paranoid. */
9736 if (redisplaying_p)
9737 return;
9738
9739 /* Record a function that resets redisplaying_p to its old value
9740 when we leave this function. */
9741 count = SPECPDL_INDEX ();
9742 record_unwind_protect (unwind_redisplay,
9743 Fcons (make_number (redisplaying_p), selected_frame));
9744 ++redisplaying_p;
9745 specbind (Qinhibit_free_realized_faces, Qnil);
9746
9747 retry:
9748 pause = 0;
9749 reconsider_clip_changes (w, current_buffer);
9750
9751 /* If new fonts have been loaded that make a glyph matrix adjustment
9752 necessary, do it. */
9753 if (fonts_changed_p)
9754 {
9755 adjust_glyphs (NULL);
9756 ++windows_or_buffers_changed;
9757 fonts_changed_p = 0;
9758 }
9759
9760 /* If face_change_count is non-zero, init_iterator will free all
9761 realized faces, which includes the faces referenced from current
9762 matrices. So, we can't reuse current matrices in this case. */
9763 if (face_change_count)
9764 ++windows_or_buffers_changed;
9765
9766 if (! FRAME_WINDOW_P (sf)
9767 && previous_terminal_frame != sf)
9768 {
9769 /* Since frames on an ASCII terminal share the same display
9770 area, displaying a different frame means redisplay the whole
9771 thing. */
9772 windows_or_buffers_changed++;
9773 SET_FRAME_GARBAGED (sf);
9774 XSETFRAME (Vterminal_frame, sf);
9775 }
9776 previous_terminal_frame = sf;
9777
9778 /* Set the visible flags for all frames. Do this before checking
9779 for resized or garbaged frames; they want to know if their frames
9780 are visible. See the comment in frame.h for
9781 FRAME_SAMPLE_VISIBILITY. */
9782 {
9783 Lisp_Object tail, frame;
9784
9785 number_of_visible_frames = 0;
9786
9787 FOR_EACH_FRAME (tail, frame)
9788 {
9789 struct frame *f = XFRAME (frame);
9790
9791 FRAME_SAMPLE_VISIBILITY (f);
9792 if (FRAME_VISIBLE_P (f))
9793 ++number_of_visible_frames;
9794 clear_desired_matrices (f);
9795 }
9796 }
9797
9798 /* Notice any pending interrupt request to change frame size. */
9799 do_pending_window_change (1);
9800
9801 /* Clear frames marked as garbaged. */
9802 if (frame_garbaged)
9803 clear_garbaged_frames ();
9804
9805 /* Build menubar and tool-bar items. */
9806 prepare_menu_bars ();
9807
9808 if (windows_or_buffers_changed)
9809 update_mode_lines++;
9810
9811 /* Detect case that we need to write or remove a star in the mode line. */
9812 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9813 {
9814 w->update_mode_line = Qt;
9815 if (buffer_shared > 1)
9816 update_mode_lines++;
9817 }
9818
9819 /* If %c is in the mode line, update it if needed. */
9820 if (!NILP (w->column_number_displayed)
9821 /* This alternative quickly identifies a common case
9822 where no change is needed. */
9823 && !(PT == XFASTINT (w->last_point)
9824 && XFASTINT (w->last_modified) >= MODIFF
9825 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9826 && (XFASTINT (w->column_number_displayed)
9827 != (int) current_column ())) /* iftc */
9828 w->update_mode_line = Qt;
9829
9830 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9831
9832 /* The variable buffer_shared is set in redisplay_window and
9833 indicates that we redisplay a buffer in different windows. See
9834 there. */
9835 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9836 || cursor_type_changed);
9837
9838 /* If specs for an arrow have changed, do thorough redisplay
9839 to ensure we remove any arrow that should no longer exist. */
9840 if (overlay_arrows_changed_p ())
9841 consider_all_windows_p = windows_or_buffers_changed = 1;
9842
9843 /* Normally the message* functions will have already displayed and
9844 updated the echo area, but the frame may have been trashed, or
9845 the update may have been preempted, so display the echo area
9846 again here. Checking message_cleared_p captures the case that
9847 the echo area should be cleared. */
9848 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9849 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9850 || (message_cleared_p
9851 && minibuf_level == 0
9852 /* If the mini-window is currently selected, this means the
9853 echo-area doesn't show through. */
9854 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9855 {
9856 int window_height_changed_p = echo_area_display (0);
9857 must_finish = 1;
9858
9859 /* If we don't display the current message, don't clear the
9860 message_cleared_p flag, because, if we did, we wouldn't clear
9861 the echo area in the next redisplay which doesn't preserve
9862 the echo area. */
9863 if (!display_last_displayed_message_p)
9864 message_cleared_p = 0;
9865
9866 if (fonts_changed_p)
9867 goto retry;
9868 else if (window_height_changed_p)
9869 {
9870 consider_all_windows_p = 1;
9871 ++update_mode_lines;
9872 ++windows_or_buffers_changed;
9873
9874 /* If window configuration was changed, frames may have been
9875 marked garbaged. Clear them or we will experience
9876 surprises wrt scrolling. */
9877 if (frame_garbaged)
9878 clear_garbaged_frames ();
9879 }
9880 }
9881 else if (EQ (selected_window, minibuf_window)
9882 && (current_buffer->clip_changed
9883 || XFASTINT (w->last_modified) < MODIFF
9884 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9885 && resize_mini_window (w, 0))
9886 {
9887 /* Resized active mini-window to fit the size of what it is
9888 showing if its contents might have changed. */
9889 must_finish = 1;
9890 consider_all_windows_p = 1;
9891 ++windows_or_buffers_changed;
9892 ++update_mode_lines;
9893
9894 /* If window configuration was changed, frames may have been
9895 marked garbaged. Clear them or we will experience
9896 surprises wrt scrolling. */
9897 if (frame_garbaged)
9898 clear_garbaged_frames ();
9899 }
9900
9901
9902 /* If showing the region, and mark has changed, we must redisplay
9903 the whole window. The assignment to this_line_start_pos prevents
9904 the optimization directly below this if-statement. */
9905 if (((!NILP (Vtransient_mark_mode)
9906 && !NILP (XBUFFER (w->buffer)->mark_active))
9907 != !NILP (w->region_showing))
9908 || (!NILP (w->region_showing)
9909 && !EQ (w->region_showing,
9910 Fmarker_position (XBUFFER (w->buffer)->mark))))
9911 CHARPOS (this_line_start_pos) = 0;
9912
9913 /* Optimize the case that only the line containing the cursor in the
9914 selected window has changed. Variables starting with this_ are
9915 set in display_line and record information about the line
9916 containing the cursor. */
9917 tlbufpos = this_line_start_pos;
9918 tlendpos = this_line_end_pos;
9919 if (!consider_all_windows_p
9920 && CHARPOS (tlbufpos) > 0
9921 && NILP (w->update_mode_line)
9922 && !current_buffer->clip_changed
9923 && !current_buffer->prevent_redisplay_optimizations_p
9924 && FRAME_VISIBLE_P (XFRAME (w->frame))
9925 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9926 /* Make sure recorded data applies to current buffer, etc. */
9927 && this_line_buffer == current_buffer
9928 && current_buffer == XBUFFER (w->buffer)
9929 && NILP (w->force_start)
9930 && NILP (w->optional_new_start)
9931 /* Point must be on the line that we have info recorded about. */
9932 && PT >= CHARPOS (tlbufpos)
9933 && PT <= Z - CHARPOS (tlendpos)
9934 /* All text outside that line, including its final newline,
9935 must be unchanged */
9936 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9937 CHARPOS (tlendpos)))
9938 {
9939 if (CHARPOS (tlbufpos) > BEGV
9940 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9941 && (CHARPOS (tlbufpos) == ZV
9942 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9943 /* Former continuation line has disappeared by becoming empty */
9944 goto cancel;
9945 else if (XFASTINT (w->last_modified) < MODIFF
9946 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9947 || MINI_WINDOW_P (w))
9948 {
9949 /* We have to handle the case of continuation around a
9950 wide-column character (See the comment in indent.c around
9951 line 885).
9952
9953 For instance, in the following case:
9954
9955 -------- Insert --------
9956 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9957 J_I_ ==> J_I_ `^^' are cursors.
9958 ^^ ^^
9959 -------- --------
9960
9961 As we have to redraw the line above, we should goto cancel. */
9962
9963 struct it it;
9964 int line_height_before = this_line_pixel_height;
9965
9966 /* Note that start_display will handle the case that the
9967 line starting at tlbufpos is a continuation lines. */
9968 start_display (&it, w, tlbufpos);
9969
9970 /* Implementation note: It this still necessary? */
9971 if (it.current_x != this_line_start_x)
9972 goto cancel;
9973
9974 TRACE ((stderr, "trying display optimization 1\n"));
9975 w->cursor.vpos = -1;
9976 overlay_arrow_seen = 0;
9977 it.vpos = this_line_vpos;
9978 it.current_y = this_line_y;
9979 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9980 display_line (&it);
9981
9982 /* If line contains point, is not continued,
9983 and ends at same distance from eob as before, we win */
9984 if (w->cursor.vpos >= 0
9985 /* Line is not continued, otherwise this_line_start_pos
9986 would have been set to 0 in display_line. */
9987 && CHARPOS (this_line_start_pos)
9988 /* Line ends as before. */
9989 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9990 /* Line has same height as before. Otherwise other lines
9991 would have to be shifted up or down. */
9992 && this_line_pixel_height == line_height_before)
9993 {
9994 /* If this is not the window's last line, we must adjust
9995 the charstarts of the lines below. */
9996 if (it.current_y < it.last_visible_y)
9997 {
9998 struct glyph_row *row
9999 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10000 int delta, delta_bytes;
10001
10002 if (Z - CHARPOS (tlendpos) == ZV)
10003 {
10004 /* This line ends at end of (accessible part of)
10005 buffer. There is no newline to count. */
10006 delta = (Z
10007 - CHARPOS (tlendpos)
10008 - MATRIX_ROW_START_CHARPOS (row));
10009 delta_bytes = (Z_BYTE
10010 - BYTEPOS (tlendpos)
10011 - MATRIX_ROW_START_BYTEPOS (row));
10012 }
10013 else
10014 {
10015 /* This line ends in a newline. Must take
10016 account of the newline and the rest of the
10017 text that follows. */
10018 delta = (Z
10019 - CHARPOS (tlendpos)
10020 - MATRIX_ROW_START_CHARPOS (row));
10021 delta_bytes = (Z_BYTE
10022 - BYTEPOS (tlendpos)
10023 - MATRIX_ROW_START_BYTEPOS (row));
10024 }
10025
10026 increment_matrix_positions (w->current_matrix,
10027 this_line_vpos + 1,
10028 w->current_matrix->nrows,
10029 delta, delta_bytes);
10030 }
10031
10032 /* If this row displays text now but previously didn't,
10033 or vice versa, w->window_end_vpos may have to be
10034 adjusted. */
10035 if ((it.glyph_row - 1)->displays_text_p)
10036 {
10037 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10038 XSETINT (w->window_end_vpos, this_line_vpos);
10039 }
10040 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10041 && this_line_vpos > 0)
10042 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10043 w->window_end_valid = Qnil;
10044
10045 /* Update hint: No need to try to scroll in update_window. */
10046 w->desired_matrix->no_scrolling_p = 1;
10047
10048 #if GLYPH_DEBUG
10049 *w->desired_matrix->method = 0;
10050 debug_method_add (w, "optimization 1");
10051 #endif
10052 #ifdef HAVE_WINDOW_SYSTEM
10053 update_window_fringes (w, 0);
10054 #endif
10055 goto update;
10056 }
10057 else
10058 goto cancel;
10059 }
10060 else if (/* Cursor position hasn't changed. */
10061 PT == XFASTINT (w->last_point)
10062 /* Make sure the cursor was last displayed
10063 in this window. Otherwise we have to reposition it. */
10064 && 0 <= w->cursor.vpos
10065 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10066 {
10067 if (!must_finish)
10068 {
10069 do_pending_window_change (1);
10070
10071 /* We used to always goto end_of_redisplay here, but this
10072 isn't enough if we have a blinking cursor. */
10073 if (w->cursor_off_p == w->last_cursor_off_p)
10074 goto end_of_redisplay;
10075 }
10076 goto update;
10077 }
10078 /* If highlighting the region, or if the cursor is in the echo area,
10079 then we can't just move the cursor. */
10080 else if (! (!NILP (Vtransient_mark_mode)
10081 && !NILP (current_buffer->mark_active))
10082 && (EQ (selected_window, current_buffer->last_selected_window)
10083 || highlight_nonselected_windows)
10084 && NILP (w->region_showing)
10085 && NILP (Vshow_trailing_whitespace)
10086 && !cursor_in_echo_area)
10087 {
10088 struct it it;
10089 struct glyph_row *row;
10090
10091 /* Skip from tlbufpos to PT and see where it is. Note that
10092 PT may be in invisible text. If so, we will end at the
10093 next visible position. */
10094 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10095 NULL, DEFAULT_FACE_ID);
10096 it.current_x = this_line_start_x;
10097 it.current_y = this_line_y;
10098 it.vpos = this_line_vpos;
10099
10100 /* The call to move_it_to stops in front of PT, but
10101 moves over before-strings. */
10102 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10103
10104 if (it.vpos == this_line_vpos
10105 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10106 row->enabled_p))
10107 {
10108 xassert (this_line_vpos == it.vpos);
10109 xassert (this_line_y == it.current_y);
10110 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10111 #if GLYPH_DEBUG
10112 *w->desired_matrix->method = 0;
10113 debug_method_add (w, "optimization 3");
10114 #endif
10115 goto update;
10116 }
10117 else
10118 goto cancel;
10119 }
10120
10121 cancel:
10122 /* Text changed drastically or point moved off of line. */
10123 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10124 }
10125
10126 CHARPOS (this_line_start_pos) = 0;
10127 consider_all_windows_p |= buffer_shared > 1;
10128 ++clear_face_cache_count;
10129
10130
10131 /* Build desired matrices, and update the display. If
10132 consider_all_windows_p is non-zero, do it for all windows on all
10133 frames. Otherwise do it for selected_window, only. */
10134
10135 if (consider_all_windows_p)
10136 {
10137 Lisp_Object tail, frame;
10138 int i, n = 0, size = 50;
10139 struct frame **updated
10140 = (struct frame **) alloca (size * sizeof *updated);
10141
10142 /* Clear the face cache eventually. */
10143 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10144 {
10145 clear_face_cache (0);
10146 clear_face_cache_count = 0;
10147 }
10148
10149 /* Recompute # windows showing selected buffer. This will be
10150 incremented each time such a window is displayed. */
10151 buffer_shared = 0;
10152
10153 FOR_EACH_FRAME (tail, frame)
10154 {
10155 struct frame *f = XFRAME (frame);
10156
10157 if (FRAME_WINDOW_P (f) || f == sf)
10158 {
10159 if (! EQ (frame, selected_frame))
10160 /* Select the frame, for the sake of frame-local
10161 variables. */
10162 select_frame_for_redisplay (frame);
10163
10164 #ifdef HAVE_WINDOW_SYSTEM
10165 if (clear_face_cache_count % 50 == 0
10166 && FRAME_WINDOW_P (f))
10167 clear_image_cache (f, 0);
10168 #endif /* HAVE_WINDOW_SYSTEM */
10169
10170 /* Mark all the scroll bars to be removed; we'll redeem
10171 the ones we want when we redisplay their windows. */
10172 if (condemn_scroll_bars_hook)
10173 condemn_scroll_bars_hook (f);
10174
10175 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10176 redisplay_windows (FRAME_ROOT_WINDOW (f));
10177
10178 /* Any scroll bars which redisplay_windows should have
10179 nuked should now go away. */
10180 if (judge_scroll_bars_hook)
10181 judge_scroll_bars_hook (f);
10182
10183 /* If fonts changed, display again. */
10184 /* ??? rms: I suspect it is a mistake to jump all the way
10185 back to retry here. It should just retry this frame. */
10186 if (fonts_changed_p)
10187 goto retry;
10188
10189 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10190 {
10191 /* See if we have to hscroll. */
10192 if (hscroll_windows (f->root_window))
10193 goto retry;
10194
10195 /* Prevent various kinds of signals during display
10196 update. stdio is not robust about handling
10197 signals, which can cause an apparent I/O
10198 error. */
10199 if (interrupt_input)
10200 unrequest_sigio ();
10201 STOP_POLLING;
10202
10203 /* Update the display. */
10204 set_window_update_flags (XWINDOW (f->root_window), 1);
10205 pause |= update_frame (f, 0, 0);
10206 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10207 if (pause)
10208 break;
10209 #endif
10210
10211 if (n == size)
10212 {
10213 int nbytes = size * sizeof *updated;
10214 struct frame **p = (struct frame **) alloca (2 * nbytes);
10215 bcopy (updated, p, nbytes);
10216 size *= 2;
10217 }
10218
10219 updated[n++] = f;
10220 }
10221 }
10222 }
10223
10224 if (!pause)
10225 {
10226 /* Do the mark_window_display_accurate after all windows have
10227 been redisplayed because this call resets flags in buffers
10228 which are needed for proper redisplay. */
10229 for (i = 0; i < n; ++i)
10230 {
10231 struct frame *f = updated[i];
10232 mark_window_display_accurate (f->root_window, 1);
10233 if (frame_up_to_date_hook)
10234 frame_up_to_date_hook (f);
10235 }
10236 }
10237 }
10238 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10239 {
10240 Lisp_Object mini_window;
10241 struct frame *mini_frame;
10242
10243 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10244 /* Use list_of_error, not Qerror, so that
10245 we catch only errors and don't run the debugger. */
10246 internal_condition_case_1 (redisplay_window_1, selected_window,
10247 list_of_error,
10248 redisplay_window_error);
10249
10250 /* Compare desired and current matrices, perform output. */
10251
10252 update:
10253 /* If fonts changed, display again. */
10254 if (fonts_changed_p)
10255 goto retry;
10256
10257 /* Prevent various kinds of signals during display update.
10258 stdio is not robust about handling signals,
10259 which can cause an apparent I/O error. */
10260 if (interrupt_input)
10261 unrequest_sigio ();
10262 STOP_POLLING;
10263
10264 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10265 {
10266 if (hscroll_windows (selected_window))
10267 goto retry;
10268
10269 XWINDOW (selected_window)->must_be_updated_p = 1;
10270 pause = update_frame (sf, 0, 0);
10271 }
10272
10273 /* We may have called echo_area_display at the top of this
10274 function. If the echo area is on another frame, that may
10275 have put text on a frame other than the selected one, so the
10276 above call to update_frame would not have caught it. Catch
10277 it here. */
10278 mini_window = FRAME_MINIBUF_WINDOW (sf);
10279 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10280
10281 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10282 {
10283 XWINDOW (mini_window)->must_be_updated_p = 1;
10284 pause |= update_frame (mini_frame, 0, 0);
10285 if (!pause && hscroll_windows (mini_window))
10286 goto retry;
10287 }
10288 }
10289
10290 /* If display was paused because of pending input, make sure we do a
10291 thorough update the next time. */
10292 if (pause)
10293 {
10294 /* Prevent the optimization at the beginning of
10295 redisplay_internal that tries a single-line update of the
10296 line containing the cursor in the selected window. */
10297 CHARPOS (this_line_start_pos) = 0;
10298
10299 /* Let the overlay arrow be updated the next time. */
10300 update_overlay_arrows (0);
10301
10302 /* If we pause after scrolling, some rows in the current
10303 matrices of some windows are not valid. */
10304 if (!WINDOW_FULL_WIDTH_P (w)
10305 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10306 update_mode_lines = 1;
10307 }
10308 else
10309 {
10310 if (!consider_all_windows_p)
10311 {
10312 /* This has already been done above if
10313 consider_all_windows_p is set. */
10314 mark_window_display_accurate_1 (w, 1);
10315
10316 /* Say overlay arrows are up to date. */
10317 update_overlay_arrows (1);
10318
10319 if (frame_up_to_date_hook != 0)
10320 frame_up_to_date_hook (sf);
10321 }
10322
10323 update_mode_lines = 0;
10324 windows_or_buffers_changed = 0;
10325 cursor_type_changed = 0;
10326 }
10327
10328 /* Start SIGIO interrupts coming again. Having them off during the
10329 code above makes it less likely one will discard output, but not
10330 impossible, since there might be stuff in the system buffer here.
10331 But it is much hairier to try to do anything about that. */
10332 if (interrupt_input)
10333 request_sigio ();
10334 RESUME_POLLING;
10335
10336 /* If a frame has become visible which was not before, redisplay
10337 again, so that we display it. Expose events for such a frame
10338 (which it gets when becoming visible) don't call the parts of
10339 redisplay constructing glyphs, so simply exposing a frame won't
10340 display anything in this case. So, we have to display these
10341 frames here explicitly. */
10342 if (!pause)
10343 {
10344 Lisp_Object tail, frame;
10345 int new_count = 0;
10346
10347 FOR_EACH_FRAME (tail, frame)
10348 {
10349 int this_is_visible = 0;
10350
10351 if (XFRAME (frame)->visible)
10352 this_is_visible = 1;
10353 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10354 if (XFRAME (frame)->visible)
10355 this_is_visible = 1;
10356
10357 if (this_is_visible)
10358 new_count++;
10359 }
10360
10361 if (new_count != number_of_visible_frames)
10362 windows_or_buffers_changed++;
10363 }
10364
10365 /* Change frame size now if a change is pending. */
10366 do_pending_window_change (1);
10367
10368 /* If we just did a pending size change, or have additional
10369 visible frames, redisplay again. */
10370 if (windows_or_buffers_changed && !pause)
10371 goto retry;
10372
10373 end_of_redisplay:
10374 unbind_to (count, Qnil);
10375 RESUME_POLLING;
10376 }
10377
10378
10379 /* Redisplay, but leave alone any recent echo area message unless
10380 another message has been requested in its place.
10381
10382 This is useful in situations where you need to redisplay but no
10383 user action has occurred, making it inappropriate for the message
10384 area to be cleared. See tracking_off and
10385 wait_reading_process_output for examples of these situations.
10386
10387 FROM_WHERE is an integer saying from where this function was
10388 called. This is useful for debugging. */
10389
10390 void
10391 redisplay_preserve_echo_area (from_where)
10392 int from_where;
10393 {
10394 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10395
10396 if (!NILP (echo_area_buffer[1]))
10397 {
10398 /* We have a previously displayed message, but no current
10399 message. Redisplay the previous message. */
10400 display_last_displayed_message_p = 1;
10401 redisplay_internal (1);
10402 display_last_displayed_message_p = 0;
10403 }
10404 else
10405 redisplay_internal (1);
10406 }
10407
10408
10409 /* Function registered with record_unwind_protect in
10410 redisplay_internal. Reset redisplaying_p to the value it had
10411 before redisplay_internal was called, and clear
10412 prevent_freeing_realized_faces_p. It also selects the previously
10413 selected frame. */
10414
10415 static Lisp_Object
10416 unwind_redisplay (val)
10417 Lisp_Object val;
10418 {
10419 Lisp_Object old_redisplaying_p, old_frame;
10420
10421 old_redisplaying_p = XCAR (val);
10422 redisplaying_p = XFASTINT (old_redisplaying_p);
10423 old_frame = XCDR (val);
10424 if (! EQ (old_frame, selected_frame))
10425 select_frame_for_redisplay (old_frame);
10426 return Qnil;
10427 }
10428
10429
10430 /* Mark the display of window W as accurate or inaccurate. If
10431 ACCURATE_P is non-zero mark display of W as accurate. If
10432 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10433 redisplay_internal is called. */
10434
10435 static void
10436 mark_window_display_accurate_1 (w, accurate_p)
10437 struct window *w;
10438 int accurate_p;
10439 {
10440 if (BUFFERP (w->buffer))
10441 {
10442 struct buffer *b = XBUFFER (w->buffer);
10443
10444 w->last_modified
10445 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10446 w->last_overlay_modified
10447 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10448 w->last_had_star
10449 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10450
10451 if (accurate_p)
10452 {
10453 b->clip_changed = 0;
10454 b->prevent_redisplay_optimizations_p = 0;
10455
10456 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10457 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10458 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10459 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10460
10461 w->current_matrix->buffer = b;
10462 w->current_matrix->begv = BUF_BEGV (b);
10463 w->current_matrix->zv = BUF_ZV (b);
10464
10465 w->last_cursor = w->cursor;
10466 w->last_cursor_off_p = w->cursor_off_p;
10467
10468 if (w == XWINDOW (selected_window))
10469 w->last_point = make_number (BUF_PT (b));
10470 else
10471 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10472 }
10473 }
10474
10475 if (accurate_p)
10476 {
10477 w->window_end_valid = w->buffer;
10478 #if 0 /* This is incorrect with variable-height lines. */
10479 xassert (XINT (w->window_end_vpos)
10480 < (WINDOW_TOTAL_LINES (w)
10481 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10482 #endif
10483 w->update_mode_line = Qnil;
10484 }
10485 }
10486
10487
10488 /* Mark the display of windows in the window tree rooted at WINDOW as
10489 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10490 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10491 be redisplayed the next time redisplay_internal is called. */
10492
10493 void
10494 mark_window_display_accurate (window, accurate_p)
10495 Lisp_Object window;
10496 int accurate_p;
10497 {
10498 struct window *w;
10499
10500 for (; !NILP (window); window = w->next)
10501 {
10502 w = XWINDOW (window);
10503 mark_window_display_accurate_1 (w, accurate_p);
10504
10505 if (!NILP (w->vchild))
10506 mark_window_display_accurate (w->vchild, accurate_p);
10507 if (!NILP (w->hchild))
10508 mark_window_display_accurate (w->hchild, accurate_p);
10509 }
10510
10511 if (accurate_p)
10512 {
10513 update_overlay_arrows (1);
10514 }
10515 else
10516 {
10517 /* Force a thorough redisplay the next time by setting
10518 last_arrow_position and last_arrow_string to t, which is
10519 unequal to any useful value of Voverlay_arrow_... */
10520 update_overlay_arrows (-1);
10521 }
10522 }
10523
10524
10525 /* Return value in display table DP (Lisp_Char_Table *) for character
10526 C. Since a display table doesn't have any parent, we don't have to
10527 follow parent. Do not call this function directly but use the
10528 macro DISP_CHAR_VECTOR. */
10529
10530 Lisp_Object
10531 disp_char_vector (dp, c)
10532 struct Lisp_Char_Table *dp;
10533 int c;
10534 {
10535 int code[4], i;
10536 Lisp_Object val;
10537
10538 if (SINGLE_BYTE_CHAR_P (c))
10539 return (dp->contents[c]);
10540
10541 SPLIT_CHAR (c, code[0], code[1], code[2]);
10542 if (code[1] < 32)
10543 code[1] = -1;
10544 else if (code[2] < 32)
10545 code[2] = -1;
10546
10547 /* Here, the possible range of code[0] (== charset ID) is
10548 128..max_charset. Since the top level char table contains data
10549 for multibyte characters after 256th element, we must increment
10550 code[0] by 128 to get a correct index. */
10551 code[0] += 128;
10552 code[3] = -1; /* anchor */
10553
10554 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10555 {
10556 val = dp->contents[code[i]];
10557 if (!SUB_CHAR_TABLE_P (val))
10558 return (NILP (val) ? dp->defalt : val);
10559 }
10560
10561 /* Here, val is a sub char table. We return the default value of
10562 it. */
10563 return (dp->defalt);
10564 }
10565
10566
10567 \f
10568 /***********************************************************************
10569 Window Redisplay
10570 ***********************************************************************/
10571
10572 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10573
10574 static void
10575 redisplay_windows (window)
10576 Lisp_Object window;
10577 {
10578 while (!NILP (window))
10579 {
10580 struct window *w = XWINDOW (window);
10581
10582 if (!NILP (w->hchild))
10583 redisplay_windows (w->hchild);
10584 else if (!NILP (w->vchild))
10585 redisplay_windows (w->vchild);
10586 else
10587 {
10588 displayed_buffer = XBUFFER (w->buffer);
10589 /* Use list_of_error, not Qerror, so that
10590 we catch only errors and don't run the debugger. */
10591 internal_condition_case_1 (redisplay_window_0, window,
10592 list_of_error,
10593 redisplay_window_error);
10594 }
10595
10596 window = w->next;
10597 }
10598 }
10599
10600 static Lisp_Object
10601 redisplay_window_error ()
10602 {
10603 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10604 return Qnil;
10605 }
10606
10607 static Lisp_Object
10608 redisplay_window_0 (window)
10609 Lisp_Object window;
10610 {
10611 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10612 redisplay_window (window, 0);
10613 return Qnil;
10614 }
10615
10616 static Lisp_Object
10617 redisplay_window_1 (window)
10618 Lisp_Object window;
10619 {
10620 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10621 redisplay_window (window, 1);
10622 return Qnil;
10623 }
10624 \f
10625
10626 /* Increment GLYPH until it reaches END or CONDITION fails while
10627 adding (GLYPH)->pixel_width to X. */
10628
10629 #define SKIP_GLYPHS(glyph, end, x, condition) \
10630 do \
10631 { \
10632 (x) += (glyph)->pixel_width; \
10633 ++(glyph); \
10634 } \
10635 while ((glyph) < (end) && (condition))
10636
10637
10638 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10639 DELTA is the number of bytes by which positions recorded in ROW
10640 differ from current buffer positions. */
10641
10642 void
10643 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10644 struct window *w;
10645 struct glyph_row *row;
10646 struct glyph_matrix *matrix;
10647 int delta, delta_bytes, dy, dvpos;
10648 {
10649 struct glyph *glyph = row->glyphs[TEXT_AREA];
10650 struct glyph *end = glyph + row->used[TEXT_AREA];
10651 struct glyph *cursor = NULL;
10652 /* The first glyph that starts a sequence of glyphs from string. */
10653 struct glyph *string_start;
10654 /* The X coordinate of string_start. */
10655 int string_start_x;
10656 /* The last known character position. */
10657 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10658 /* The last known character position before string_start. */
10659 int string_before_pos;
10660 int x = row->x;
10661 int cursor_x = x;
10662 int cursor_from_overlay_pos = 0;
10663 int pt_old = PT - delta;
10664
10665 /* Skip over glyphs not having an object at the start of the row.
10666 These are special glyphs like truncation marks on terminal
10667 frames. */
10668 if (row->displays_text_p)
10669 while (glyph < end
10670 && INTEGERP (glyph->object)
10671 && glyph->charpos < 0)
10672 {
10673 x += glyph->pixel_width;
10674 ++glyph;
10675 }
10676
10677 string_start = NULL;
10678 while (glyph < end
10679 && !INTEGERP (glyph->object)
10680 && (!BUFFERP (glyph->object)
10681 || (last_pos = glyph->charpos) < pt_old))
10682 {
10683 if (! STRINGP (glyph->object))
10684 {
10685 string_start = NULL;
10686 x += glyph->pixel_width;
10687 ++glyph;
10688 if (cursor_from_overlay_pos
10689 && last_pos > cursor_from_overlay_pos)
10690 {
10691 cursor_from_overlay_pos = 0;
10692 cursor = 0;
10693 }
10694 }
10695 else
10696 {
10697 string_before_pos = last_pos;
10698 string_start = glyph;
10699 string_start_x = x;
10700 /* Skip all glyphs from string. */
10701 do
10702 {
10703 int pos;
10704 if ((cursor == NULL || glyph > cursor)
10705 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10706 Qcursor, (glyph)->object))
10707 && (pos = string_buffer_position (w, glyph->object,
10708 string_before_pos),
10709 (pos == 0 /* From overlay */
10710 || pos == pt_old)))
10711 {
10712 /* Estimate overlay buffer position from the buffer
10713 positions of the glyphs before and after the overlay.
10714 Add 1 to last_pos so that if point corresponds to the
10715 glyph right after the overlay, we still use a 'cursor'
10716 property found in that overlay. */
10717 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10718 cursor = glyph;
10719 cursor_x = x;
10720 }
10721 x += glyph->pixel_width;
10722 ++glyph;
10723 }
10724 while (glyph < end && STRINGP (glyph->object));
10725 }
10726 }
10727
10728 if (cursor != NULL)
10729 {
10730 glyph = cursor;
10731 x = cursor_x;
10732 }
10733 else if (string_start
10734 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10735 {
10736 /* We may have skipped over point because the previous glyphs
10737 are from string. As there's no easy way to know the
10738 character position of the current glyph, find the correct
10739 glyph on point by scanning from string_start again. */
10740 Lisp_Object limit;
10741 Lisp_Object string;
10742 int pos;
10743
10744 limit = make_number (pt_old + 1);
10745 end = glyph;
10746 glyph = string_start;
10747 x = string_start_x;
10748 string = glyph->object;
10749 pos = string_buffer_position (w, string, string_before_pos);
10750 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10751 because we always put cursor after overlay strings. */
10752 while (pos == 0 && glyph < end)
10753 {
10754 string = glyph->object;
10755 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10756 if (glyph < end)
10757 pos = string_buffer_position (w, glyph->object, string_before_pos);
10758 }
10759
10760 while (glyph < end)
10761 {
10762 pos = XINT (Fnext_single_char_property_change
10763 (make_number (pos), Qdisplay, Qnil, limit));
10764 if (pos > pt_old)
10765 break;
10766 /* Skip glyphs from the same string. */
10767 string = glyph->object;
10768 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10769 /* Skip glyphs from an overlay. */
10770 while (glyph < end
10771 && ! string_buffer_position (w, glyph->object, pos))
10772 {
10773 string = glyph->object;
10774 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10775 }
10776 }
10777 }
10778
10779 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10780 w->cursor.x = x;
10781 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10782 w->cursor.y = row->y + dy;
10783
10784 if (w == XWINDOW (selected_window))
10785 {
10786 if (!row->continued_p
10787 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10788 && row->x == 0)
10789 {
10790 this_line_buffer = XBUFFER (w->buffer);
10791
10792 CHARPOS (this_line_start_pos)
10793 = MATRIX_ROW_START_CHARPOS (row) + delta;
10794 BYTEPOS (this_line_start_pos)
10795 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10796
10797 CHARPOS (this_line_end_pos)
10798 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10799 BYTEPOS (this_line_end_pos)
10800 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10801
10802 this_line_y = w->cursor.y;
10803 this_line_pixel_height = row->height;
10804 this_line_vpos = w->cursor.vpos;
10805 this_line_start_x = row->x;
10806 }
10807 else
10808 CHARPOS (this_line_start_pos) = 0;
10809 }
10810 }
10811
10812
10813 /* Run window scroll functions, if any, for WINDOW with new window
10814 start STARTP. Sets the window start of WINDOW to that position.
10815
10816 We assume that the window's buffer is really current. */
10817
10818 static INLINE struct text_pos
10819 run_window_scroll_functions (window, startp)
10820 Lisp_Object window;
10821 struct text_pos startp;
10822 {
10823 struct window *w = XWINDOW (window);
10824 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10825
10826 if (current_buffer != XBUFFER (w->buffer))
10827 abort ();
10828
10829 if (!NILP (Vwindow_scroll_functions))
10830 {
10831 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10832 make_number (CHARPOS (startp)));
10833 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10834 /* In case the hook functions switch buffers. */
10835 if (current_buffer != XBUFFER (w->buffer))
10836 set_buffer_internal_1 (XBUFFER (w->buffer));
10837 }
10838
10839 return startp;
10840 }
10841
10842
10843 /* Make sure the line containing the cursor is fully visible.
10844 A value of 1 means there is nothing to be done.
10845 (Either the line is fully visible, or it cannot be made so,
10846 or we cannot tell.)
10847
10848 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10849 is higher than window.
10850
10851 A value of 0 means the caller should do scrolling
10852 as if point had gone off the screen. */
10853
10854 static int
10855 make_cursor_line_fully_visible (w, force_p)
10856 struct window *w;
10857 int force_p;
10858 {
10859 struct glyph_matrix *matrix;
10860 struct glyph_row *row;
10861 int window_height;
10862
10863 /* It's not always possible to find the cursor, e.g, when a window
10864 is full of overlay strings. Don't do anything in that case. */
10865 if (w->cursor.vpos < 0)
10866 return 1;
10867
10868 matrix = w->desired_matrix;
10869 row = MATRIX_ROW (matrix, w->cursor.vpos);
10870
10871 /* If the cursor row is not partially visible, there's nothing to do. */
10872 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10873 return 1;
10874
10875 /* If the row the cursor is in is taller than the window's height,
10876 it's not clear what to do, so do nothing. */
10877 window_height = window_box_height (w);
10878 if (row->height >= window_height)
10879 {
10880 if (!force_p || w->vscroll)
10881 return 1;
10882 }
10883 return 0;
10884
10885 #if 0
10886 /* This code used to try to scroll the window just enough to make
10887 the line visible. It returned 0 to say that the caller should
10888 allocate larger glyph matrices. */
10889
10890 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10891 {
10892 int dy = row->height - row->visible_height;
10893 w->vscroll = 0;
10894 w->cursor.y += dy;
10895 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10896 }
10897 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10898 {
10899 int dy = - (row->height - row->visible_height);
10900 w->vscroll = dy;
10901 w->cursor.y += dy;
10902 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10903 }
10904
10905 /* When we change the cursor y-position of the selected window,
10906 change this_line_y as well so that the display optimization for
10907 the cursor line of the selected window in redisplay_internal uses
10908 the correct y-position. */
10909 if (w == XWINDOW (selected_window))
10910 this_line_y = w->cursor.y;
10911
10912 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10913 redisplay with larger matrices. */
10914 if (matrix->nrows < required_matrix_height (w))
10915 {
10916 fonts_changed_p = 1;
10917 return 0;
10918 }
10919
10920 return 1;
10921 #endif /* 0 */
10922 }
10923
10924
10925 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10926 non-zero means only WINDOW is redisplayed in redisplay_internal.
10927 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10928 in redisplay_window to bring a partially visible line into view in
10929 the case that only the cursor has moved.
10930
10931 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10932 last screen line's vertical height extends past the end of the screen.
10933
10934 Value is
10935
10936 1 if scrolling succeeded
10937
10938 0 if scrolling didn't find point.
10939
10940 -1 if new fonts have been loaded so that we must interrupt
10941 redisplay, adjust glyph matrices, and try again. */
10942
10943 enum
10944 {
10945 SCROLLING_SUCCESS,
10946 SCROLLING_FAILED,
10947 SCROLLING_NEED_LARGER_MATRICES
10948 };
10949
10950 static int
10951 try_scrolling (window, just_this_one_p, scroll_conservatively,
10952 scroll_step, temp_scroll_step, last_line_misfit)
10953 Lisp_Object window;
10954 int just_this_one_p;
10955 EMACS_INT scroll_conservatively, scroll_step;
10956 int temp_scroll_step;
10957 int last_line_misfit;
10958 {
10959 struct window *w = XWINDOW (window);
10960 struct frame *f = XFRAME (w->frame);
10961 struct text_pos scroll_margin_pos;
10962 struct text_pos pos;
10963 struct text_pos startp;
10964 struct it it;
10965 Lisp_Object window_end;
10966 int this_scroll_margin;
10967 int dy = 0;
10968 int scroll_max;
10969 int rc;
10970 int amount_to_scroll = 0;
10971 Lisp_Object aggressive;
10972 int height;
10973 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10974
10975 #if GLYPH_DEBUG
10976 debug_method_add (w, "try_scrolling");
10977 #endif
10978
10979 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10980
10981 /* Compute scroll margin height in pixels. We scroll when point is
10982 within this distance from the top or bottom of the window. */
10983 if (scroll_margin > 0)
10984 {
10985 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10986 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10987 }
10988 else
10989 this_scroll_margin = 0;
10990
10991 /* Force scroll_conservatively to have a reasonable value so it doesn't
10992 cause an overflow while computing how much to scroll. */
10993 if (scroll_conservatively)
10994 scroll_conservatively = min (scroll_conservatively,
10995 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
10996
10997 /* Compute how much we should try to scroll maximally to bring point
10998 into view. */
10999 if (scroll_step || scroll_conservatively || temp_scroll_step)
11000 scroll_max = max (scroll_step,
11001 max (scroll_conservatively, temp_scroll_step));
11002 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11003 || NUMBERP (current_buffer->scroll_up_aggressively))
11004 /* We're trying to scroll because of aggressive scrolling
11005 but no scroll_step is set. Choose an arbitrary one. Maybe
11006 there should be a variable for this. */
11007 scroll_max = 10;
11008 else
11009 scroll_max = 0;
11010 scroll_max *= FRAME_LINE_HEIGHT (f);
11011
11012 /* Decide whether we have to scroll down. Start at the window end
11013 and move this_scroll_margin up to find the position of the scroll
11014 margin. */
11015 window_end = Fwindow_end (window, Qt);
11016
11017 too_near_end:
11018
11019 CHARPOS (scroll_margin_pos) = XINT (window_end);
11020 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11021
11022 if (this_scroll_margin || extra_scroll_margin_lines)
11023 {
11024 start_display (&it, w, scroll_margin_pos);
11025 if (this_scroll_margin)
11026 move_it_vertically (&it, - this_scroll_margin);
11027 if (extra_scroll_margin_lines)
11028 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11029 scroll_margin_pos = it.current.pos;
11030 }
11031
11032 if (PT >= CHARPOS (scroll_margin_pos))
11033 {
11034 int y0;
11035
11036 /* Point is in the scroll margin at the bottom of the window, or
11037 below. Compute a new window start that makes point visible. */
11038
11039 /* Compute the distance from the scroll margin to PT.
11040 Give up if the distance is greater than scroll_max. */
11041 start_display (&it, w, scroll_margin_pos);
11042 y0 = it.current_y;
11043 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11044 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11045
11046 /* To make point visible, we have to move the window start
11047 down so that the line the cursor is in is visible, which
11048 means we have to add in the height of the cursor line. */
11049 dy = line_bottom_y (&it) - y0;
11050
11051 if (dy > scroll_max)
11052 return SCROLLING_FAILED;
11053
11054 /* Move the window start down. If scrolling conservatively,
11055 move it just enough down to make point visible. If
11056 scroll_step is set, move it down by scroll_step. */
11057 start_display (&it, w, startp);
11058
11059 if (scroll_conservatively)
11060 /* Set AMOUNT_TO_SCROLL to at least one line,
11061 and at most scroll_conservatively lines. */
11062 amount_to_scroll
11063 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11064 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11065 else if (scroll_step || temp_scroll_step)
11066 amount_to_scroll = scroll_max;
11067 else
11068 {
11069 aggressive = current_buffer->scroll_up_aggressively;
11070 height = WINDOW_BOX_TEXT_HEIGHT (w);
11071 if (NUMBERP (aggressive))
11072 {
11073 double float_amount = XFLOATINT (aggressive) * height;
11074 amount_to_scroll = float_amount;
11075 if (amount_to_scroll == 0 && float_amount > 0)
11076 amount_to_scroll = 1;
11077 }
11078 }
11079
11080 if (amount_to_scroll <= 0)
11081 return SCROLLING_FAILED;
11082
11083 /* If moving by amount_to_scroll leaves STARTP unchanged,
11084 move it down one screen line. */
11085
11086 move_it_vertically (&it, amount_to_scroll);
11087 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11088 move_it_by_lines (&it, 1, 1);
11089 startp = it.current.pos;
11090 }
11091 else
11092 {
11093 /* See if point is inside the scroll margin at the top of the
11094 window. */
11095 scroll_margin_pos = startp;
11096 if (this_scroll_margin)
11097 {
11098 start_display (&it, w, startp);
11099 move_it_vertically (&it, this_scroll_margin);
11100 scroll_margin_pos = it.current.pos;
11101 }
11102
11103 if (PT < CHARPOS (scroll_margin_pos))
11104 {
11105 /* Point is in the scroll margin at the top of the window or
11106 above what is displayed in the window. */
11107 int y0;
11108
11109 /* Compute the vertical distance from PT to the scroll
11110 margin position. Give up if distance is greater than
11111 scroll_max. */
11112 SET_TEXT_POS (pos, PT, PT_BYTE);
11113 start_display (&it, w, pos);
11114 y0 = it.current_y;
11115 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11116 it.last_visible_y, -1,
11117 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11118 dy = it.current_y - y0;
11119 if (dy > scroll_max)
11120 return SCROLLING_FAILED;
11121
11122 /* Compute new window start. */
11123 start_display (&it, w, startp);
11124
11125 if (scroll_conservatively)
11126 amount_to_scroll
11127 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11128 else if (scroll_step || temp_scroll_step)
11129 amount_to_scroll = scroll_max;
11130 else
11131 {
11132 aggressive = current_buffer->scroll_down_aggressively;
11133 height = WINDOW_BOX_TEXT_HEIGHT (w);
11134 if (NUMBERP (aggressive))
11135 {
11136 double float_amount = XFLOATINT (aggressive) * height;
11137 amount_to_scroll = float_amount;
11138 if (amount_to_scroll == 0 && float_amount > 0)
11139 amount_to_scroll = 1;
11140 }
11141 }
11142
11143 if (amount_to_scroll <= 0)
11144 return SCROLLING_FAILED;
11145
11146 move_it_vertically (&it, - amount_to_scroll);
11147 startp = it.current.pos;
11148 }
11149 }
11150
11151 /* Run window scroll functions. */
11152 startp = run_window_scroll_functions (window, startp);
11153
11154 /* Display the window. Give up if new fonts are loaded, or if point
11155 doesn't appear. */
11156 if (!try_window (window, startp))
11157 rc = SCROLLING_NEED_LARGER_MATRICES;
11158 else if (w->cursor.vpos < 0)
11159 {
11160 clear_glyph_matrix (w->desired_matrix);
11161 rc = SCROLLING_FAILED;
11162 }
11163 else
11164 {
11165 /* Maybe forget recorded base line for line number display. */
11166 if (!just_this_one_p
11167 || current_buffer->clip_changed
11168 || BEG_UNCHANGED < CHARPOS (startp))
11169 w->base_line_number = Qnil;
11170
11171 /* If cursor ends up on a partially visible line,
11172 treat that as being off the bottom of the screen. */
11173 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11174 {
11175 clear_glyph_matrix (w->desired_matrix);
11176 ++extra_scroll_margin_lines;
11177 goto too_near_end;
11178 }
11179 rc = SCROLLING_SUCCESS;
11180 }
11181
11182 return rc;
11183 }
11184
11185
11186 /* Compute a suitable window start for window W if display of W starts
11187 on a continuation line. Value is non-zero if a new window start
11188 was computed.
11189
11190 The new window start will be computed, based on W's width, starting
11191 from the start of the continued line. It is the start of the
11192 screen line with the minimum distance from the old start W->start. */
11193
11194 static int
11195 compute_window_start_on_continuation_line (w)
11196 struct window *w;
11197 {
11198 struct text_pos pos, start_pos;
11199 int window_start_changed_p = 0;
11200
11201 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11202
11203 /* If window start is on a continuation line... Window start may be
11204 < BEGV in case there's invisible text at the start of the
11205 buffer (M-x rmail, for example). */
11206 if (CHARPOS (start_pos) > BEGV
11207 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11208 {
11209 struct it it;
11210 struct glyph_row *row;
11211
11212 /* Handle the case that the window start is out of range. */
11213 if (CHARPOS (start_pos) < BEGV)
11214 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11215 else if (CHARPOS (start_pos) > ZV)
11216 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11217
11218 /* Find the start of the continued line. This should be fast
11219 because scan_buffer is fast (newline cache). */
11220 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11221 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11222 row, DEFAULT_FACE_ID);
11223 reseat_at_previous_visible_line_start (&it);
11224
11225 /* If the line start is "too far" away from the window start,
11226 say it takes too much time to compute a new window start. */
11227 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11228 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11229 {
11230 int min_distance, distance;
11231
11232 /* Move forward by display lines to find the new window
11233 start. If window width was enlarged, the new start can
11234 be expected to be > the old start. If window width was
11235 decreased, the new window start will be < the old start.
11236 So, we're looking for the display line start with the
11237 minimum distance from the old window start. */
11238 pos = it.current.pos;
11239 min_distance = INFINITY;
11240 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11241 distance < min_distance)
11242 {
11243 min_distance = distance;
11244 pos = it.current.pos;
11245 move_it_by_lines (&it, 1, 0);
11246 }
11247
11248 /* Set the window start there. */
11249 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11250 window_start_changed_p = 1;
11251 }
11252 }
11253
11254 return window_start_changed_p;
11255 }
11256
11257
11258 /* Try cursor movement in case text has not changed in window WINDOW,
11259 with window start STARTP. Value is
11260
11261 CURSOR_MOVEMENT_SUCCESS if successful
11262
11263 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11264
11265 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11266 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11267 we want to scroll as if scroll-step were set to 1. See the code.
11268
11269 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11270 which case we have to abort this redisplay, and adjust matrices
11271 first. */
11272
11273 enum
11274 {
11275 CURSOR_MOVEMENT_SUCCESS,
11276 CURSOR_MOVEMENT_CANNOT_BE_USED,
11277 CURSOR_MOVEMENT_MUST_SCROLL,
11278 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11279 };
11280
11281 static int
11282 try_cursor_movement (window, startp, scroll_step)
11283 Lisp_Object window;
11284 struct text_pos startp;
11285 int *scroll_step;
11286 {
11287 struct window *w = XWINDOW (window);
11288 struct frame *f = XFRAME (w->frame);
11289 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11290
11291 #if GLYPH_DEBUG
11292 if (inhibit_try_cursor_movement)
11293 return rc;
11294 #endif
11295
11296 /* Handle case where text has not changed, only point, and it has
11297 not moved off the frame. */
11298 if (/* Point may be in this window. */
11299 PT >= CHARPOS (startp)
11300 /* Selective display hasn't changed. */
11301 && !current_buffer->clip_changed
11302 /* Function force-mode-line-update is used to force a thorough
11303 redisplay. It sets either windows_or_buffers_changed or
11304 update_mode_lines. So don't take a shortcut here for these
11305 cases. */
11306 && !update_mode_lines
11307 && !windows_or_buffers_changed
11308 && !cursor_type_changed
11309 /* Can't use this case if highlighting a region. When a
11310 region exists, cursor movement has to do more than just
11311 set the cursor. */
11312 && !(!NILP (Vtransient_mark_mode)
11313 && !NILP (current_buffer->mark_active))
11314 && NILP (w->region_showing)
11315 && NILP (Vshow_trailing_whitespace)
11316 /* Right after splitting windows, last_point may be nil. */
11317 && INTEGERP (w->last_point)
11318 /* This code is not used for mini-buffer for the sake of the case
11319 of redisplaying to replace an echo area message; since in
11320 that case the mini-buffer contents per se are usually
11321 unchanged. This code is of no real use in the mini-buffer
11322 since the handling of this_line_start_pos, etc., in redisplay
11323 handles the same cases. */
11324 && !EQ (window, minibuf_window)
11325 /* When splitting windows or for new windows, it happens that
11326 redisplay is called with a nil window_end_vpos or one being
11327 larger than the window. This should really be fixed in
11328 window.c. I don't have this on my list, now, so we do
11329 approximately the same as the old redisplay code. --gerd. */
11330 && INTEGERP (w->window_end_vpos)
11331 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11332 && (FRAME_WINDOW_P (f)
11333 || !overlay_arrow_in_current_buffer_p ()))
11334 {
11335 int this_scroll_margin, top_scroll_margin;
11336 struct glyph_row *row = NULL;
11337
11338 #if GLYPH_DEBUG
11339 debug_method_add (w, "cursor movement");
11340 #endif
11341
11342 /* Scroll if point within this distance from the top or bottom
11343 of the window. This is a pixel value. */
11344 this_scroll_margin = max (0, scroll_margin);
11345 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11346 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11347
11348 top_scroll_margin = this_scroll_margin;
11349 if (WINDOW_WANTS_HEADER_LINE_P (w))
11350 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11351
11352 /* Start with the row the cursor was displayed during the last
11353 not paused redisplay. Give up if that row is not valid. */
11354 if (w->last_cursor.vpos < 0
11355 || w->last_cursor.vpos >= w->current_matrix->nrows)
11356 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11357 else
11358 {
11359 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11360 if (row->mode_line_p)
11361 ++row;
11362 if (!row->enabled_p)
11363 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11364 }
11365
11366 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11367 {
11368 int scroll_p = 0;
11369 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11370
11371 if (PT > XFASTINT (w->last_point))
11372 {
11373 /* Point has moved forward. */
11374 while (MATRIX_ROW_END_CHARPOS (row) < PT
11375 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11376 {
11377 xassert (row->enabled_p);
11378 ++row;
11379 }
11380
11381 /* The end position of a row equals the start position
11382 of the next row. If PT is there, we would rather
11383 display it in the next line. */
11384 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11385 && MATRIX_ROW_END_CHARPOS (row) == PT
11386 && !cursor_row_p (w, row))
11387 ++row;
11388
11389 /* If within the scroll margin, scroll. Note that
11390 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11391 the next line would be drawn, and that
11392 this_scroll_margin can be zero. */
11393 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11394 || PT > MATRIX_ROW_END_CHARPOS (row)
11395 /* Line is completely visible last line in window
11396 and PT is to be set in the next line. */
11397 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11398 && PT == MATRIX_ROW_END_CHARPOS (row)
11399 && !row->ends_at_zv_p
11400 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11401 scroll_p = 1;
11402 }
11403 else if (PT < XFASTINT (w->last_point))
11404 {
11405 /* Cursor has to be moved backward. Note that PT >=
11406 CHARPOS (startp) because of the outer if-statement. */
11407 while (!row->mode_line_p
11408 && (MATRIX_ROW_START_CHARPOS (row) > PT
11409 || (MATRIX_ROW_START_CHARPOS (row) == PT
11410 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11411 && (row->y > top_scroll_margin
11412 || CHARPOS (startp) == BEGV))
11413 {
11414 xassert (row->enabled_p);
11415 --row;
11416 }
11417
11418 /* Consider the following case: Window starts at BEGV,
11419 there is invisible, intangible text at BEGV, so that
11420 display starts at some point START > BEGV. It can
11421 happen that we are called with PT somewhere between
11422 BEGV and START. Try to handle that case. */
11423 if (row < w->current_matrix->rows
11424 || row->mode_line_p)
11425 {
11426 row = w->current_matrix->rows;
11427 if (row->mode_line_p)
11428 ++row;
11429 }
11430
11431 /* Due to newlines in overlay strings, we may have to
11432 skip forward over overlay strings. */
11433 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11434 && MATRIX_ROW_END_CHARPOS (row) == PT
11435 && !cursor_row_p (w, row))
11436 ++row;
11437
11438 /* If within the scroll margin, scroll. */
11439 if (row->y < top_scroll_margin
11440 && CHARPOS (startp) != BEGV)
11441 scroll_p = 1;
11442 }
11443
11444 if (PT < MATRIX_ROW_START_CHARPOS (row)
11445 || PT > MATRIX_ROW_END_CHARPOS (row))
11446 {
11447 /* if PT is not in the glyph row, give up. */
11448 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11449 }
11450 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11451 {
11452 if (PT == MATRIX_ROW_END_CHARPOS (row)
11453 && !row->ends_at_zv_p
11454 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11455 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11456 else if (row->height > window_box_height (w))
11457 {
11458 /* If we end up in a partially visible line, let's
11459 make it fully visible, except when it's taller
11460 than the window, in which case we can't do much
11461 about it. */
11462 *scroll_step = 1;
11463 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11464 }
11465 else
11466 {
11467 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11468 if (!make_cursor_line_fully_visible (w, 0))
11469 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11470 else
11471 rc = CURSOR_MOVEMENT_SUCCESS;
11472 }
11473 }
11474 else if (scroll_p)
11475 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11476 else
11477 {
11478 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11479 rc = CURSOR_MOVEMENT_SUCCESS;
11480 }
11481 }
11482 }
11483
11484 return rc;
11485 }
11486
11487 void
11488 set_vertical_scroll_bar (w)
11489 struct window *w;
11490 {
11491 int start, end, whole;
11492
11493 /* Calculate the start and end positions for the current window.
11494 At some point, it would be nice to choose between scrollbars
11495 which reflect the whole buffer size, with special markers
11496 indicating narrowing, and scrollbars which reflect only the
11497 visible region.
11498
11499 Note that mini-buffers sometimes aren't displaying any text. */
11500 if (!MINI_WINDOW_P (w)
11501 || (w == XWINDOW (minibuf_window)
11502 && NILP (echo_area_buffer[0])))
11503 {
11504 struct buffer *buf = XBUFFER (w->buffer);
11505 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11506 start = marker_position (w->start) - BUF_BEGV (buf);
11507 /* I don't think this is guaranteed to be right. For the
11508 moment, we'll pretend it is. */
11509 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11510
11511 if (end < start)
11512 end = start;
11513 if (whole < (end - start))
11514 whole = end - start;
11515 }
11516 else
11517 start = end = whole = 0;
11518
11519 /* Indicate what this scroll bar ought to be displaying now. */
11520 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11521 }
11522
11523
11524 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11525 selected_window is redisplayed.
11526
11527 We can return without actually redisplaying the window if
11528 fonts_changed_p is nonzero. In that case, redisplay_internal will
11529 retry. */
11530
11531 static void
11532 redisplay_window (window, just_this_one_p)
11533 Lisp_Object window;
11534 int just_this_one_p;
11535 {
11536 struct window *w = XWINDOW (window);
11537 struct frame *f = XFRAME (w->frame);
11538 struct buffer *buffer = XBUFFER (w->buffer);
11539 struct buffer *old = current_buffer;
11540 struct text_pos lpoint, opoint, startp;
11541 int update_mode_line;
11542 int tem;
11543 struct it it;
11544 /* Record it now because it's overwritten. */
11545 int current_matrix_up_to_date_p = 0;
11546 int used_current_matrix_p = 0;
11547 /* This is less strict than current_matrix_up_to_date_p.
11548 It indictes that the buffer contents and narrowing are unchanged. */
11549 int buffer_unchanged_p = 0;
11550 int temp_scroll_step = 0;
11551 int count = SPECPDL_INDEX ();
11552 int rc;
11553 int centering_position;
11554 int last_line_misfit = 0;
11555
11556 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11557 opoint = lpoint;
11558
11559 /* W must be a leaf window here. */
11560 xassert (!NILP (w->buffer));
11561 #if GLYPH_DEBUG
11562 *w->desired_matrix->method = 0;
11563 #endif
11564
11565 specbind (Qinhibit_point_motion_hooks, Qt);
11566
11567 reconsider_clip_changes (w, buffer);
11568
11569 /* Has the mode line to be updated? */
11570 update_mode_line = (!NILP (w->update_mode_line)
11571 || update_mode_lines
11572 || buffer->clip_changed
11573 || buffer->prevent_redisplay_optimizations_p);
11574
11575 if (MINI_WINDOW_P (w))
11576 {
11577 if (w == XWINDOW (echo_area_window)
11578 && !NILP (echo_area_buffer[0]))
11579 {
11580 if (update_mode_line)
11581 /* We may have to update a tty frame's menu bar or a
11582 tool-bar. Example `M-x C-h C-h C-g'. */
11583 goto finish_menu_bars;
11584 else
11585 /* We've already displayed the echo area glyphs in this window. */
11586 goto finish_scroll_bars;
11587 }
11588 else if ((w != XWINDOW (minibuf_window)
11589 || minibuf_level == 0)
11590 /* When buffer is nonempty, redisplay window normally. */
11591 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11592 /* Quail displays non-mini buffers in minibuffer window.
11593 In that case, redisplay the window normally. */
11594 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11595 {
11596 /* W is a mini-buffer window, but it's not active, so clear
11597 it. */
11598 int yb = window_text_bottom_y (w);
11599 struct glyph_row *row;
11600 int y;
11601
11602 for (y = 0, row = w->desired_matrix->rows;
11603 y < yb;
11604 y += row->height, ++row)
11605 blank_row (w, row, y);
11606 goto finish_scroll_bars;
11607 }
11608
11609 clear_glyph_matrix (w->desired_matrix);
11610 }
11611
11612 /* Otherwise set up data on this window; select its buffer and point
11613 value. */
11614 /* Really select the buffer, for the sake of buffer-local
11615 variables. */
11616 set_buffer_internal_1 (XBUFFER (w->buffer));
11617 SET_TEXT_POS (opoint, PT, PT_BYTE);
11618
11619 current_matrix_up_to_date_p
11620 = (!NILP (w->window_end_valid)
11621 && !current_buffer->clip_changed
11622 && !current_buffer->prevent_redisplay_optimizations_p
11623 && XFASTINT (w->last_modified) >= MODIFF
11624 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11625
11626 buffer_unchanged_p
11627 = (!NILP (w->window_end_valid)
11628 && !current_buffer->clip_changed
11629 && XFASTINT (w->last_modified) >= MODIFF
11630 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11631
11632 /* When windows_or_buffers_changed is non-zero, we can't rely on
11633 the window end being valid, so set it to nil there. */
11634 if (windows_or_buffers_changed)
11635 {
11636 /* If window starts on a continuation line, maybe adjust the
11637 window start in case the window's width changed. */
11638 if (XMARKER (w->start)->buffer == current_buffer)
11639 compute_window_start_on_continuation_line (w);
11640
11641 w->window_end_valid = Qnil;
11642 }
11643
11644 /* Some sanity checks. */
11645 CHECK_WINDOW_END (w);
11646 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11647 abort ();
11648 if (BYTEPOS (opoint) < CHARPOS (opoint))
11649 abort ();
11650
11651 /* If %c is in mode line, update it if needed. */
11652 if (!NILP (w->column_number_displayed)
11653 /* This alternative quickly identifies a common case
11654 where no change is needed. */
11655 && !(PT == XFASTINT (w->last_point)
11656 && XFASTINT (w->last_modified) >= MODIFF
11657 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11658 && (XFASTINT (w->column_number_displayed)
11659 != (int) current_column ())) /* iftc */
11660 update_mode_line = 1;
11661
11662 /* Count number of windows showing the selected buffer. An indirect
11663 buffer counts as its base buffer. */
11664 if (!just_this_one_p)
11665 {
11666 struct buffer *current_base, *window_base;
11667 current_base = current_buffer;
11668 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11669 if (current_base->base_buffer)
11670 current_base = current_base->base_buffer;
11671 if (window_base->base_buffer)
11672 window_base = window_base->base_buffer;
11673 if (current_base == window_base)
11674 buffer_shared++;
11675 }
11676
11677 /* Point refers normally to the selected window. For any other
11678 window, set up appropriate value. */
11679 if (!EQ (window, selected_window))
11680 {
11681 int new_pt = XMARKER (w->pointm)->charpos;
11682 int new_pt_byte = marker_byte_position (w->pointm);
11683 if (new_pt < BEGV)
11684 {
11685 new_pt = BEGV;
11686 new_pt_byte = BEGV_BYTE;
11687 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11688 }
11689 else if (new_pt > (ZV - 1))
11690 {
11691 new_pt = ZV;
11692 new_pt_byte = ZV_BYTE;
11693 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11694 }
11695
11696 /* We don't use SET_PT so that the point-motion hooks don't run. */
11697 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11698 }
11699
11700 /* If any of the character widths specified in the display table
11701 have changed, invalidate the width run cache. It's true that
11702 this may be a bit late to catch such changes, but the rest of
11703 redisplay goes (non-fatally) haywire when the display table is
11704 changed, so why should we worry about doing any better? */
11705 if (current_buffer->width_run_cache)
11706 {
11707 struct Lisp_Char_Table *disptab = buffer_display_table ();
11708
11709 if (! disptab_matches_widthtab (disptab,
11710 XVECTOR (current_buffer->width_table)))
11711 {
11712 invalidate_region_cache (current_buffer,
11713 current_buffer->width_run_cache,
11714 BEG, Z);
11715 recompute_width_table (current_buffer, disptab);
11716 }
11717 }
11718
11719 /* If window-start is screwed up, choose a new one. */
11720 if (XMARKER (w->start)->buffer != current_buffer)
11721 goto recenter;
11722
11723 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11724
11725 /* If someone specified a new starting point but did not insist,
11726 check whether it can be used. */
11727 if (!NILP (w->optional_new_start)
11728 && CHARPOS (startp) >= BEGV
11729 && CHARPOS (startp) <= ZV)
11730 {
11731 w->optional_new_start = Qnil;
11732 start_display (&it, w, startp);
11733 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11734 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11735 if (IT_CHARPOS (it) == PT)
11736 w->force_start = Qt;
11737 /* IT may overshoot PT if text at PT is invisible. */
11738 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11739 w->force_start = Qt;
11740
11741
11742 }
11743
11744 /* Handle case where place to start displaying has been specified,
11745 unless the specified location is outside the accessible range. */
11746 if (!NILP (w->force_start)
11747 || w->frozen_window_start_p)
11748 {
11749 /* We set this later on if we have to adjust point. */
11750 int new_vpos = -1;
11751
11752 w->force_start = Qnil;
11753 w->vscroll = 0;
11754 w->window_end_valid = Qnil;
11755
11756 /* Forget any recorded base line for line number display. */
11757 if (!buffer_unchanged_p)
11758 w->base_line_number = Qnil;
11759
11760 /* Redisplay the mode line. Select the buffer properly for that.
11761 Also, run the hook window-scroll-functions
11762 because we have scrolled. */
11763 /* Note, we do this after clearing force_start because
11764 if there's an error, it is better to forget about force_start
11765 than to get into an infinite loop calling the hook functions
11766 and having them get more errors. */
11767 if (!update_mode_line
11768 || ! NILP (Vwindow_scroll_functions))
11769 {
11770 update_mode_line = 1;
11771 w->update_mode_line = Qt;
11772 startp = run_window_scroll_functions (window, startp);
11773 }
11774
11775 w->last_modified = make_number (0);
11776 w->last_overlay_modified = make_number (0);
11777 if (CHARPOS (startp) < BEGV)
11778 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11779 else if (CHARPOS (startp) > ZV)
11780 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11781
11782 /* Redisplay, then check if cursor has been set during the
11783 redisplay. Give up if new fonts were loaded. */
11784 if (!try_window (window, startp))
11785 {
11786 w->force_start = Qt;
11787 clear_glyph_matrix (w->desired_matrix);
11788 goto need_larger_matrices;
11789 }
11790
11791 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11792 {
11793 /* If point does not appear, try to move point so it does
11794 appear. The desired matrix has been built above, so we
11795 can use it here. */
11796 new_vpos = window_box_height (w) / 2;
11797 }
11798
11799 if (!make_cursor_line_fully_visible (w, 0))
11800 {
11801 /* Point does appear, but on a line partly visible at end of window.
11802 Move it back to a fully-visible line. */
11803 new_vpos = window_box_height (w);
11804 }
11805
11806 /* If we need to move point for either of the above reasons,
11807 now actually do it. */
11808 if (new_vpos >= 0)
11809 {
11810 struct glyph_row *row;
11811
11812 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11813 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11814 ++row;
11815
11816 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11817 MATRIX_ROW_START_BYTEPOS (row));
11818
11819 if (w != XWINDOW (selected_window))
11820 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11821 else if (current_buffer == old)
11822 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11823
11824 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11825
11826 /* If we are highlighting the region, then we just changed
11827 the region, so redisplay to show it. */
11828 if (!NILP (Vtransient_mark_mode)
11829 && !NILP (current_buffer->mark_active))
11830 {
11831 clear_glyph_matrix (w->desired_matrix);
11832 if (!try_window (window, startp))
11833 goto need_larger_matrices;
11834 }
11835 }
11836
11837 #if GLYPH_DEBUG
11838 debug_method_add (w, "forced window start");
11839 #endif
11840 goto done;
11841 }
11842
11843 /* Handle case where text has not changed, only point, and it has
11844 not moved off the frame, and we are not retrying after hscroll.
11845 (current_matrix_up_to_date_p is nonzero when retrying.) */
11846 if (current_matrix_up_to_date_p
11847 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11848 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11849 {
11850 switch (rc)
11851 {
11852 case CURSOR_MOVEMENT_SUCCESS:
11853 used_current_matrix_p = 1;
11854 goto done;
11855
11856 #if 0 /* try_cursor_movement never returns this value. */
11857 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11858 goto need_larger_matrices;
11859 #endif
11860
11861 case CURSOR_MOVEMENT_MUST_SCROLL:
11862 goto try_to_scroll;
11863
11864 default:
11865 abort ();
11866 }
11867 }
11868 /* If current starting point was originally the beginning of a line
11869 but no longer is, find a new starting point. */
11870 else if (!NILP (w->start_at_line_beg)
11871 && !(CHARPOS (startp) <= BEGV
11872 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11873 {
11874 #if GLYPH_DEBUG
11875 debug_method_add (w, "recenter 1");
11876 #endif
11877 goto recenter;
11878 }
11879
11880 /* Try scrolling with try_window_id. Value is > 0 if update has
11881 been done, it is -1 if we know that the same window start will
11882 not work. It is 0 if unsuccessful for some other reason. */
11883 else if ((tem = try_window_id (w)) != 0)
11884 {
11885 #if GLYPH_DEBUG
11886 debug_method_add (w, "try_window_id %d", tem);
11887 #endif
11888
11889 if (fonts_changed_p)
11890 goto need_larger_matrices;
11891 if (tem > 0)
11892 goto done;
11893
11894 /* Otherwise try_window_id has returned -1 which means that we
11895 don't want the alternative below this comment to execute. */
11896 }
11897 else if (CHARPOS (startp) >= BEGV
11898 && CHARPOS (startp) <= ZV
11899 && PT >= CHARPOS (startp)
11900 && (CHARPOS (startp) < ZV
11901 /* Avoid starting at end of buffer. */
11902 || CHARPOS (startp) == BEGV
11903 || (XFASTINT (w->last_modified) >= MODIFF
11904 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11905 {
11906 #if GLYPH_DEBUG
11907 debug_method_add (w, "same window start");
11908 #endif
11909
11910 /* Try to redisplay starting at same place as before.
11911 If point has not moved off frame, accept the results. */
11912 if (!current_matrix_up_to_date_p
11913 /* Don't use try_window_reusing_current_matrix in this case
11914 because a window scroll function can have changed the
11915 buffer. */
11916 || !NILP (Vwindow_scroll_functions)
11917 || MINI_WINDOW_P (w)
11918 || !(used_current_matrix_p
11919 = try_window_reusing_current_matrix (w)))
11920 {
11921 IF_DEBUG (debug_method_add (w, "1"));
11922 try_window (window, startp);
11923 }
11924
11925 if (fonts_changed_p)
11926 goto need_larger_matrices;
11927
11928 if (w->cursor.vpos >= 0)
11929 {
11930 if (!just_this_one_p
11931 || current_buffer->clip_changed
11932 || BEG_UNCHANGED < CHARPOS (startp))
11933 /* Forget any recorded base line for line number display. */
11934 w->base_line_number = Qnil;
11935
11936 if (!make_cursor_line_fully_visible (w, 1))
11937 {
11938 clear_glyph_matrix (w->desired_matrix);
11939 last_line_misfit = 1;
11940 }
11941 /* Drop through and scroll. */
11942 else
11943 goto done;
11944 }
11945 else
11946 clear_glyph_matrix (w->desired_matrix);
11947 }
11948
11949 try_to_scroll:
11950
11951 w->last_modified = make_number (0);
11952 w->last_overlay_modified = make_number (0);
11953
11954 /* Redisplay the mode line. Select the buffer properly for that. */
11955 if (!update_mode_line)
11956 {
11957 update_mode_line = 1;
11958 w->update_mode_line = Qt;
11959 }
11960
11961 /* Try to scroll by specified few lines. */
11962 if ((scroll_conservatively
11963 || scroll_step
11964 || temp_scroll_step
11965 || NUMBERP (current_buffer->scroll_up_aggressively)
11966 || NUMBERP (current_buffer->scroll_down_aggressively))
11967 && !current_buffer->clip_changed
11968 && CHARPOS (startp) >= BEGV
11969 && CHARPOS (startp) <= ZV)
11970 {
11971 /* The function returns -1 if new fonts were loaded, 1 if
11972 successful, 0 if not successful. */
11973 int rc = try_scrolling (window, just_this_one_p,
11974 scroll_conservatively,
11975 scroll_step,
11976 temp_scroll_step, last_line_misfit);
11977 switch (rc)
11978 {
11979 case SCROLLING_SUCCESS:
11980 goto done;
11981
11982 case SCROLLING_NEED_LARGER_MATRICES:
11983 goto need_larger_matrices;
11984
11985 case SCROLLING_FAILED:
11986 break;
11987
11988 default:
11989 abort ();
11990 }
11991 }
11992
11993 /* Finally, just choose place to start which centers point */
11994
11995 recenter:
11996 centering_position = window_box_height (w) / 2;
11997
11998 point_at_top:
11999 /* Jump here with centering_position already set to 0. */
12000
12001 #if GLYPH_DEBUG
12002 debug_method_add (w, "recenter");
12003 #endif
12004
12005 /* w->vscroll = 0; */
12006
12007 /* Forget any previously recorded base line for line number display. */
12008 if (!buffer_unchanged_p)
12009 w->base_line_number = Qnil;
12010
12011 /* Move backward half the height of the window. */
12012 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12013 it.current_y = it.last_visible_y;
12014 move_it_vertically_backward (&it, centering_position);
12015 xassert (IT_CHARPOS (it) >= BEGV);
12016
12017 /* The function move_it_vertically_backward may move over more
12018 than the specified y-distance. If it->w is small, e.g. a
12019 mini-buffer window, we may end up in front of the window's
12020 display area. Start displaying at the start of the line
12021 containing PT in this case. */
12022 if (it.current_y <= 0)
12023 {
12024 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12025 move_it_vertically (&it, 0);
12026 xassert (IT_CHARPOS (it) <= PT);
12027 it.current_y = 0;
12028 }
12029
12030 it.current_x = it.hpos = 0;
12031
12032 /* Set startp here explicitly in case that helps avoid an infinite loop
12033 in case the window-scroll-functions functions get errors. */
12034 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12035
12036 /* Run scroll hooks. */
12037 startp = run_window_scroll_functions (window, it.current.pos);
12038
12039 /* Redisplay the window. */
12040 if (!current_matrix_up_to_date_p
12041 || windows_or_buffers_changed
12042 || cursor_type_changed
12043 /* Don't use try_window_reusing_current_matrix in this case
12044 because it can have changed the buffer. */
12045 || !NILP (Vwindow_scroll_functions)
12046 || !just_this_one_p
12047 || MINI_WINDOW_P (w)
12048 || !(used_current_matrix_p
12049 = try_window_reusing_current_matrix (w)))
12050 try_window (window, startp);
12051
12052 /* If new fonts have been loaded (due to fontsets), give up. We
12053 have to start a new redisplay since we need to re-adjust glyph
12054 matrices. */
12055 if (fonts_changed_p)
12056 goto need_larger_matrices;
12057
12058 /* If cursor did not appear assume that the middle of the window is
12059 in the first line of the window. Do it again with the next line.
12060 (Imagine a window of height 100, displaying two lines of height
12061 60. Moving back 50 from it->last_visible_y will end in the first
12062 line.) */
12063 if (w->cursor.vpos < 0)
12064 {
12065 if (!NILP (w->window_end_valid)
12066 && PT >= Z - XFASTINT (w->window_end_pos))
12067 {
12068 clear_glyph_matrix (w->desired_matrix);
12069 move_it_by_lines (&it, 1, 0);
12070 try_window (window, it.current.pos);
12071 }
12072 else if (PT < IT_CHARPOS (it))
12073 {
12074 clear_glyph_matrix (w->desired_matrix);
12075 move_it_by_lines (&it, -1, 0);
12076 try_window (window, it.current.pos);
12077 }
12078 else
12079 {
12080 /* Not much we can do about it. */
12081 }
12082 }
12083
12084 /* Consider the following case: Window starts at BEGV, there is
12085 invisible, intangible text at BEGV, so that display starts at
12086 some point START > BEGV. It can happen that we are called with
12087 PT somewhere between BEGV and START. Try to handle that case. */
12088 if (w->cursor.vpos < 0)
12089 {
12090 struct glyph_row *row = w->current_matrix->rows;
12091 if (row->mode_line_p)
12092 ++row;
12093 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12094 }
12095
12096 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12097 {
12098 /* If vscroll is enabled, disable it and try again. */
12099 if (w->vscroll)
12100 {
12101 w->vscroll = 0;
12102 clear_glyph_matrix (w->desired_matrix);
12103 goto recenter;
12104 }
12105
12106 /* If centering point failed to make the whole line visible,
12107 put point at the top instead. That has to make the whole line
12108 visible, if it can be done. */
12109 clear_glyph_matrix (w->desired_matrix);
12110 centering_position = 0;
12111 goto point_at_top;
12112 }
12113
12114 done:
12115
12116 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12117 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12118 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12119 ? Qt : Qnil);
12120
12121 /* Display the mode line, if we must. */
12122 if ((update_mode_line
12123 /* If window not full width, must redo its mode line
12124 if (a) the window to its side is being redone and
12125 (b) we do a frame-based redisplay. This is a consequence
12126 of how inverted lines are drawn in frame-based redisplay. */
12127 || (!just_this_one_p
12128 && !FRAME_WINDOW_P (f)
12129 && !WINDOW_FULL_WIDTH_P (w))
12130 /* Line number to display. */
12131 || INTEGERP (w->base_line_pos)
12132 /* Column number is displayed and different from the one displayed. */
12133 || (!NILP (w->column_number_displayed)
12134 && (XFASTINT (w->column_number_displayed)
12135 != (int) current_column ()))) /* iftc */
12136 /* This means that the window has a mode line. */
12137 && (WINDOW_WANTS_MODELINE_P (w)
12138 || WINDOW_WANTS_HEADER_LINE_P (w)))
12139 {
12140 display_mode_lines (w);
12141
12142 /* If mode line height has changed, arrange for a thorough
12143 immediate redisplay using the correct mode line height. */
12144 if (WINDOW_WANTS_MODELINE_P (w)
12145 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12146 {
12147 fonts_changed_p = 1;
12148 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12149 = DESIRED_MODE_LINE_HEIGHT (w);
12150 }
12151
12152 /* If top line height has changed, arrange for a thorough
12153 immediate redisplay using the correct mode line height. */
12154 if (WINDOW_WANTS_HEADER_LINE_P (w)
12155 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12156 {
12157 fonts_changed_p = 1;
12158 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12159 = DESIRED_HEADER_LINE_HEIGHT (w);
12160 }
12161
12162 if (fonts_changed_p)
12163 goto need_larger_matrices;
12164 }
12165
12166 if (!line_number_displayed
12167 && !BUFFERP (w->base_line_pos))
12168 {
12169 w->base_line_pos = Qnil;
12170 w->base_line_number = Qnil;
12171 }
12172
12173 finish_menu_bars:
12174
12175 /* When we reach a frame's selected window, redo the frame's menu bar. */
12176 if (update_mode_line
12177 && EQ (FRAME_SELECTED_WINDOW (f), window))
12178 {
12179 int redisplay_menu_p = 0;
12180 int redisplay_tool_bar_p = 0;
12181
12182 if (FRAME_WINDOW_P (f))
12183 {
12184 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12185 || defined (USE_GTK)
12186 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12187 #else
12188 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12189 #endif
12190 }
12191 else
12192 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12193
12194 if (redisplay_menu_p)
12195 display_menu_bar (w);
12196
12197 #ifdef HAVE_WINDOW_SYSTEM
12198 #ifdef USE_GTK
12199 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12200 #else
12201 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12202 && (FRAME_TOOL_BAR_LINES (f) > 0
12203 || auto_resize_tool_bars_p);
12204
12205 #endif
12206
12207 if (redisplay_tool_bar_p)
12208 redisplay_tool_bar (f);
12209 #endif
12210 }
12211
12212 #ifdef HAVE_WINDOW_SYSTEM
12213 if (update_window_fringes (w, 0)
12214 && !just_this_one_p
12215 && (used_current_matrix_p || overlay_arrow_seen)
12216 && !w->pseudo_window_p)
12217 {
12218 update_begin (f);
12219 BLOCK_INPUT;
12220 draw_window_fringes (w);
12221 UNBLOCK_INPUT;
12222 update_end (f);
12223 }
12224 #endif /* HAVE_WINDOW_SYSTEM */
12225
12226 /* We go to this label, with fonts_changed_p nonzero,
12227 if it is necessary to try again using larger glyph matrices.
12228 We have to redeem the scroll bar even in this case,
12229 because the loop in redisplay_internal expects that. */
12230 need_larger_matrices:
12231 ;
12232 finish_scroll_bars:
12233
12234 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12235 {
12236 /* Set the thumb's position and size. */
12237 set_vertical_scroll_bar (w);
12238
12239 /* Note that we actually used the scroll bar attached to this
12240 window, so it shouldn't be deleted at the end of redisplay. */
12241 redeem_scroll_bar_hook (w);
12242 }
12243
12244 /* Restore current_buffer and value of point in it. */
12245 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12246 set_buffer_internal_1 (old);
12247 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12248
12249 unbind_to (count, Qnil);
12250 }
12251
12252
12253 /* Build the complete desired matrix of WINDOW with a window start
12254 buffer position POS. Value is non-zero if successful. It is zero
12255 if fonts were loaded during redisplay which makes re-adjusting
12256 glyph matrices necessary. */
12257
12258 int
12259 try_window (window, pos)
12260 Lisp_Object window;
12261 struct text_pos pos;
12262 {
12263 struct window *w = XWINDOW (window);
12264 struct it it;
12265 struct glyph_row *last_text_row = NULL;
12266
12267 /* Make POS the new window start. */
12268 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12269
12270 /* Mark cursor position as unknown. No overlay arrow seen. */
12271 w->cursor.vpos = -1;
12272 overlay_arrow_seen = 0;
12273
12274 /* Initialize iterator and info to start at POS. */
12275 start_display (&it, w, pos);
12276
12277 /* Display all lines of W. */
12278 while (it.current_y < it.last_visible_y)
12279 {
12280 if (display_line (&it))
12281 last_text_row = it.glyph_row - 1;
12282 if (fonts_changed_p)
12283 return 0;
12284 }
12285
12286 /* If bottom moved off end of frame, change mode line percentage. */
12287 if (XFASTINT (w->window_end_pos) <= 0
12288 && Z != IT_CHARPOS (it))
12289 w->update_mode_line = Qt;
12290
12291 /* Set window_end_pos to the offset of the last character displayed
12292 on the window from the end of current_buffer. Set
12293 window_end_vpos to its row number. */
12294 if (last_text_row)
12295 {
12296 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12297 w->window_end_bytepos
12298 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12299 w->window_end_pos
12300 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12301 w->window_end_vpos
12302 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12303 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12304 ->displays_text_p);
12305 }
12306 else
12307 {
12308 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12309 w->window_end_pos = make_number (Z - ZV);
12310 w->window_end_vpos = make_number (0);
12311 }
12312
12313 /* But that is not valid info until redisplay finishes. */
12314 w->window_end_valid = Qnil;
12315 return 1;
12316 }
12317
12318
12319 \f
12320 /************************************************************************
12321 Window redisplay reusing current matrix when buffer has not changed
12322 ************************************************************************/
12323
12324 /* Try redisplay of window W showing an unchanged buffer with a
12325 different window start than the last time it was displayed by
12326 reusing its current matrix. Value is non-zero if successful.
12327 W->start is the new window start. */
12328
12329 static int
12330 try_window_reusing_current_matrix (w)
12331 struct window *w;
12332 {
12333 struct frame *f = XFRAME (w->frame);
12334 struct glyph_row *row, *bottom_row;
12335 struct it it;
12336 struct run run;
12337 struct text_pos start, new_start;
12338 int nrows_scrolled, i;
12339 struct glyph_row *last_text_row;
12340 struct glyph_row *last_reused_text_row;
12341 struct glyph_row *start_row;
12342 int start_vpos, min_y, max_y;
12343
12344 #if GLYPH_DEBUG
12345 if (inhibit_try_window_reusing)
12346 return 0;
12347 #endif
12348
12349 if (/* This function doesn't handle terminal frames. */
12350 !FRAME_WINDOW_P (f)
12351 /* Don't try to reuse the display if windows have been split
12352 or such. */
12353 || windows_or_buffers_changed
12354 || cursor_type_changed)
12355 return 0;
12356
12357 /* Can't do this if region may have changed. */
12358 if ((!NILP (Vtransient_mark_mode)
12359 && !NILP (current_buffer->mark_active))
12360 || !NILP (w->region_showing)
12361 || !NILP (Vshow_trailing_whitespace))
12362 return 0;
12363
12364 /* If top-line visibility has changed, give up. */
12365 if (WINDOW_WANTS_HEADER_LINE_P (w)
12366 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12367 return 0;
12368
12369 /* Give up if old or new display is scrolled vertically. We could
12370 make this function handle this, but right now it doesn't. */
12371 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12372 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12373 return 0;
12374
12375 /* The variable new_start now holds the new window start. The old
12376 start `start' can be determined from the current matrix. */
12377 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12378 start = start_row->start.pos;
12379 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12380
12381 /* Clear the desired matrix for the display below. */
12382 clear_glyph_matrix (w->desired_matrix);
12383
12384 if (CHARPOS (new_start) <= CHARPOS (start))
12385 {
12386 int first_row_y;
12387
12388 /* Don't use this method if the display starts with an ellipsis
12389 displayed for invisible text. It's not easy to handle that case
12390 below, and it's certainly not worth the effort since this is
12391 not a frequent case. */
12392 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12393 return 0;
12394
12395 IF_DEBUG (debug_method_add (w, "twu1"));
12396
12397 /* Display up to a row that can be reused. The variable
12398 last_text_row is set to the last row displayed that displays
12399 text. Note that it.vpos == 0 if or if not there is a
12400 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12401 start_display (&it, w, new_start);
12402 first_row_y = it.current_y;
12403 w->cursor.vpos = -1;
12404 last_text_row = last_reused_text_row = NULL;
12405
12406 while (it.current_y < it.last_visible_y
12407 && IT_CHARPOS (it) < CHARPOS (start)
12408 && !fonts_changed_p)
12409 if (display_line (&it))
12410 last_text_row = it.glyph_row - 1;
12411
12412 /* A value of current_y < last_visible_y means that we stopped
12413 at the previous window start, which in turn means that we
12414 have at least one reusable row. */
12415 if (it.current_y < it.last_visible_y)
12416 {
12417 /* IT.vpos always starts from 0; it counts text lines. */
12418 nrows_scrolled = it.vpos;
12419
12420 /* Find PT if not already found in the lines displayed. */
12421 if (w->cursor.vpos < 0)
12422 {
12423 int dy = it.current_y - first_row_y;
12424
12425 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12426 row = row_containing_pos (w, PT, row, NULL, dy);
12427 if (row)
12428 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12429 dy, nrows_scrolled);
12430 else
12431 {
12432 clear_glyph_matrix (w->desired_matrix);
12433 return 0;
12434 }
12435 }
12436
12437 /* Scroll the display. Do it before the current matrix is
12438 changed. The problem here is that update has not yet
12439 run, i.e. part of the current matrix is not up to date.
12440 scroll_run_hook will clear the cursor, and use the
12441 current matrix to get the height of the row the cursor is
12442 in. */
12443 run.current_y = first_row_y;
12444 run.desired_y = it.current_y;
12445 run.height = it.last_visible_y - it.current_y;
12446
12447 if (run.height > 0 && run.current_y != run.desired_y)
12448 {
12449 update_begin (f);
12450 rif->update_window_begin_hook (w);
12451 rif->clear_window_mouse_face (w);
12452 rif->scroll_run_hook (w, &run);
12453 rif->update_window_end_hook (w, 0, 0);
12454 update_end (f);
12455 }
12456
12457 /* Shift current matrix down by nrows_scrolled lines. */
12458 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12459 rotate_matrix (w->current_matrix,
12460 start_vpos,
12461 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12462 nrows_scrolled);
12463
12464 /* Disable lines that must be updated. */
12465 for (i = 0; i < it.vpos; ++i)
12466 (start_row + i)->enabled_p = 0;
12467
12468 /* Re-compute Y positions. */
12469 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12470 max_y = it.last_visible_y;
12471 for (row = start_row + nrows_scrolled;
12472 row < bottom_row;
12473 ++row)
12474 {
12475 row->y = it.current_y;
12476 row->visible_height = row->height;
12477
12478 if (row->y < min_y)
12479 row->visible_height -= min_y - row->y;
12480 if (row->y + row->height > max_y)
12481 row->visible_height -= row->y + row->height - max_y;
12482 row->redraw_fringe_bitmaps_p = 1;
12483
12484 it.current_y += row->height;
12485
12486 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12487 last_reused_text_row = row;
12488 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12489 break;
12490 }
12491
12492 /* Disable lines in the current matrix which are now
12493 below the window. */
12494 for (++row; row < bottom_row; ++row)
12495 row->enabled_p = 0;
12496 }
12497
12498 /* Update window_end_pos etc.; last_reused_text_row is the last
12499 reused row from the current matrix containing text, if any.
12500 The value of last_text_row is the last displayed line
12501 containing text. */
12502 if (last_reused_text_row)
12503 {
12504 w->window_end_bytepos
12505 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12506 w->window_end_pos
12507 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12508 w->window_end_vpos
12509 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12510 w->current_matrix));
12511 }
12512 else if (last_text_row)
12513 {
12514 w->window_end_bytepos
12515 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12516 w->window_end_pos
12517 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12518 w->window_end_vpos
12519 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12520 }
12521 else
12522 {
12523 /* This window must be completely empty. */
12524 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12525 w->window_end_pos = make_number (Z - ZV);
12526 w->window_end_vpos = make_number (0);
12527 }
12528 w->window_end_valid = Qnil;
12529
12530 /* Update hint: don't try scrolling again in update_window. */
12531 w->desired_matrix->no_scrolling_p = 1;
12532
12533 #if GLYPH_DEBUG
12534 debug_method_add (w, "try_window_reusing_current_matrix 1");
12535 #endif
12536 return 1;
12537 }
12538 else if (CHARPOS (new_start) > CHARPOS (start))
12539 {
12540 struct glyph_row *pt_row, *row;
12541 struct glyph_row *first_reusable_row;
12542 struct glyph_row *first_row_to_display;
12543 int dy;
12544 int yb = window_text_bottom_y (w);
12545
12546 /* Find the row starting at new_start, if there is one. Don't
12547 reuse a partially visible line at the end. */
12548 first_reusable_row = start_row;
12549 while (first_reusable_row->enabled_p
12550 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12551 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12552 < CHARPOS (new_start)))
12553 ++first_reusable_row;
12554
12555 /* Give up if there is no row to reuse. */
12556 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12557 || !first_reusable_row->enabled_p
12558 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12559 != CHARPOS (new_start)))
12560 return 0;
12561
12562 /* We can reuse fully visible rows beginning with
12563 first_reusable_row to the end of the window. Set
12564 first_row_to_display to the first row that cannot be reused.
12565 Set pt_row to the row containing point, if there is any. */
12566 pt_row = NULL;
12567 for (first_row_to_display = first_reusable_row;
12568 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12569 ++first_row_to_display)
12570 {
12571 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12572 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12573 pt_row = first_row_to_display;
12574 }
12575
12576 /* Start displaying at the start of first_row_to_display. */
12577 xassert (first_row_to_display->y < yb);
12578 init_to_row_start (&it, w, first_row_to_display);
12579
12580 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12581 - start_vpos);
12582 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12583 - nrows_scrolled);
12584 it.current_y = (first_row_to_display->y - first_reusable_row->y
12585 + WINDOW_HEADER_LINE_HEIGHT (w));
12586
12587 /* Display lines beginning with first_row_to_display in the
12588 desired matrix. Set last_text_row to the last row displayed
12589 that displays text. */
12590 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12591 if (pt_row == NULL)
12592 w->cursor.vpos = -1;
12593 last_text_row = NULL;
12594 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12595 if (display_line (&it))
12596 last_text_row = it.glyph_row - 1;
12597
12598 /* Give up If point isn't in a row displayed or reused. */
12599 if (w->cursor.vpos < 0)
12600 {
12601 clear_glyph_matrix (w->desired_matrix);
12602 return 0;
12603 }
12604
12605 /* If point is in a reused row, adjust y and vpos of the cursor
12606 position. */
12607 if (pt_row)
12608 {
12609 w->cursor.vpos -= nrows_scrolled;
12610 w->cursor.y -= first_reusable_row->y - start_row->y;
12611 }
12612
12613 /* Scroll the display. */
12614 run.current_y = first_reusable_row->y;
12615 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12616 run.height = it.last_visible_y - run.current_y;
12617 dy = run.current_y - run.desired_y;
12618
12619 if (run.height)
12620 {
12621 update_begin (f);
12622 rif->update_window_begin_hook (w);
12623 rif->clear_window_mouse_face (w);
12624 rif->scroll_run_hook (w, &run);
12625 rif->update_window_end_hook (w, 0, 0);
12626 update_end (f);
12627 }
12628
12629 /* Adjust Y positions of reused rows. */
12630 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12631 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12632 max_y = it.last_visible_y;
12633 for (row = first_reusable_row; row < first_row_to_display; ++row)
12634 {
12635 row->y -= dy;
12636 row->visible_height = row->height;
12637 if (row->y < min_y)
12638 row->visible_height -= min_y - row->y;
12639 if (row->y + row->height > max_y)
12640 row->visible_height -= row->y + row->height - max_y;
12641 row->redraw_fringe_bitmaps_p = 1;
12642 }
12643
12644 /* Scroll the current matrix. */
12645 xassert (nrows_scrolled > 0);
12646 rotate_matrix (w->current_matrix,
12647 start_vpos,
12648 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12649 -nrows_scrolled);
12650
12651 /* Disable rows not reused. */
12652 for (row -= nrows_scrolled; row < bottom_row; ++row)
12653 row->enabled_p = 0;
12654
12655 /* Point may have moved to a different line, so we cannot assume that
12656 the previous cursor position is valid; locate the correct row. */
12657 if (pt_row)
12658 {
12659 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12660 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12661 row++)
12662 {
12663 w->cursor.vpos++;
12664 w->cursor.y = row->y;
12665 }
12666 if (row < bottom_row)
12667 {
12668 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12669 while (glyph->charpos < PT)
12670 {
12671 w->cursor.hpos++;
12672 w->cursor.x += glyph->pixel_width;
12673 glyph++;
12674 }
12675 }
12676 }
12677
12678 /* Adjust window end. A null value of last_text_row means that
12679 the window end is in reused rows which in turn means that
12680 only its vpos can have changed. */
12681 if (last_text_row)
12682 {
12683 w->window_end_bytepos
12684 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12685 w->window_end_pos
12686 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12687 w->window_end_vpos
12688 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12689 }
12690 else
12691 {
12692 w->window_end_vpos
12693 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12694 }
12695
12696 w->window_end_valid = Qnil;
12697 w->desired_matrix->no_scrolling_p = 1;
12698
12699 #if GLYPH_DEBUG
12700 debug_method_add (w, "try_window_reusing_current_matrix 2");
12701 #endif
12702 return 1;
12703 }
12704
12705 return 0;
12706 }
12707
12708
12709 \f
12710 /************************************************************************
12711 Window redisplay reusing current matrix when buffer has changed
12712 ************************************************************************/
12713
12714 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12715 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12716 int *, int *));
12717 static struct glyph_row *
12718 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12719 struct glyph_row *));
12720
12721
12722 /* Return the last row in MATRIX displaying text. If row START is
12723 non-null, start searching with that row. IT gives the dimensions
12724 of the display. Value is null if matrix is empty; otherwise it is
12725 a pointer to the row found. */
12726
12727 static struct glyph_row *
12728 find_last_row_displaying_text (matrix, it, start)
12729 struct glyph_matrix *matrix;
12730 struct it *it;
12731 struct glyph_row *start;
12732 {
12733 struct glyph_row *row, *row_found;
12734
12735 /* Set row_found to the last row in IT->w's current matrix
12736 displaying text. The loop looks funny but think of partially
12737 visible lines. */
12738 row_found = NULL;
12739 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12740 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12741 {
12742 xassert (row->enabled_p);
12743 row_found = row;
12744 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12745 break;
12746 ++row;
12747 }
12748
12749 return row_found;
12750 }
12751
12752
12753 /* Return the last row in the current matrix of W that is not affected
12754 by changes at the start of current_buffer that occurred since W's
12755 current matrix was built. Value is null if no such row exists.
12756
12757 BEG_UNCHANGED us the number of characters unchanged at the start of
12758 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12759 first changed character in current_buffer. Characters at positions <
12760 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12761 when the current matrix was built. */
12762
12763 static struct glyph_row *
12764 find_last_unchanged_at_beg_row (w)
12765 struct window *w;
12766 {
12767 int first_changed_pos = BEG + BEG_UNCHANGED;
12768 struct glyph_row *row;
12769 struct glyph_row *row_found = NULL;
12770 int yb = window_text_bottom_y (w);
12771
12772 /* Find the last row displaying unchanged text. */
12773 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12774 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12775 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12776 {
12777 if (/* If row ends before first_changed_pos, it is unchanged,
12778 except in some case. */
12779 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12780 /* When row ends in ZV and we write at ZV it is not
12781 unchanged. */
12782 && !row->ends_at_zv_p
12783 /* When first_changed_pos is the end of a continued line,
12784 row is not unchanged because it may be no longer
12785 continued. */
12786 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12787 && (row->continued_p
12788 || row->exact_window_width_line_p)))
12789 row_found = row;
12790
12791 /* Stop if last visible row. */
12792 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12793 break;
12794
12795 ++row;
12796 }
12797
12798 return row_found;
12799 }
12800
12801
12802 /* Find the first glyph row in the current matrix of W that is not
12803 affected by changes at the end of current_buffer since the
12804 time W's current matrix was built.
12805
12806 Return in *DELTA the number of chars by which buffer positions in
12807 unchanged text at the end of current_buffer must be adjusted.
12808
12809 Return in *DELTA_BYTES the corresponding number of bytes.
12810
12811 Value is null if no such row exists, i.e. all rows are affected by
12812 changes. */
12813
12814 static struct glyph_row *
12815 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12816 struct window *w;
12817 int *delta, *delta_bytes;
12818 {
12819 struct glyph_row *row;
12820 struct glyph_row *row_found = NULL;
12821
12822 *delta = *delta_bytes = 0;
12823
12824 /* Display must not have been paused, otherwise the current matrix
12825 is not up to date. */
12826 if (NILP (w->window_end_valid))
12827 abort ();
12828
12829 /* A value of window_end_pos >= END_UNCHANGED means that the window
12830 end is in the range of changed text. If so, there is no
12831 unchanged row at the end of W's current matrix. */
12832 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12833 return NULL;
12834
12835 /* Set row to the last row in W's current matrix displaying text. */
12836 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12837
12838 /* If matrix is entirely empty, no unchanged row exists. */
12839 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12840 {
12841 /* The value of row is the last glyph row in the matrix having a
12842 meaningful buffer position in it. The end position of row
12843 corresponds to window_end_pos. This allows us to translate
12844 buffer positions in the current matrix to current buffer
12845 positions for characters not in changed text. */
12846 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12847 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12848 int last_unchanged_pos, last_unchanged_pos_old;
12849 struct glyph_row *first_text_row
12850 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12851
12852 *delta = Z - Z_old;
12853 *delta_bytes = Z_BYTE - Z_BYTE_old;
12854
12855 /* Set last_unchanged_pos to the buffer position of the last
12856 character in the buffer that has not been changed. Z is the
12857 index + 1 of the last character in current_buffer, i.e. by
12858 subtracting END_UNCHANGED we get the index of the last
12859 unchanged character, and we have to add BEG to get its buffer
12860 position. */
12861 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12862 last_unchanged_pos_old = last_unchanged_pos - *delta;
12863
12864 /* Search backward from ROW for a row displaying a line that
12865 starts at a minimum position >= last_unchanged_pos_old. */
12866 for (; row > first_text_row; --row)
12867 {
12868 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12869 abort ();
12870
12871 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12872 row_found = row;
12873 }
12874 }
12875
12876 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12877 abort ();
12878
12879 return row_found;
12880 }
12881
12882
12883 /* Make sure that glyph rows in the current matrix of window W
12884 reference the same glyph memory as corresponding rows in the
12885 frame's frame matrix. This function is called after scrolling W's
12886 current matrix on a terminal frame in try_window_id and
12887 try_window_reusing_current_matrix. */
12888
12889 static void
12890 sync_frame_with_window_matrix_rows (w)
12891 struct window *w;
12892 {
12893 struct frame *f = XFRAME (w->frame);
12894 struct glyph_row *window_row, *window_row_end, *frame_row;
12895
12896 /* Preconditions: W must be a leaf window and full-width. Its frame
12897 must have a frame matrix. */
12898 xassert (NILP (w->hchild) && NILP (w->vchild));
12899 xassert (WINDOW_FULL_WIDTH_P (w));
12900 xassert (!FRAME_WINDOW_P (f));
12901
12902 /* If W is a full-width window, glyph pointers in W's current matrix
12903 have, by definition, to be the same as glyph pointers in the
12904 corresponding frame matrix. Note that frame matrices have no
12905 marginal areas (see build_frame_matrix). */
12906 window_row = w->current_matrix->rows;
12907 window_row_end = window_row + w->current_matrix->nrows;
12908 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12909 while (window_row < window_row_end)
12910 {
12911 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12912 struct glyph *end = window_row->glyphs[LAST_AREA];
12913
12914 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12915 frame_row->glyphs[TEXT_AREA] = start;
12916 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12917 frame_row->glyphs[LAST_AREA] = end;
12918
12919 /* Disable frame rows whose corresponding window rows have
12920 been disabled in try_window_id. */
12921 if (!window_row->enabled_p)
12922 frame_row->enabled_p = 0;
12923
12924 ++window_row, ++frame_row;
12925 }
12926 }
12927
12928
12929 /* Find the glyph row in window W containing CHARPOS. Consider all
12930 rows between START and END (not inclusive). END null means search
12931 all rows to the end of the display area of W. Value is the row
12932 containing CHARPOS or null. */
12933
12934 struct glyph_row *
12935 row_containing_pos (w, charpos, start, end, dy)
12936 struct window *w;
12937 int charpos;
12938 struct glyph_row *start, *end;
12939 int dy;
12940 {
12941 struct glyph_row *row = start;
12942 int last_y;
12943
12944 /* If we happen to start on a header-line, skip that. */
12945 if (row->mode_line_p)
12946 ++row;
12947
12948 if ((end && row >= end) || !row->enabled_p)
12949 return NULL;
12950
12951 last_y = window_text_bottom_y (w) - dy;
12952
12953 while (1)
12954 {
12955 /* Give up if we have gone too far. */
12956 if (end && row >= end)
12957 return NULL;
12958 /* This formerly returned if they were equal.
12959 I think that both quantities are of a "last plus one" type;
12960 if so, when they are equal, the row is within the screen. -- rms. */
12961 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12962 return NULL;
12963
12964 /* If it is in this row, return this row. */
12965 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12966 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12967 /* The end position of a row equals the start
12968 position of the next row. If CHARPOS is there, we
12969 would rather display it in the next line, except
12970 when this line ends in ZV. */
12971 && !row->ends_at_zv_p
12972 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12973 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12974 return row;
12975 ++row;
12976 }
12977 }
12978
12979
12980 /* Try to redisplay window W by reusing its existing display. W's
12981 current matrix must be up to date when this function is called,
12982 i.e. window_end_valid must not be nil.
12983
12984 Value is
12985
12986 1 if display has been updated
12987 0 if otherwise unsuccessful
12988 -1 if redisplay with same window start is known not to succeed
12989
12990 The following steps are performed:
12991
12992 1. Find the last row in the current matrix of W that is not
12993 affected by changes at the start of current_buffer. If no such row
12994 is found, give up.
12995
12996 2. Find the first row in W's current matrix that is not affected by
12997 changes at the end of current_buffer. Maybe there is no such row.
12998
12999 3. Display lines beginning with the row + 1 found in step 1 to the
13000 row found in step 2 or, if step 2 didn't find a row, to the end of
13001 the window.
13002
13003 4. If cursor is not known to appear on the window, give up.
13004
13005 5. If display stopped at the row found in step 2, scroll the
13006 display and current matrix as needed.
13007
13008 6. Maybe display some lines at the end of W, if we must. This can
13009 happen under various circumstances, like a partially visible line
13010 becoming fully visible, or because newly displayed lines are displayed
13011 in smaller font sizes.
13012
13013 7. Update W's window end information. */
13014
13015 static int
13016 try_window_id (w)
13017 struct window *w;
13018 {
13019 struct frame *f = XFRAME (w->frame);
13020 struct glyph_matrix *current_matrix = w->current_matrix;
13021 struct glyph_matrix *desired_matrix = w->desired_matrix;
13022 struct glyph_row *last_unchanged_at_beg_row;
13023 struct glyph_row *first_unchanged_at_end_row;
13024 struct glyph_row *row;
13025 struct glyph_row *bottom_row;
13026 int bottom_vpos;
13027 struct it it;
13028 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13029 struct text_pos start_pos;
13030 struct run run;
13031 int first_unchanged_at_end_vpos = 0;
13032 struct glyph_row *last_text_row, *last_text_row_at_end;
13033 struct text_pos start;
13034 int first_changed_charpos, last_changed_charpos;
13035
13036 #if GLYPH_DEBUG
13037 if (inhibit_try_window_id)
13038 return 0;
13039 #endif
13040
13041 /* This is handy for debugging. */
13042 #if 0
13043 #define GIVE_UP(X) \
13044 do { \
13045 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13046 return 0; \
13047 } while (0)
13048 #else
13049 #define GIVE_UP(X) return 0
13050 #endif
13051
13052 SET_TEXT_POS_FROM_MARKER (start, w->start);
13053
13054 /* Don't use this for mini-windows because these can show
13055 messages and mini-buffers, and we don't handle that here. */
13056 if (MINI_WINDOW_P (w))
13057 GIVE_UP (1);
13058
13059 /* This flag is used to prevent redisplay optimizations. */
13060 if (windows_or_buffers_changed || cursor_type_changed)
13061 GIVE_UP (2);
13062
13063 /* Verify that narrowing has not changed.
13064 Also verify that we were not told to prevent redisplay optimizations.
13065 It would be nice to further
13066 reduce the number of cases where this prevents try_window_id. */
13067 if (current_buffer->clip_changed
13068 || current_buffer->prevent_redisplay_optimizations_p)
13069 GIVE_UP (3);
13070
13071 /* Window must either use window-based redisplay or be full width. */
13072 if (!FRAME_WINDOW_P (f)
13073 && (!line_ins_del_ok
13074 || !WINDOW_FULL_WIDTH_P (w)))
13075 GIVE_UP (4);
13076
13077 /* Give up if point is not known NOT to appear in W. */
13078 if (PT < CHARPOS (start))
13079 GIVE_UP (5);
13080
13081 /* Another way to prevent redisplay optimizations. */
13082 if (XFASTINT (w->last_modified) == 0)
13083 GIVE_UP (6);
13084
13085 /* Verify that window is not hscrolled. */
13086 if (XFASTINT (w->hscroll) != 0)
13087 GIVE_UP (7);
13088
13089 /* Verify that display wasn't paused. */
13090 if (NILP (w->window_end_valid))
13091 GIVE_UP (8);
13092
13093 /* Can't use this if highlighting a region because a cursor movement
13094 will do more than just set the cursor. */
13095 if (!NILP (Vtransient_mark_mode)
13096 && !NILP (current_buffer->mark_active))
13097 GIVE_UP (9);
13098
13099 /* Likewise if highlighting trailing whitespace. */
13100 if (!NILP (Vshow_trailing_whitespace))
13101 GIVE_UP (11);
13102
13103 /* Likewise if showing a region. */
13104 if (!NILP (w->region_showing))
13105 GIVE_UP (10);
13106
13107 /* Can use this if overlay arrow position and or string have changed. */
13108 if (overlay_arrows_changed_p ())
13109 GIVE_UP (12);
13110
13111
13112 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13113 only if buffer has really changed. The reason is that the gap is
13114 initially at Z for freshly visited files. The code below would
13115 set end_unchanged to 0 in that case. */
13116 if (MODIFF > SAVE_MODIFF
13117 /* This seems to happen sometimes after saving a buffer. */
13118 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13119 {
13120 if (GPT - BEG < BEG_UNCHANGED)
13121 BEG_UNCHANGED = GPT - BEG;
13122 if (Z - GPT < END_UNCHANGED)
13123 END_UNCHANGED = Z - GPT;
13124 }
13125
13126 /* The position of the first and last character that has been changed. */
13127 first_changed_charpos = BEG + BEG_UNCHANGED;
13128 last_changed_charpos = Z - END_UNCHANGED;
13129
13130 /* If window starts after a line end, and the last change is in
13131 front of that newline, then changes don't affect the display.
13132 This case happens with stealth-fontification. Note that although
13133 the display is unchanged, glyph positions in the matrix have to
13134 be adjusted, of course. */
13135 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13136 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13137 && ((last_changed_charpos < CHARPOS (start)
13138 && CHARPOS (start) == BEGV)
13139 || (last_changed_charpos < CHARPOS (start) - 1
13140 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13141 {
13142 int Z_old, delta, Z_BYTE_old, delta_bytes;
13143 struct glyph_row *r0;
13144
13145 /* Compute how many chars/bytes have been added to or removed
13146 from the buffer. */
13147 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13148 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13149 delta = Z - Z_old;
13150 delta_bytes = Z_BYTE - Z_BYTE_old;
13151
13152 /* Give up if PT is not in the window. Note that it already has
13153 been checked at the start of try_window_id that PT is not in
13154 front of the window start. */
13155 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13156 GIVE_UP (13);
13157
13158 /* If window start is unchanged, we can reuse the whole matrix
13159 as is, after adjusting glyph positions. No need to compute
13160 the window end again, since its offset from Z hasn't changed. */
13161 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13162 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13163 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13164 /* PT must not be in a partially visible line. */
13165 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13166 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13167 {
13168 /* Adjust positions in the glyph matrix. */
13169 if (delta || delta_bytes)
13170 {
13171 struct glyph_row *r1
13172 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13173 increment_matrix_positions (w->current_matrix,
13174 MATRIX_ROW_VPOS (r0, current_matrix),
13175 MATRIX_ROW_VPOS (r1, current_matrix),
13176 delta, delta_bytes);
13177 }
13178
13179 /* Set the cursor. */
13180 row = row_containing_pos (w, PT, r0, NULL, 0);
13181 if (row)
13182 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13183 else
13184 abort ();
13185 return 1;
13186 }
13187 }
13188
13189 /* Handle the case that changes are all below what is displayed in
13190 the window, and that PT is in the window. This shortcut cannot
13191 be taken if ZV is visible in the window, and text has been added
13192 there that is visible in the window. */
13193 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13194 /* ZV is not visible in the window, or there are no
13195 changes at ZV, actually. */
13196 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13197 || first_changed_charpos == last_changed_charpos))
13198 {
13199 struct glyph_row *r0;
13200
13201 /* Give up if PT is not in the window. Note that it already has
13202 been checked at the start of try_window_id that PT is not in
13203 front of the window start. */
13204 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13205 GIVE_UP (14);
13206
13207 /* If window start is unchanged, we can reuse the whole matrix
13208 as is, without changing glyph positions since no text has
13209 been added/removed in front of the window end. */
13210 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13211 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13212 /* PT must not be in a partially visible line. */
13213 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13214 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13215 {
13216 /* We have to compute the window end anew since text
13217 can have been added/removed after it. */
13218 w->window_end_pos
13219 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13220 w->window_end_bytepos
13221 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13222
13223 /* Set the cursor. */
13224 row = row_containing_pos (w, PT, r0, NULL, 0);
13225 if (row)
13226 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13227 else
13228 abort ();
13229 return 2;
13230 }
13231 }
13232
13233 /* Give up if window start is in the changed area.
13234
13235 The condition used to read
13236
13237 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13238
13239 but why that was tested escapes me at the moment. */
13240 if (CHARPOS (start) >= first_changed_charpos
13241 && CHARPOS (start) <= last_changed_charpos)
13242 GIVE_UP (15);
13243
13244 /* Check that window start agrees with the start of the first glyph
13245 row in its current matrix. Check this after we know the window
13246 start is not in changed text, otherwise positions would not be
13247 comparable. */
13248 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13249 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13250 GIVE_UP (16);
13251
13252 /* Give up if the window ends in strings. Overlay strings
13253 at the end are difficult to handle, so don't try. */
13254 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13255 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13256 GIVE_UP (20);
13257
13258 /* Compute the position at which we have to start displaying new
13259 lines. Some of the lines at the top of the window might be
13260 reusable because they are not displaying changed text. Find the
13261 last row in W's current matrix not affected by changes at the
13262 start of current_buffer. Value is null if changes start in the
13263 first line of window. */
13264 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13265 if (last_unchanged_at_beg_row)
13266 {
13267 /* Avoid starting to display in the moddle of a character, a TAB
13268 for instance. This is easier than to set up the iterator
13269 exactly, and it's not a frequent case, so the additional
13270 effort wouldn't really pay off. */
13271 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13272 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13273 && last_unchanged_at_beg_row > w->current_matrix->rows)
13274 --last_unchanged_at_beg_row;
13275
13276 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13277 GIVE_UP (17);
13278
13279 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13280 GIVE_UP (18);
13281 start_pos = it.current.pos;
13282
13283 /* Start displaying new lines in the desired matrix at the same
13284 vpos we would use in the current matrix, i.e. below
13285 last_unchanged_at_beg_row. */
13286 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13287 current_matrix);
13288 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13289 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13290
13291 xassert (it.hpos == 0 && it.current_x == 0);
13292 }
13293 else
13294 {
13295 /* There are no reusable lines at the start of the window.
13296 Start displaying in the first text line. */
13297 start_display (&it, w, start);
13298 it.vpos = it.first_vpos;
13299 start_pos = it.current.pos;
13300 }
13301
13302 /* Find the first row that is not affected by changes at the end of
13303 the buffer. Value will be null if there is no unchanged row, in
13304 which case we must redisplay to the end of the window. delta
13305 will be set to the value by which buffer positions beginning with
13306 first_unchanged_at_end_row have to be adjusted due to text
13307 changes. */
13308 first_unchanged_at_end_row
13309 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13310 IF_DEBUG (debug_delta = delta);
13311 IF_DEBUG (debug_delta_bytes = delta_bytes);
13312
13313 /* Set stop_pos to the buffer position up to which we will have to
13314 display new lines. If first_unchanged_at_end_row != NULL, this
13315 is the buffer position of the start of the line displayed in that
13316 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13317 that we don't stop at a buffer position. */
13318 stop_pos = 0;
13319 if (first_unchanged_at_end_row)
13320 {
13321 xassert (last_unchanged_at_beg_row == NULL
13322 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13323
13324 /* If this is a continuation line, move forward to the next one
13325 that isn't. Changes in lines above affect this line.
13326 Caution: this may move first_unchanged_at_end_row to a row
13327 not displaying text. */
13328 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13329 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13330 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13331 < it.last_visible_y))
13332 ++first_unchanged_at_end_row;
13333
13334 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13335 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13336 >= it.last_visible_y))
13337 first_unchanged_at_end_row = NULL;
13338 else
13339 {
13340 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13341 + delta);
13342 first_unchanged_at_end_vpos
13343 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13344 xassert (stop_pos >= Z - END_UNCHANGED);
13345 }
13346 }
13347 else if (last_unchanged_at_beg_row == NULL)
13348 GIVE_UP (19);
13349
13350
13351 #if GLYPH_DEBUG
13352
13353 /* Either there is no unchanged row at the end, or the one we have
13354 now displays text. This is a necessary condition for the window
13355 end pos calculation at the end of this function. */
13356 xassert (first_unchanged_at_end_row == NULL
13357 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13358
13359 debug_last_unchanged_at_beg_vpos
13360 = (last_unchanged_at_beg_row
13361 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13362 : -1);
13363 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13364
13365 #endif /* GLYPH_DEBUG != 0 */
13366
13367
13368 /* Display new lines. Set last_text_row to the last new line
13369 displayed which has text on it, i.e. might end up as being the
13370 line where the window_end_vpos is. */
13371 w->cursor.vpos = -1;
13372 last_text_row = NULL;
13373 overlay_arrow_seen = 0;
13374 while (it.current_y < it.last_visible_y
13375 && !fonts_changed_p
13376 && (first_unchanged_at_end_row == NULL
13377 || IT_CHARPOS (it) < stop_pos))
13378 {
13379 if (display_line (&it))
13380 last_text_row = it.glyph_row - 1;
13381 }
13382
13383 if (fonts_changed_p)
13384 return -1;
13385
13386
13387 /* Compute differences in buffer positions, y-positions etc. for
13388 lines reused at the bottom of the window. Compute what we can
13389 scroll. */
13390 if (first_unchanged_at_end_row
13391 /* No lines reused because we displayed everything up to the
13392 bottom of the window. */
13393 && it.current_y < it.last_visible_y)
13394 {
13395 dvpos = (it.vpos
13396 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13397 current_matrix));
13398 dy = it.current_y - first_unchanged_at_end_row->y;
13399 run.current_y = first_unchanged_at_end_row->y;
13400 run.desired_y = run.current_y + dy;
13401 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13402 }
13403 else
13404 {
13405 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13406 first_unchanged_at_end_row = NULL;
13407 }
13408 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13409
13410
13411 /* Find the cursor if not already found. We have to decide whether
13412 PT will appear on this window (it sometimes doesn't, but this is
13413 not a very frequent case.) This decision has to be made before
13414 the current matrix is altered. A value of cursor.vpos < 0 means
13415 that PT is either in one of the lines beginning at
13416 first_unchanged_at_end_row or below the window. Don't care for
13417 lines that might be displayed later at the window end; as
13418 mentioned, this is not a frequent case. */
13419 if (w->cursor.vpos < 0)
13420 {
13421 /* Cursor in unchanged rows at the top? */
13422 if (PT < CHARPOS (start_pos)
13423 && last_unchanged_at_beg_row)
13424 {
13425 row = row_containing_pos (w, PT,
13426 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13427 last_unchanged_at_beg_row + 1, 0);
13428 if (row)
13429 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13430 }
13431
13432 /* Start from first_unchanged_at_end_row looking for PT. */
13433 else if (first_unchanged_at_end_row)
13434 {
13435 row = row_containing_pos (w, PT - delta,
13436 first_unchanged_at_end_row, NULL, 0);
13437 if (row)
13438 set_cursor_from_row (w, row, w->current_matrix, delta,
13439 delta_bytes, dy, dvpos);
13440 }
13441
13442 /* Give up if cursor was not found. */
13443 if (w->cursor.vpos < 0)
13444 {
13445 clear_glyph_matrix (w->desired_matrix);
13446 return -1;
13447 }
13448 }
13449
13450 /* Don't let the cursor end in the scroll margins. */
13451 {
13452 int this_scroll_margin, cursor_height;
13453
13454 this_scroll_margin = max (0, scroll_margin);
13455 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13456 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13457 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13458
13459 if ((w->cursor.y < this_scroll_margin
13460 && CHARPOS (start) > BEGV)
13461 /* Old redisplay didn't take scroll margin into account at the bottom,
13462 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13463 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
13464 {
13465 w->cursor.vpos = -1;
13466 clear_glyph_matrix (w->desired_matrix);
13467 return -1;
13468 }
13469 }
13470
13471 /* Scroll the display. Do it before changing the current matrix so
13472 that xterm.c doesn't get confused about where the cursor glyph is
13473 found. */
13474 if (dy && run.height)
13475 {
13476 update_begin (f);
13477
13478 if (FRAME_WINDOW_P (f))
13479 {
13480 rif->update_window_begin_hook (w);
13481 rif->clear_window_mouse_face (w);
13482 rif->scroll_run_hook (w, &run);
13483 rif->update_window_end_hook (w, 0, 0);
13484 }
13485 else
13486 {
13487 /* Terminal frame. In this case, dvpos gives the number of
13488 lines to scroll by; dvpos < 0 means scroll up. */
13489 int first_unchanged_at_end_vpos
13490 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13491 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13492 int end = (WINDOW_TOP_EDGE_LINE (w)
13493 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13494 + window_internal_height (w));
13495
13496 /* Perform the operation on the screen. */
13497 if (dvpos > 0)
13498 {
13499 /* Scroll last_unchanged_at_beg_row to the end of the
13500 window down dvpos lines. */
13501 set_terminal_window (end);
13502
13503 /* On dumb terminals delete dvpos lines at the end
13504 before inserting dvpos empty lines. */
13505 if (!scroll_region_ok)
13506 ins_del_lines (end - dvpos, -dvpos);
13507
13508 /* Insert dvpos empty lines in front of
13509 last_unchanged_at_beg_row. */
13510 ins_del_lines (from, dvpos);
13511 }
13512 else if (dvpos < 0)
13513 {
13514 /* Scroll up last_unchanged_at_beg_vpos to the end of
13515 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13516 set_terminal_window (end);
13517
13518 /* Delete dvpos lines in front of
13519 last_unchanged_at_beg_vpos. ins_del_lines will set
13520 the cursor to the given vpos and emit |dvpos| delete
13521 line sequences. */
13522 ins_del_lines (from + dvpos, dvpos);
13523
13524 /* On a dumb terminal insert dvpos empty lines at the
13525 end. */
13526 if (!scroll_region_ok)
13527 ins_del_lines (end + dvpos, -dvpos);
13528 }
13529
13530 set_terminal_window (0);
13531 }
13532
13533 update_end (f);
13534 }
13535
13536 /* Shift reused rows of the current matrix to the right position.
13537 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13538 text. */
13539 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13540 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13541 if (dvpos < 0)
13542 {
13543 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13544 bottom_vpos, dvpos);
13545 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13546 bottom_vpos, 0);
13547 }
13548 else if (dvpos > 0)
13549 {
13550 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13551 bottom_vpos, dvpos);
13552 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13553 first_unchanged_at_end_vpos + dvpos, 0);
13554 }
13555
13556 /* For frame-based redisplay, make sure that current frame and window
13557 matrix are in sync with respect to glyph memory. */
13558 if (!FRAME_WINDOW_P (f))
13559 sync_frame_with_window_matrix_rows (w);
13560
13561 /* Adjust buffer positions in reused rows. */
13562 if (delta)
13563 increment_matrix_positions (current_matrix,
13564 first_unchanged_at_end_vpos + dvpos,
13565 bottom_vpos, delta, delta_bytes);
13566
13567 /* Adjust Y positions. */
13568 if (dy)
13569 shift_glyph_matrix (w, current_matrix,
13570 first_unchanged_at_end_vpos + dvpos,
13571 bottom_vpos, dy);
13572
13573 if (first_unchanged_at_end_row)
13574 first_unchanged_at_end_row += dvpos;
13575
13576 /* If scrolling up, there may be some lines to display at the end of
13577 the window. */
13578 last_text_row_at_end = NULL;
13579 if (dy < 0)
13580 {
13581 /* Scrolling up can leave for example a partially visible line
13582 at the end of the window to be redisplayed. */
13583 /* Set last_row to the glyph row in the current matrix where the
13584 window end line is found. It has been moved up or down in
13585 the matrix by dvpos. */
13586 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13587 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13588
13589 /* If last_row is the window end line, it should display text. */
13590 xassert (last_row->displays_text_p);
13591
13592 /* If window end line was partially visible before, begin
13593 displaying at that line. Otherwise begin displaying with the
13594 line following it. */
13595 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13596 {
13597 init_to_row_start (&it, w, last_row);
13598 it.vpos = last_vpos;
13599 it.current_y = last_row->y;
13600 }
13601 else
13602 {
13603 init_to_row_end (&it, w, last_row);
13604 it.vpos = 1 + last_vpos;
13605 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13606 ++last_row;
13607 }
13608
13609 /* We may start in a continuation line. If so, we have to
13610 get the right continuation_lines_width and current_x. */
13611 it.continuation_lines_width = last_row->continuation_lines_width;
13612 it.hpos = it.current_x = 0;
13613
13614 /* Display the rest of the lines at the window end. */
13615 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13616 while (it.current_y < it.last_visible_y
13617 && !fonts_changed_p)
13618 {
13619 /* Is it always sure that the display agrees with lines in
13620 the current matrix? I don't think so, so we mark rows
13621 displayed invalid in the current matrix by setting their
13622 enabled_p flag to zero. */
13623 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13624 if (display_line (&it))
13625 last_text_row_at_end = it.glyph_row - 1;
13626 }
13627 }
13628
13629 /* Update window_end_pos and window_end_vpos. */
13630 if (first_unchanged_at_end_row
13631 && first_unchanged_at_end_row->y < it.last_visible_y
13632 && !last_text_row_at_end)
13633 {
13634 /* Window end line if one of the preserved rows from the current
13635 matrix. Set row to the last row displaying text in current
13636 matrix starting at first_unchanged_at_end_row, after
13637 scrolling. */
13638 xassert (first_unchanged_at_end_row->displays_text_p);
13639 row = find_last_row_displaying_text (w->current_matrix, &it,
13640 first_unchanged_at_end_row);
13641 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13642
13643 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13644 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13645 w->window_end_vpos
13646 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13647 xassert (w->window_end_bytepos >= 0);
13648 IF_DEBUG (debug_method_add (w, "A"));
13649 }
13650 else if (last_text_row_at_end)
13651 {
13652 w->window_end_pos
13653 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13654 w->window_end_bytepos
13655 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13656 w->window_end_vpos
13657 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13658 xassert (w->window_end_bytepos >= 0);
13659 IF_DEBUG (debug_method_add (w, "B"));
13660 }
13661 else if (last_text_row)
13662 {
13663 /* We have displayed either to the end of the window or at the
13664 end of the window, i.e. the last row with text is to be found
13665 in the desired matrix. */
13666 w->window_end_pos
13667 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13668 w->window_end_bytepos
13669 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13670 w->window_end_vpos
13671 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13672 xassert (w->window_end_bytepos >= 0);
13673 }
13674 else if (first_unchanged_at_end_row == NULL
13675 && last_text_row == NULL
13676 && last_text_row_at_end == NULL)
13677 {
13678 /* Displayed to end of window, but no line containing text was
13679 displayed. Lines were deleted at the end of the window. */
13680 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13681 int vpos = XFASTINT (w->window_end_vpos);
13682 struct glyph_row *current_row = current_matrix->rows + vpos;
13683 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13684
13685 for (row = NULL;
13686 row == NULL && vpos >= first_vpos;
13687 --vpos, --current_row, --desired_row)
13688 {
13689 if (desired_row->enabled_p)
13690 {
13691 if (desired_row->displays_text_p)
13692 row = desired_row;
13693 }
13694 else if (current_row->displays_text_p)
13695 row = current_row;
13696 }
13697
13698 xassert (row != NULL);
13699 w->window_end_vpos = make_number (vpos + 1);
13700 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13701 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13702 xassert (w->window_end_bytepos >= 0);
13703 IF_DEBUG (debug_method_add (w, "C"));
13704 }
13705 else
13706 abort ();
13707
13708 #if 0 /* This leads to problems, for instance when the cursor is
13709 at ZV, and the cursor line displays no text. */
13710 /* Disable rows below what's displayed in the window. This makes
13711 debugging easier. */
13712 enable_glyph_matrix_rows (current_matrix,
13713 XFASTINT (w->window_end_vpos) + 1,
13714 bottom_vpos, 0);
13715 #endif
13716
13717 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13718 debug_end_vpos = XFASTINT (w->window_end_vpos));
13719
13720 /* Record that display has not been completed. */
13721 w->window_end_valid = Qnil;
13722 w->desired_matrix->no_scrolling_p = 1;
13723 return 3;
13724
13725 #undef GIVE_UP
13726 }
13727
13728
13729 \f
13730 /***********************************************************************
13731 More debugging support
13732 ***********************************************************************/
13733
13734 #if GLYPH_DEBUG
13735
13736 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13737 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13738 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13739
13740
13741 /* Dump the contents of glyph matrix MATRIX on stderr.
13742
13743 GLYPHS 0 means don't show glyph contents.
13744 GLYPHS 1 means show glyphs in short form
13745 GLYPHS > 1 means show glyphs in long form. */
13746
13747 void
13748 dump_glyph_matrix (matrix, glyphs)
13749 struct glyph_matrix *matrix;
13750 int glyphs;
13751 {
13752 int i;
13753 for (i = 0; i < matrix->nrows; ++i)
13754 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13755 }
13756
13757
13758 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13759 the glyph row and area where the glyph comes from. */
13760
13761 void
13762 dump_glyph (row, glyph, area)
13763 struct glyph_row *row;
13764 struct glyph *glyph;
13765 int area;
13766 {
13767 if (glyph->type == CHAR_GLYPH)
13768 {
13769 fprintf (stderr,
13770 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13771 glyph - row->glyphs[TEXT_AREA],
13772 'C',
13773 glyph->charpos,
13774 (BUFFERP (glyph->object)
13775 ? 'B'
13776 : (STRINGP (glyph->object)
13777 ? 'S'
13778 : '-')),
13779 glyph->pixel_width,
13780 glyph->u.ch,
13781 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13782 ? glyph->u.ch
13783 : '.'),
13784 glyph->face_id,
13785 glyph->left_box_line_p,
13786 glyph->right_box_line_p);
13787 }
13788 else if (glyph->type == STRETCH_GLYPH)
13789 {
13790 fprintf (stderr,
13791 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13792 glyph - row->glyphs[TEXT_AREA],
13793 'S',
13794 glyph->charpos,
13795 (BUFFERP (glyph->object)
13796 ? 'B'
13797 : (STRINGP (glyph->object)
13798 ? 'S'
13799 : '-')),
13800 glyph->pixel_width,
13801 0,
13802 '.',
13803 glyph->face_id,
13804 glyph->left_box_line_p,
13805 glyph->right_box_line_p);
13806 }
13807 else if (glyph->type == IMAGE_GLYPH)
13808 {
13809 fprintf (stderr,
13810 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13811 glyph - row->glyphs[TEXT_AREA],
13812 'I',
13813 glyph->charpos,
13814 (BUFFERP (glyph->object)
13815 ? 'B'
13816 : (STRINGP (glyph->object)
13817 ? 'S'
13818 : '-')),
13819 glyph->pixel_width,
13820 glyph->u.img_id,
13821 '.',
13822 glyph->face_id,
13823 glyph->left_box_line_p,
13824 glyph->right_box_line_p);
13825 }
13826 }
13827
13828
13829 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13830 GLYPHS 0 means don't show glyph contents.
13831 GLYPHS 1 means show glyphs in short form
13832 GLYPHS > 1 means show glyphs in long form. */
13833
13834 void
13835 dump_glyph_row (row, vpos, glyphs)
13836 struct glyph_row *row;
13837 int vpos, glyphs;
13838 {
13839 if (glyphs != 1)
13840 {
13841 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13842 fprintf (stderr, "=======================================================================\n");
13843
13844 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13845 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13846 vpos,
13847 MATRIX_ROW_START_CHARPOS (row),
13848 MATRIX_ROW_END_CHARPOS (row),
13849 row->used[TEXT_AREA],
13850 row->contains_overlapping_glyphs_p,
13851 row->enabled_p,
13852 row->truncated_on_left_p,
13853 row->truncated_on_right_p,
13854 row->overlay_arrow_p,
13855 row->continued_p,
13856 MATRIX_ROW_CONTINUATION_LINE_P (row),
13857 row->displays_text_p,
13858 row->ends_at_zv_p,
13859 row->fill_line_p,
13860 row->ends_in_middle_of_char_p,
13861 row->starts_in_middle_of_char_p,
13862 row->mouse_face_p,
13863 row->x,
13864 row->y,
13865 row->pixel_width,
13866 row->height,
13867 row->visible_height,
13868 row->ascent,
13869 row->phys_ascent);
13870 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13871 row->end.overlay_string_index,
13872 row->continuation_lines_width);
13873 fprintf (stderr, "%9d %5d\n",
13874 CHARPOS (row->start.string_pos),
13875 CHARPOS (row->end.string_pos));
13876 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13877 row->end.dpvec_index);
13878 }
13879
13880 if (glyphs > 1)
13881 {
13882 int area;
13883
13884 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13885 {
13886 struct glyph *glyph = row->glyphs[area];
13887 struct glyph *glyph_end = glyph + row->used[area];
13888
13889 /* Glyph for a line end in text. */
13890 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13891 ++glyph_end;
13892
13893 if (glyph < glyph_end)
13894 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13895
13896 for (; glyph < glyph_end; ++glyph)
13897 dump_glyph (row, glyph, area);
13898 }
13899 }
13900 else if (glyphs == 1)
13901 {
13902 int area;
13903
13904 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13905 {
13906 char *s = (char *) alloca (row->used[area] + 1);
13907 int i;
13908
13909 for (i = 0; i < row->used[area]; ++i)
13910 {
13911 struct glyph *glyph = row->glyphs[area] + i;
13912 if (glyph->type == CHAR_GLYPH
13913 && glyph->u.ch < 0x80
13914 && glyph->u.ch >= ' ')
13915 s[i] = glyph->u.ch;
13916 else
13917 s[i] = '.';
13918 }
13919
13920 s[i] = '\0';
13921 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13922 }
13923 }
13924 }
13925
13926
13927 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13928 Sdump_glyph_matrix, 0, 1, "p",
13929 doc: /* Dump the current matrix of the selected window to stderr.
13930 Shows contents of glyph row structures. With non-nil
13931 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13932 glyphs in short form, otherwise show glyphs in long form. */)
13933 (glyphs)
13934 Lisp_Object glyphs;
13935 {
13936 struct window *w = XWINDOW (selected_window);
13937 struct buffer *buffer = XBUFFER (w->buffer);
13938
13939 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13940 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13941 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13942 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13943 fprintf (stderr, "=============================================\n");
13944 dump_glyph_matrix (w->current_matrix,
13945 NILP (glyphs) ? 0 : XINT (glyphs));
13946 return Qnil;
13947 }
13948
13949
13950 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13951 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13952 ()
13953 {
13954 struct frame *f = XFRAME (selected_frame);
13955 dump_glyph_matrix (f->current_matrix, 1);
13956 return Qnil;
13957 }
13958
13959
13960 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13961 doc: /* Dump glyph row ROW to stderr.
13962 GLYPH 0 means don't dump glyphs.
13963 GLYPH 1 means dump glyphs in short form.
13964 GLYPH > 1 or omitted means dump glyphs in long form. */)
13965 (row, glyphs)
13966 Lisp_Object row, glyphs;
13967 {
13968 struct glyph_matrix *matrix;
13969 int vpos;
13970
13971 CHECK_NUMBER (row);
13972 matrix = XWINDOW (selected_window)->current_matrix;
13973 vpos = XINT (row);
13974 if (vpos >= 0 && vpos < matrix->nrows)
13975 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13976 vpos,
13977 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13978 return Qnil;
13979 }
13980
13981
13982 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13983 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13984 GLYPH 0 means don't dump glyphs.
13985 GLYPH 1 means dump glyphs in short form.
13986 GLYPH > 1 or omitted means dump glyphs in long form. */)
13987 (row, glyphs)
13988 Lisp_Object row, glyphs;
13989 {
13990 struct frame *sf = SELECTED_FRAME ();
13991 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13992 int vpos;
13993
13994 CHECK_NUMBER (row);
13995 vpos = XINT (row);
13996 if (vpos >= 0 && vpos < m->nrows)
13997 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13998 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13999 return Qnil;
14000 }
14001
14002
14003 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14004 doc: /* Toggle tracing of redisplay.
14005 With ARG, turn tracing on if and only if ARG is positive. */)
14006 (arg)
14007 Lisp_Object arg;
14008 {
14009 if (NILP (arg))
14010 trace_redisplay_p = !trace_redisplay_p;
14011 else
14012 {
14013 arg = Fprefix_numeric_value (arg);
14014 trace_redisplay_p = XINT (arg) > 0;
14015 }
14016
14017 return Qnil;
14018 }
14019
14020
14021 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14022 doc: /* Like `format', but print result to stderr.
14023 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14024 (nargs, args)
14025 int nargs;
14026 Lisp_Object *args;
14027 {
14028 Lisp_Object s = Fformat (nargs, args);
14029 fprintf (stderr, "%s", SDATA (s));
14030 return Qnil;
14031 }
14032
14033 #endif /* GLYPH_DEBUG */
14034
14035
14036 \f
14037 /***********************************************************************
14038 Building Desired Matrix Rows
14039 ***********************************************************************/
14040
14041 /* Return a temporary glyph row holding the glyphs of an overlay
14042 arrow. Only used for non-window-redisplay windows. */
14043
14044 static struct glyph_row *
14045 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14046 struct window *w;
14047 Lisp_Object overlay_arrow_string;
14048 {
14049 struct frame *f = XFRAME (WINDOW_FRAME (w));
14050 struct buffer *buffer = XBUFFER (w->buffer);
14051 struct buffer *old = current_buffer;
14052 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14053 int arrow_len = SCHARS (overlay_arrow_string);
14054 const unsigned char *arrow_end = arrow_string + arrow_len;
14055 const unsigned char *p;
14056 struct it it;
14057 int multibyte_p;
14058 int n_glyphs_before;
14059
14060 set_buffer_temp (buffer);
14061 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14062 it.glyph_row->used[TEXT_AREA] = 0;
14063 SET_TEXT_POS (it.position, 0, 0);
14064
14065 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14066 p = arrow_string;
14067 while (p < arrow_end)
14068 {
14069 Lisp_Object face, ilisp;
14070
14071 /* Get the next character. */
14072 if (multibyte_p)
14073 it.c = string_char_and_length (p, arrow_len, &it.len);
14074 else
14075 it.c = *p, it.len = 1;
14076 p += it.len;
14077
14078 /* Get its face. */
14079 ilisp = make_number (p - arrow_string);
14080 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14081 it.face_id = compute_char_face (f, it.c, face);
14082
14083 /* Compute its width, get its glyphs. */
14084 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14085 SET_TEXT_POS (it.position, -1, -1);
14086 PRODUCE_GLYPHS (&it);
14087
14088 /* If this character doesn't fit any more in the line, we have
14089 to remove some glyphs. */
14090 if (it.current_x > it.last_visible_x)
14091 {
14092 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14093 break;
14094 }
14095 }
14096
14097 set_buffer_temp (old);
14098 return it.glyph_row;
14099 }
14100
14101
14102 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14103 glyphs are only inserted for terminal frames since we can't really
14104 win with truncation glyphs when partially visible glyphs are
14105 involved. Which glyphs to insert is determined by
14106 produce_special_glyphs. */
14107
14108 static void
14109 insert_left_trunc_glyphs (it)
14110 struct it *it;
14111 {
14112 struct it truncate_it;
14113 struct glyph *from, *end, *to, *toend;
14114
14115 xassert (!FRAME_WINDOW_P (it->f));
14116
14117 /* Get the truncation glyphs. */
14118 truncate_it = *it;
14119 truncate_it.current_x = 0;
14120 truncate_it.face_id = DEFAULT_FACE_ID;
14121 truncate_it.glyph_row = &scratch_glyph_row;
14122 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14123 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14124 truncate_it.object = make_number (0);
14125 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14126
14127 /* Overwrite glyphs from IT with truncation glyphs. */
14128 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14129 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14130 to = it->glyph_row->glyphs[TEXT_AREA];
14131 toend = to + it->glyph_row->used[TEXT_AREA];
14132
14133 while (from < end)
14134 *to++ = *from++;
14135
14136 /* There may be padding glyphs left over. Overwrite them too. */
14137 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14138 {
14139 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14140 while (from < end)
14141 *to++ = *from++;
14142 }
14143
14144 if (to > toend)
14145 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14146 }
14147
14148
14149 /* Compute the pixel height and width of IT->glyph_row.
14150
14151 Most of the time, ascent and height of a display line will be equal
14152 to the max_ascent and max_height values of the display iterator
14153 structure. This is not the case if
14154
14155 1. We hit ZV without displaying anything. In this case, max_ascent
14156 and max_height will be zero.
14157
14158 2. We have some glyphs that don't contribute to the line height.
14159 (The glyph row flag contributes_to_line_height_p is for future
14160 pixmap extensions).
14161
14162 The first case is easily covered by using default values because in
14163 these cases, the line height does not really matter, except that it
14164 must not be zero. */
14165
14166 static void
14167 compute_line_metrics (it)
14168 struct it *it;
14169 {
14170 struct glyph_row *row = it->glyph_row;
14171 int area, i;
14172
14173 if (FRAME_WINDOW_P (it->f))
14174 {
14175 int i, min_y, max_y;
14176
14177 /* The line may consist of one space only, that was added to
14178 place the cursor on it. If so, the row's height hasn't been
14179 computed yet. */
14180 if (row->height == 0)
14181 {
14182 if (it->max_ascent + it->max_descent == 0)
14183 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14184 row->ascent = it->max_ascent;
14185 row->height = it->max_ascent + it->max_descent;
14186 row->phys_ascent = it->max_phys_ascent;
14187 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14188 }
14189
14190 /* Compute the width of this line. */
14191 row->pixel_width = row->x;
14192 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14193 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14194
14195 xassert (row->pixel_width >= 0);
14196 xassert (row->ascent >= 0 && row->height > 0);
14197
14198 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14199 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14200
14201 /* If first line's physical ascent is larger than its logical
14202 ascent, use the physical ascent, and make the row taller.
14203 This makes accented characters fully visible. */
14204 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14205 && row->phys_ascent > row->ascent)
14206 {
14207 row->height += row->phys_ascent - row->ascent;
14208 row->ascent = row->phys_ascent;
14209 }
14210
14211 /* Compute how much of the line is visible. */
14212 row->visible_height = row->height;
14213
14214 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14215 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14216
14217 if (row->y < min_y)
14218 row->visible_height -= min_y - row->y;
14219 if (row->y + row->height > max_y)
14220 row->visible_height -= row->y + row->height - max_y;
14221 }
14222 else
14223 {
14224 row->pixel_width = row->used[TEXT_AREA];
14225 if (row->continued_p)
14226 row->pixel_width -= it->continuation_pixel_width;
14227 else if (row->truncated_on_right_p)
14228 row->pixel_width -= it->truncation_pixel_width;
14229 row->ascent = row->phys_ascent = 0;
14230 row->height = row->phys_height = row->visible_height = 1;
14231 }
14232
14233 /* Compute a hash code for this row. */
14234 row->hash = 0;
14235 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14236 for (i = 0; i < row->used[area]; ++i)
14237 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14238 + row->glyphs[area][i].u.val
14239 + row->glyphs[area][i].face_id
14240 + row->glyphs[area][i].padding_p
14241 + (row->glyphs[area][i].type << 2));
14242
14243 it->max_ascent = it->max_descent = 0;
14244 it->max_phys_ascent = it->max_phys_descent = 0;
14245 }
14246
14247
14248 /* Append one space to the glyph row of iterator IT if doing a
14249 window-based redisplay. The space has the same face as
14250 IT->face_id. Value is non-zero if a space was added.
14251
14252 This function is called to make sure that there is always one glyph
14253 at the end of a glyph row that the cursor can be set on under
14254 window-systems. (If there weren't such a glyph we would not know
14255 how wide and tall a box cursor should be displayed).
14256
14257 At the same time this space let's a nicely handle clearing to the
14258 end of the line if the row ends in italic text. */
14259
14260 static int
14261 append_space_for_newline (it, default_face_p)
14262 struct it *it;
14263 int default_face_p;
14264 {
14265 if (FRAME_WINDOW_P (it->f))
14266 {
14267 int n = it->glyph_row->used[TEXT_AREA];
14268
14269 if (it->glyph_row->glyphs[TEXT_AREA] + n
14270 < it->glyph_row->glyphs[1 + TEXT_AREA])
14271 {
14272 /* Save some values that must not be changed.
14273 Must save IT->c and IT->len because otherwise
14274 ITERATOR_AT_END_P wouldn't work anymore after
14275 append_space_for_newline has been called. */
14276 enum display_element_type saved_what = it->what;
14277 int saved_c = it->c, saved_len = it->len;
14278 int saved_x = it->current_x;
14279 int saved_face_id = it->face_id;
14280 struct text_pos saved_pos;
14281 Lisp_Object saved_object;
14282 struct face *face;
14283
14284 saved_object = it->object;
14285 saved_pos = it->position;
14286
14287 it->what = IT_CHARACTER;
14288 bzero (&it->position, sizeof it->position);
14289 it->object = make_number (0);
14290 it->c = ' ';
14291 it->len = 1;
14292
14293 if (default_face_p)
14294 it->face_id = DEFAULT_FACE_ID;
14295 else if (it->face_before_selective_p)
14296 it->face_id = it->saved_face_id;
14297 face = FACE_FROM_ID (it->f, it->face_id);
14298 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14299
14300 PRODUCE_GLYPHS (it);
14301
14302 it->override_ascent = -1;
14303 it->constrain_row_ascent_descent_p = 0;
14304 it->current_x = saved_x;
14305 it->object = saved_object;
14306 it->position = saved_pos;
14307 it->what = saved_what;
14308 it->face_id = saved_face_id;
14309 it->len = saved_len;
14310 it->c = saved_c;
14311 return 1;
14312 }
14313 }
14314
14315 return 0;
14316 }
14317
14318
14319 /* Extend the face of the last glyph in the text area of IT->glyph_row
14320 to the end of the display line. Called from display_line.
14321 If the glyph row is empty, add a space glyph to it so that we
14322 know the face to draw. Set the glyph row flag fill_line_p. */
14323
14324 static void
14325 extend_face_to_end_of_line (it)
14326 struct it *it;
14327 {
14328 struct face *face;
14329 struct frame *f = it->f;
14330
14331 /* If line is already filled, do nothing. */
14332 if (it->current_x >= it->last_visible_x)
14333 return;
14334
14335 /* Face extension extends the background and box of IT->face_id
14336 to the end of the line. If the background equals the background
14337 of the frame, we don't have to do anything. */
14338 if (it->face_before_selective_p)
14339 face = FACE_FROM_ID (it->f, it->saved_face_id);
14340 else
14341 face = FACE_FROM_ID (f, it->face_id);
14342
14343 if (FRAME_WINDOW_P (f)
14344 && face->box == FACE_NO_BOX
14345 && face->background == FRAME_BACKGROUND_PIXEL (f)
14346 && !face->stipple)
14347 return;
14348
14349 /* Set the glyph row flag indicating that the face of the last glyph
14350 in the text area has to be drawn to the end of the text area. */
14351 it->glyph_row->fill_line_p = 1;
14352
14353 /* If current character of IT is not ASCII, make sure we have the
14354 ASCII face. This will be automatically undone the next time
14355 get_next_display_element returns a multibyte character. Note
14356 that the character will always be single byte in unibyte text. */
14357 if (!SINGLE_BYTE_CHAR_P (it->c))
14358 {
14359 it->face_id = FACE_FOR_CHAR (f, face, 0);
14360 }
14361
14362 if (FRAME_WINDOW_P (f))
14363 {
14364 /* If the row is empty, add a space with the current face of IT,
14365 so that we know which face to draw. */
14366 if (it->glyph_row->used[TEXT_AREA] == 0)
14367 {
14368 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14369 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14370 it->glyph_row->used[TEXT_AREA] = 1;
14371 }
14372 }
14373 else
14374 {
14375 /* Save some values that must not be changed. */
14376 int saved_x = it->current_x;
14377 struct text_pos saved_pos;
14378 Lisp_Object saved_object;
14379 enum display_element_type saved_what = it->what;
14380 int saved_face_id = it->face_id;
14381
14382 saved_object = it->object;
14383 saved_pos = it->position;
14384
14385 it->what = IT_CHARACTER;
14386 bzero (&it->position, sizeof it->position);
14387 it->object = make_number (0);
14388 it->c = ' ';
14389 it->len = 1;
14390 it->face_id = face->id;
14391
14392 PRODUCE_GLYPHS (it);
14393
14394 while (it->current_x <= it->last_visible_x)
14395 PRODUCE_GLYPHS (it);
14396
14397 /* Don't count these blanks really. It would let us insert a left
14398 truncation glyph below and make us set the cursor on them, maybe. */
14399 it->current_x = saved_x;
14400 it->object = saved_object;
14401 it->position = saved_pos;
14402 it->what = saved_what;
14403 it->face_id = saved_face_id;
14404 }
14405 }
14406
14407
14408 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14409 trailing whitespace. */
14410
14411 static int
14412 trailing_whitespace_p (charpos)
14413 int charpos;
14414 {
14415 int bytepos = CHAR_TO_BYTE (charpos);
14416 int c = 0;
14417
14418 while (bytepos < ZV_BYTE
14419 && (c = FETCH_CHAR (bytepos),
14420 c == ' ' || c == '\t'))
14421 ++bytepos;
14422
14423 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14424 {
14425 if (bytepos != PT_BYTE)
14426 return 1;
14427 }
14428 return 0;
14429 }
14430
14431
14432 /* Highlight trailing whitespace, if any, in ROW. */
14433
14434 void
14435 highlight_trailing_whitespace (f, row)
14436 struct frame *f;
14437 struct glyph_row *row;
14438 {
14439 int used = row->used[TEXT_AREA];
14440
14441 if (used)
14442 {
14443 struct glyph *start = row->glyphs[TEXT_AREA];
14444 struct glyph *glyph = start + used - 1;
14445
14446 /* Skip over glyphs inserted to display the cursor at the
14447 end of a line, for extending the face of the last glyph
14448 to the end of the line on terminals, and for truncation
14449 and continuation glyphs. */
14450 while (glyph >= start
14451 && glyph->type == CHAR_GLYPH
14452 && INTEGERP (glyph->object))
14453 --glyph;
14454
14455 /* If last glyph is a space or stretch, and it's trailing
14456 whitespace, set the face of all trailing whitespace glyphs in
14457 IT->glyph_row to `trailing-whitespace'. */
14458 if (glyph >= start
14459 && BUFFERP (glyph->object)
14460 && (glyph->type == STRETCH_GLYPH
14461 || (glyph->type == CHAR_GLYPH
14462 && glyph->u.ch == ' '))
14463 && trailing_whitespace_p (glyph->charpos))
14464 {
14465 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14466
14467 while (glyph >= start
14468 && BUFFERP (glyph->object)
14469 && (glyph->type == STRETCH_GLYPH
14470 || (glyph->type == CHAR_GLYPH
14471 && glyph->u.ch == ' ')))
14472 (glyph--)->face_id = face_id;
14473 }
14474 }
14475 }
14476
14477
14478 /* Value is non-zero if glyph row ROW in window W should be
14479 used to hold the cursor. */
14480
14481 static int
14482 cursor_row_p (w, row)
14483 struct window *w;
14484 struct glyph_row *row;
14485 {
14486 int cursor_row_p = 1;
14487
14488 if (PT == MATRIX_ROW_END_CHARPOS (row))
14489 {
14490 /* If the row ends with a newline from a string, we don't want
14491 the cursor there (if the row is continued it doesn't end in a
14492 newline). */
14493 if (CHARPOS (row->end.string_pos) >= 0
14494 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14495 cursor_row_p = row->continued_p;
14496
14497 /* If the row ends at ZV, display the cursor at the end of that
14498 row instead of at the start of the row below. */
14499 else if (row->ends_at_zv_p)
14500 cursor_row_p = 1;
14501 else
14502 cursor_row_p = 0;
14503 }
14504
14505 return cursor_row_p;
14506 }
14507
14508
14509 /* Construct the glyph row IT->glyph_row in the desired matrix of
14510 IT->w from text at the current position of IT. See dispextern.h
14511 for an overview of struct it. Value is non-zero if
14512 IT->glyph_row displays text, as opposed to a line displaying ZV
14513 only. */
14514
14515 static int
14516 display_line (it)
14517 struct it *it;
14518 {
14519 struct glyph_row *row = it->glyph_row;
14520 int overlay_arrow_bitmap;
14521 Lisp_Object overlay_arrow_string;
14522
14523 /* We always start displaying at hpos zero even if hscrolled. */
14524 xassert (it->hpos == 0 && it->current_x == 0);
14525
14526 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14527 >= it->w->desired_matrix->nrows)
14528 {
14529 it->w->nrows_scale_factor++;
14530 fonts_changed_p = 1;
14531 return 0;
14532 }
14533
14534 /* Is IT->w showing the region? */
14535 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14536
14537 /* Clear the result glyph row and enable it. */
14538 prepare_desired_row (row);
14539
14540 row->y = it->current_y;
14541 row->start = it->start;
14542 row->continuation_lines_width = it->continuation_lines_width;
14543 row->displays_text_p = 1;
14544 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14545 it->starts_in_middle_of_char_p = 0;
14546
14547 /* Arrange the overlays nicely for our purposes. Usually, we call
14548 display_line on only one line at a time, in which case this
14549 can't really hurt too much, or we call it on lines which appear
14550 one after another in the buffer, in which case all calls to
14551 recenter_overlay_lists but the first will be pretty cheap. */
14552 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14553
14554 /* Move over display elements that are not visible because we are
14555 hscrolled. This may stop at an x-position < IT->first_visible_x
14556 if the first glyph is partially visible or if we hit a line end. */
14557 if (it->current_x < it->first_visible_x)
14558 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14559 MOVE_TO_POS | MOVE_TO_X);
14560
14561 /* Get the initial row height. This is either the height of the
14562 text hscrolled, if there is any, or zero. */
14563 row->ascent = it->max_ascent;
14564 row->height = it->max_ascent + it->max_descent;
14565 row->phys_ascent = it->max_phys_ascent;
14566 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14567
14568 /* Loop generating characters. The loop is left with IT on the next
14569 character to display. */
14570 while (1)
14571 {
14572 int n_glyphs_before, hpos_before, x_before;
14573 int x, i, nglyphs;
14574 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14575
14576 /* Retrieve the next thing to display. Value is zero if end of
14577 buffer reached. */
14578 if (!get_next_display_element (it))
14579 {
14580 /* Maybe add a space at the end of this line that is used to
14581 display the cursor there under X. Set the charpos of the
14582 first glyph of blank lines not corresponding to any text
14583 to -1. */
14584 #ifdef HAVE_WINDOW_SYSTEM
14585 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14586 row->exact_window_width_line_p = 1;
14587 else
14588 #endif /* HAVE_WINDOW_SYSTEM */
14589 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14590 || row->used[TEXT_AREA] == 0)
14591 {
14592 row->glyphs[TEXT_AREA]->charpos = -1;
14593 row->displays_text_p = 0;
14594
14595 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14596 && (!MINI_WINDOW_P (it->w)
14597 || (minibuf_level && EQ (it->window, minibuf_window))))
14598 row->indicate_empty_line_p = 1;
14599 }
14600
14601 it->continuation_lines_width = 0;
14602 row->ends_at_zv_p = 1;
14603 break;
14604 }
14605
14606 /* Now, get the metrics of what we want to display. This also
14607 generates glyphs in `row' (which is IT->glyph_row). */
14608 n_glyphs_before = row->used[TEXT_AREA];
14609 x = it->current_x;
14610
14611 /* Remember the line height so far in case the next element doesn't
14612 fit on the line. */
14613 if (!it->truncate_lines_p)
14614 {
14615 ascent = it->max_ascent;
14616 descent = it->max_descent;
14617 phys_ascent = it->max_phys_ascent;
14618 phys_descent = it->max_phys_descent;
14619 }
14620
14621 PRODUCE_GLYPHS (it);
14622
14623 /* If this display element was in marginal areas, continue with
14624 the next one. */
14625 if (it->area != TEXT_AREA)
14626 {
14627 row->ascent = max (row->ascent, it->max_ascent);
14628 row->height = max (row->height, it->max_ascent + it->max_descent);
14629 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14630 row->phys_height = max (row->phys_height,
14631 it->max_phys_ascent + it->max_phys_descent);
14632 set_iterator_to_next (it, 1);
14633 continue;
14634 }
14635
14636 /* Does the display element fit on the line? If we truncate
14637 lines, we should draw past the right edge of the window. If
14638 we don't truncate, we want to stop so that we can display the
14639 continuation glyph before the right margin. If lines are
14640 continued, there are two possible strategies for characters
14641 resulting in more than 1 glyph (e.g. tabs): Display as many
14642 glyphs as possible in this line and leave the rest for the
14643 continuation line, or display the whole element in the next
14644 line. Original redisplay did the former, so we do it also. */
14645 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14646 hpos_before = it->hpos;
14647 x_before = x;
14648
14649 if (/* Not a newline. */
14650 nglyphs > 0
14651 /* Glyphs produced fit entirely in the line. */
14652 && it->current_x < it->last_visible_x)
14653 {
14654 it->hpos += nglyphs;
14655 row->ascent = max (row->ascent, it->max_ascent);
14656 row->height = max (row->height, it->max_ascent + it->max_descent);
14657 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14658 row->phys_height = max (row->phys_height,
14659 it->max_phys_ascent + it->max_phys_descent);
14660 if (it->current_x - it->pixel_width < it->first_visible_x)
14661 row->x = x - it->first_visible_x;
14662 }
14663 else
14664 {
14665 int new_x;
14666 struct glyph *glyph;
14667
14668 for (i = 0; i < nglyphs; ++i, x = new_x)
14669 {
14670 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14671 new_x = x + glyph->pixel_width;
14672
14673 if (/* Lines are continued. */
14674 !it->truncate_lines_p
14675 && (/* Glyph doesn't fit on the line. */
14676 new_x > it->last_visible_x
14677 /* Or it fits exactly on a window system frame. */
14678 || (new_x == it->last_visible_x
14679 && FRAME_WINDOW_P (it->f))))
14680 {
14681 /* End of a continued line. */
14682
14683 if (it->hpos == 0
14684 || (new_x == it->last_visible_x
14685 && FRAME_WINDOW_P (it->f)))
14686 {
14687 /* Current glyph is the only one on the line or
14688 fits exactly on the line. We must continue
14689 the line because we can't draw the cursor
14690 after the glyph. */
14691 row->continued_p = 1;
14692 it->current_x = new_x;
14693 it->continuation_lines_width += new_x;
14694 ++it->hpos;
14695 if (i == nglyphs - 1)
14696 {
14697 set_iterator_to_next (it, 1);
14698 #ifdef HAVE_WINDOW_SYSTEM
14699 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14700 {
14701 if (!get_next_display_element (it))
14702 {
14703 row->exact_window_width_line_p = 1;
14704 it->continuation_lines_width = 0;
14705 row->continued_p = 0;
14706 row->ends_at_zv_p = 1;
14707 }
14708 else if (ITERATOR_AT_END_OF_LINE_P (it))
14709 {
14710 row->continued_p = 0;
14711 row->exact_window_width_line_p = 1;
14712 }
14713 }
14714 #endif /* HAVE_WINDOW_SYSTEM */
14715 }
14716 }
14717 else if (CHAR_GLYPH_PADDING_P (*glyph)
14718 && !FRAME_WINDOW_P (it->f))
14719 {
14720 /* A padding glyph that doesn't fit on this line.
14721 This means the whole character doesn't fit
14722 on the line. */
14723 row->used[TEXT_AREA] = n_glyphs_before;
14724
14725 /* Fill the rest of the row with continuation
14726 glyphs like in 20.x. */
14727 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14728 < row->glyphs[1 + TEXT_AREA])
14729 produce_special_glyphs (it, IT_CONTINUATION);
14730
14731 row->continued_p = 1;
14732 it->current_x = x_before;
14733 it->continuation_lines_width += x_before;
14734
14735 /* Restore the height to what it was before the
14736 element not fitting on the line. */
14737 it->max_ascent = ascent;
14738 it->max_descent = descent;
14739 it->max_phys_ascent = phys_ascent;
14740 it->max_phys_descent = phys_descent;
14741 }
14742 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14743 {
14744 /* A TAB that extends past the right edge of the
14745 window. This produces a single glyph on
14746 window system frames. We leave the glyph in
14747 this row and let it fill the row, but don't
14748 consume the TAB. */
14749 it->continuation_lines_width += it->last_visible_x;
14750 row->ends_in_middle_of_char_p = 1;
14751 row->continued_p = 1;
14752 glyph->pixel_width = it->last_visible_x - x;
14753 it->starts_in_middle_of_char_p = 1;
14754 }
14755 else
14756 {
14757 /* Something other than a TAB that draws past
14758 the right edge of the window. Restore
14759 positions to values before the element. */
14760 row->used[TEXT_AREA] = n_glyphs_before + i;
14761
14762 /* Display continuation glyphs. */
14763 if (!FRAME_WINDOW_P (it->f))
14764 produce_special_glyphs (it, IT_CONTINUATION);
14765 row->continued_p = 1;
14766
14767 it->continuation_lines_width += x;
14768
14769 if (nglyphs > 1 && i > 0)
14770 {
14771 row->ends_in_middle_of_char_p = 1;
14772 it->starts_in_middle_of_char_p = 1;
14773 }
14774
14775 /* Restore the height to what it was before the
14776 element not fitting on the line. */
14777 it->max_ascent = ascent;
14778 it->max_descent = descent;
14779 it->max_phys_ascent = phys_ascent;
14780 it->max_phys_descent = phys_descent;
14781 }
14782
14783 break;
14784 }
14785 else if (new_x > it->first_visible_x)
14786 {
14787 /* Increment number of glyphs actually displayed. */
14788 ++it->hpos;
14789
14790 if (x < it->first_visible_x)
14791 /* Glyph is partially visible, i.e. row starts at
14792 negative X position. */
14793 row->x = x - it->first_visible_x;
14794 }
14795 else
14796 {
14797 /* Glyph is completely off the left margin of the
14798 window. This should not happen because of the
14799 move_it_in_display_line at the start of this
14800 function, unless the text display area of the
14801 window is empty. */
14802 xassert (it->first_visible_x <= it->last_visible_x);
14803 }
14804 }
14805
14806 row->ascent = max (row->ascent, it->max_ascent);
14807 row->height = max (row->height, it->max_ascent + it->max_descent);
14808 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14809 row->phys_height = max (row->phys_height,
14810 it->max_phys_ascent + it->max_phys_descent);
14811
14812 /* End of this display line if row is continued. */
14813 if (row->continued_p || row->ends_at_zv_p)
14814 break;
14815 }
14816
14817 at_end_of_line:
14818 /* Is this a line end? If yes, we're also done, after making
14819 sure that a non-default face is extended up to the right
14820 margin of the window. */
14821 if (ITERATOR_AT_END_OF_LINE_P (it))
14822 {
14823 int used_before = row->used[TEXT_AREA];
14824
14825 row->ends_in_newline_from_string_p = STRINGP (it->object);
14826
14827 #ifdef HAVE_WINDOW_SYSTEM
14828 /* Add a space at the end of the line that is used to
14829 display the cursor there. */
14830 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14831 append_space_for_newline (it, 0);
14832 #endif /* HAVE_WINDOW_SYSTEM */
14833
14834 /* Extend the face to the end of the line. */
14835 extend_face_to_end_of_line (it);
14836
14837 /* Make sure we have the position. */
14838 if (used_before == 0)
14839 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14840
14841 /* Consume the line end. This skips over invisible lines. */
14842 set_iterator_to_next (it, 1);
14843 it->continuation_lines_width = 0;
14844 break;
14845 }
14846
14847 /* Proceed with next display element. Note that this skips
14848 over lines invisible because of selective display. */
14849 set_iterator_to_next (it, 1);
14850
14851 /* If we truncate lines, we are done when the last displayed
14852 glyphs reach past the right margin of the window. */
14853 if (it->truncate_lines_p
14854 && (FRAME_WINDOW_P (it->f)
14855 ? (it->current_x >= it->last_visible_x)
14856 : (it->current_x > it->last_visible_x)))
14857 {
14858 /* Maybe add truncation glyphs. */
14859 if (!FRAME_WINDOW_P (it->f))
14860 {
14861 int i, n;
14862
14863 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14864 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14865 break;
14866
14867 for (n = row->used[TEXT_AREA]; i < n; ++i)
14868 {
14869 row->used[TEXT_AREA] = i;
14870 produce_special_glyphs (it, IT_TRUNCATION);
14871 }
14872 }
14873 #ifdef HAVE_WINDOW_SYSTEM
14874 else
14875 {
14876 /* Don't truncate if we can overflow newline into fringe. */
14877 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14878 {
14879 if (!get_next_display_element (it))
14880 {
14881 #ifdef HAVE_WINDOW_SYSTEM
14882 it->continuation_lines_width = 0;
14883 row->ends_at_zv_p = 1;
14884 row->exact_window_width_line_p = 1;
14885 break;
14886 #endif /* HAVE_WINDOW_SYSTEM */
14887 }
14888 if (ITERATOR_AT_END_OF_LINE_P (it))
14889 {
14890 row->exact_window_width_line_p = 1;
14891 goto at_end_of_line;
14892 }
14893 }
14894 }
14895 #endif /* HAVE_WINDOW_SYSTEM */
14896
14897 row->truncated_on_right_p = 1;
14898 it->continuation_lines_width = 0;
14899 reseat_at_next_visible_line_start (it, 0);
14900 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14901 it->hpos = hpos_before;
14902 it->current_x = x_before;
14903 break;
14904 }
14905 }
14906
14907 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14908 at the left window margin. */
14909 if (it->first_visible_x
14910 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14911 {
14912 if (!FRAME_WINDOW_P (it->f))
14913 insert_left_trunc_glyphs (it);
14914 row->truncated_on_left_p = 1;
14915 }
14916
14917 /* If the start of this line is the overlay arrow-position, then
14918 mark this glyph row as the one containing the overlay arrow.
14919 This is clearly a mess with variable size fonts. It would be
14920 better to let it be displayed like cursors under X. */
14921 if (! overlay_arrow_seen
14922 && (overlay_arrow_string
14923 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14924 !NILP (overlay_arrow_string)))
14925 {
14926 /* Overlay arrow in window redisplay is a fringe bitmap. */
14927 if (!FRAME_WINDOW_P (it->f))
14928 {
14929 struct glyph_row *arrow_row
14930 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14931 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14932 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14933 struct glyph *p = row->glyphs[TEXT_AREA];
14934 struct glyph *p2, *end;
14935
14936 /* Copy the arrow glyphs. */
14937 while (glyph < arrow_end)
14938 *p++ = *glyph++;
14939
14940 /* Throw away padding glyphs. */
14941 p2 = p;
14942 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14943 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14944 ++p2;
14945 if (p2 > p)
14946 {
14947 while (p2 < end)
14948 *p++ = *p2++;
14949 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14950 }
14951 }
14952
14953 overlay_arrow_seen = 1;
14954 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14955 row->overlay_arrow_p = 1;
14956 }
14957
14958 /* Compute pixel dimensions of this line. */
14959 compute_line_metrics (it);
14960
14961 /* Remember the position at which this line ends. */
14962 row->end = it->current;
14963
14964 /* Save fringe bitmaps in this row. */
14965 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14966 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14967 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14968 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14969
14970 it->left_user_fringe_bitmap = 0;
14971 it->left_user_fringe_face_id = 0;
14972 it->right_user_fringe_bitmap = 0;
14973 it->right_user_fringe_face_id = 0;
14974
14975 /* Maybe set the cursor. */
14976 if (it->w->cursor.vpos < 0
14977 && PT >= MATRIX_ROW_START_CHARPOS (row)
14978 && PT <= MATRIX_ROW_END_CHARPOS (row)
14979 && cursor_row_p (it->w, row))
14980 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14981
14982 /* Highlight trailing whitespace. */
14983 if (!NILP (Vshow_trailing_whitespace))
14984 highlight_trailing_whitespace (it->f, it->glyph_row);
14985
14986 /* Prepare for the next line. This line starts horizontally at (X
14987 HPOS) = (0 0). Vertical positions are incremented. As a
14988 convenience for the caller, IT->glyph_row is set to the next
14989 row to be used. */
14990 it->current_x = it->hpos = 0;
14991 it->current_y += row->height;
14992 ++it->vpos;
14993 ++it->glyph_row;
14994 it->start = it->current;
14995 return row->displays_text_p;
14996 }
14997
14998
14999 \f
15000 /***********************************************************************
15001 Menu Bar
15002 ***********************************************************************/
15003
15004 /* Redisplay the menu bar in the frame for window W.
15005
15006 The menu bar of X frames that don't have X toolkit support is
15007 displayed in a special window W->frame->menu_bar_window.
15008
15009 The menu bar of terminal frames is treated specially as far as
15010 glyph matrices are concerned. Menu bar lines are not part of
15011 windows, so the update is done directly on the frame matrix rows
15012 for the menu bar. */
15013
15014 static void
15015 display_menu_bar (w)
15016 struct window *w;
15017 {
15018 struct frame *f = XFRAME (WINDOW_FRAME (w));
15019 struct it it;
15020 Lisp_Object items;
15021 int i;
15022
15023 /* Don't do all this for graphical frames. */
15024 #ifdef HAVE_NTGUI
15025 if (!NILP (Vwindow_system))
15026 return;
15027 #endif
15028 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15029 if (FRAME_X_P (f))
15030 return;
15031 #endif
15032 #ifdef MAC_OS
15033 if (FRAME_MAC_P (f))
15034 return;
15035 #endif
15036
15037 #ifdef USE_X_TOOLKIT
15038 xassert (!FRAME_WINDOW_P (f));
15039 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15040 it.first_visible_x = 0;
15041 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15042 #else /* not USE_X_TOOLKIT */
15043 if (FRAME_WINDOW_P (f))
15044 {
15045 /* Menu bar lines are displayed in the desired matrix of the
15046 dummy window menu_bar_window. */
15047 struct window *menu_w;
15048 xassert (WINDOWP (f->menu_bar_window));
15049 menu_w = XWINDOW (f->menu_bar_window);
15050 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15051 MENU_FACE_ID);
15052 it.first_visible_x = 0;
15053 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15054 }
15055 else
15056 {
15057 /* This is a TTY frame, i.e. character hpos/vpos are used as
15058 pixel x/y. */
15059 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15060 MENU_FACE_ID);
15061 it.first_visible_x = 0;
15062 it.last_visible_x = FRAME_COLS (f);
15063 }
15064 #endif /* not USE_X_TOOLKIT */
15065
15066 if (! mode_line_inverse_video)
15067 /* Force the menu-bar to be displayed in the default face. */
15068 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15069
15070 /* Clear all rows of the menu bar. */
15071 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15072 {
15073 struct glyph_row *row = it.glyph_row + i;
15074 clear_glyph_row (row);
15075 row->enabled_p = 1;
15076 row->full_width_p = 1;
15077 }
15078
15079 /* Display all items of the menu bar. */
15080 items = FRAME_MENU_BAR_ITEMS (it.f);
15081 for (i = 0; i < XVECTOR (items)->size; i += 4)
15082 {
15083 Lisp_Object string;
15084
15085 /* Stop at nil string. */
15086 string = AREF (items, i + 1);
15087 if (NILP (string))
15088 break;
15089
15090 /* Remember where item was displayed. */
15091 AREF (items, i + 3) = make_number (it.hpos);
15092
15093 /* Display the item, pad with one space. */
15094 if (it.current_x < it.last_visible_x)
15095 display_string (NULL, string, Qnil, 0, 0, &it,
15096 SCHARS (string) + 1, 0, 0, -1);
15097 }
15098
15099 /* Fill out the line with spaces. */
15100 if (it.current_x < it.last_visible_x)
15101 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15102
15103 /* Compute the total height of the lines. */
15104 compute_line_metrics (&it);
15105 }
15106
15107
15108 \f
15109 /***********************************************************************
15110 Mode Line
15111 ***********************************************************************/
15112
15113 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15114 FORCE is non-zero, redisplay mode lines unconditionally.
15115 Otherwise, redisplay only mode lines that are garbaged. Value is
15116 the number of windows whose mode lines were redisplayed. */
15117
15118 static int
15119 redisplay_mode_lines (window, force)
15120 Lisp_Object window;
15121 int force;
15122 {
15123 int nwindows = 0;
15124
15125 while (!NILP (window))
15126 {
15127 struct window *w = XWINDOW (window);
15128
15129 if (WINDOWP (w->hchild))
15130 nwindows += redisplay_mode_lines (w->hchild, force);
15131 else if (WINDOWP (w->vchild))
15132 nwindows += redisplay_mode_lines (w->vchild, force);
15133 else if (force
15134 || FRAME_GARBAGED_P (XFRAME (w->frame))
15135 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15136 {
15137 struct text_pos lpoint;
15138 struct buffer *old = current_buffer;
15139
15140 /* Set the window's buffer for the mode line display. */
15141 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15142 set_buffer_internal_1 (XBUFFER (w->buffer));
15143
15144 /* Point refers normally to the selected window. For any
15145 other window, set up appropriate value. */
15146 if (!EQ (window, selected_window))
15147 {
15148 struct text_pos pt;
15149
15150 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15151 if (CHARPOS (pt) < BEGV)
15152 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15153 else if (CHARPOS (pt) > (ZV - 1))
15154 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15155 else
15156 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15157 }
15158
15159 /* Display mode lines. */
15160 clear_glyph_matrix (w->desired_matrix);
15161 if (display_mode_lines (w))
15162 {
15163 ++nwindows;
15164 w->must_be_updated_p = 1;
15165 }
15166
15167 /* Restore old settings. */
15168 set_buffer_internal_1 (old);
15169 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15170 }
15171
15172 window = w->next;
15173 }
15174
15175 return nwindows;
15176 }
15177
15178
15179 /* Display the mode and/or top line of window W. Value is the number
15180 of mode lines displayed. */
15181
15182 static int
15183 display_mode_lines (w)
15184 struct window *w;
15185 {
15186 Lisp_Object old_selected_window, old_selected_frame;
15187 int n = 0;
15188
15189 old_selected_frame = selected_frame;
15190 selected_frame = w->frame;
15191 old_selected_window = selected_window;
15192 XSETWINDOW (selected_window, w);
15193
15194 /* These will be set while the mode line specs are processed. */
15195 line_number_displayed = 0;
15196 w->column_number_displayed = Qnil;
15197
15198 if (WINDOW_WANTS_MODELINE_P (w))
15199 {
15200 struct window *sel_w = XWINDOW (old_selected_window);
15201
15202 /* Select mode line face based on the real selected window. */
15203 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15204 current_buffer->mode_line_format);
15205 ++n;
15206 }
15207
15208 if (WINDOW_WANTS_HEADER_LINE_P (w))
15209 {
15210 display_mode_line (w, HEADER_LINE_FACE_ID,
15211 current_buffer->header_line_format);
15212 ++n;
15213 }
15214
15215 selected_frame = old_selected_frame;
15216 selected_window = old_selected_window;
15217 return n;
15218 }
15219
15220
15221 /* Display mode or top line of window W. FACE_ID specifies which line
15222 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15223 FORMAT is the mode line format to display. Value is the pixel
15224 height of the mode line displayed. */
15225
15226 static int
15227 display_mode_line (w, face_id, format)
15228 struct window *w;
15229 enum face_id face_id;
15230 Lisp_Object format;
15231 {
15232 struct it it;
15233 struct face *face;
15234
15235 init_iterator (&it, w, -1, -1, NULL, face_id);
15236 prepare_desired_row (it.glyph_row);
15237
15238 it.glyph_row->mode_line_p = 1;
15239
15240 if (! mode_line_inverse_video)
15241 /* Force the mode-line to be displayed in the default face. */
15242 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15243
15244 /* Temporarily make frame's keyboard the current kboard so that
15245 kboard-local variables in the mode_line_format will get the right
15246 values. */
15247 push_frame_kboard (it.f);
15248 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15249 pop_frame_kboard ();
15250
15251 /* Fill up with spaces. */
15252 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15253
15254 compute_line_metrics (&it);
15255 it.glyph_row->full_width_p = 1;
15256 it.glyph_row->continued_p = 0;
15257 it.glyph_row->truncated_on_left_p = 0;
15258 it.glyph_row->truncated_on_right_p = 0;
15259
15260 /* Make a 3D mode-line have a shadow at its right end. */
15261 face = FACE_FROM_ID (it.f, face_id);
15262 extend_face_to_end_of_line (&it);
15263 if (face->box != FACE_NO_BOX)
15264 {
15265 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15266 + it.glyph_row->used[TEXT_AREA] - 1);
15267 last->right_box_line_p = 1;
15268 }
15269
15270 return it.glyph_row->height;
15271 }
15272
15273 /* Alist that caches the results of :propertize.
15274 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15275 Lisp_Object mode_line_proptrans_alist;
15276
15277 /* List of strings making up the mode-line. */
15278 Lisp_Object mode_line_string_list;
15279
15280 /* Base face property when building propertized mode line string. */
15281 static Lisp_Object mode_line_string_face;
15282 static Lisp_Object mode_line_string_face_prop;
15283
15284
15285 /* Contribute ELT to the mode line for window IT->w. How it
15286 translates into text depends on its data type.
15287
15288 IT describes the display environment in which we display, as usual.
15289
15290 DEPTH is the depth in recursion. It is used to prevent
15291 infinite recursion here.
15292
15293 FIELD_WIDTH is the number of characters the display of ELT should
15294 occupy in the mode line, and PRECISION is the maximum number of
15295 characters to display from ELT's representation. See
15296 display_string for details.
15297
15298 Returns the hpos of the end of the text generated by ELT.
15299
15300 PROPS is a property list to add to any string we encounter.
15301
15302 If RISKY is nonzero, remove (disregard) any properties in any string
15303 we encounter, and ignore :eval and :propertize.
15304
15305 If the global variable `frame_title_ptr' is non-NULL, then the output
15306 is passed to `store_frame_title' instead of `display_string'. */
15307
15308 static int
15309 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15310 struct it *it;
15311 int depth;
15312 int field_width, precision;
15313 Lisp_Object elt, props;
15314 int risky;
15315 {
15316 int n = 0, field, prec;
15317 int literal = 0;
15318
15319 tail_recurse:
15320 if (depth > 100)
15321 elt = build_string ("*too-deep*");
15322
15323 depth++;
15324
15325 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15326 {
15327 case Lisp_String:
15328 {
15329 /* A string: output it and check for %-constructs within it. */
15330 unsigned char c;
15331 const unsigned char *this, *lisp_string;
15332
15333 if (!NILP (props) || risky)
15334 {
15335 Lisp_Object oprops, aelt;
15336 oprops = Ftext_properties_at (make_number (0), elt);
15337
15338 if (NILP (Fequal (props, oprops)) || risky)
15339 {
15340 /* If the starting string has properties,
15341 merge the specified ones onto the existing ones. */
15342 if (! NILP (oprops) && !risky)
15343 {
15344 Lisp_Object tem;
15345
15346 oprops = Fcopy_sequence (oprops);
15347 tem = props;
15348 while (CONSP (tem))
15349 {
15350 oprops = Fplist_put (oprops, XCAR (tem),
15351 XCAR (XCDR (tem)));
15352 tem = XCDR (XCDR (tem));
15353 }
15354 props = oprops;
15355 }
15356
15357 aelt = Fassoc (elt, mode_line_proptrans_alist);
15358 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15359 {
15360 mode_line_proptrans_alist
15361 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15362 elt = XCAR (aelt);
15363 }
15364 else
15365 {
15366 Lisp_Object tem;
15367
15368 elt = Fcopy_sequence (elt);
15369 Fset_text_properties (make_number (0), Flength (elt),
15370 props, elt);
15371 /* Add this item to mode_line_proptrans_alist. */
15372 mode_line_proptrans_alist
15373 = Fcons (Fcons (elt, props),
15374 mode_line_proptrans_alist);
15375 /* Truncate mode_line_proptrans_alist
15376 to at most 50 elements. */
15377 tem = Fnthcdr (make_number (50),
15378 mode_line_proptrans_alist);
15379 if (! NILP (tem))
15380 XSETCDR (tem, Qnil);
15381 }
15382 }
15383 }
15384
15385 this = SDATA (elt);
15386 lisp_string = this;
15387
15388 if (literal)
15389 {
15390 prec = precision - n;
15391 if (frame_title_ptr)
15392 n += store_frame_title (SDATA (elt), -1, prec);
15393 else if (!NILP (mode_line_string_list))
15394 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15395 else
15396 n += display_string (NULL, elt, Qnil, 0, 0, it,
15397 0, prec, 0, STRING_MULTIBYTE (elt));
15398
15399 break;
15400 }
15401
15402 while ((precision <= 0 || n < precision)
15403 && *this
15404 && (frame_title_ptr
15405 || !NILP (mode_line_string_list)
15406 || it->current_x < it->last_visible_x))
15407 {
15408 const unsigned char *last = this;
15409
15410 /* Advance to end of string or next format specifier. */
15411 while ((c = *this++) != '\0' && c != '%')
15412 ;
15413
15414 if (this - 1 != last)
15415 {
15416 /* Output to end of string or up to '%'. Field width
15417 is length of string. Don't output more than
15418 PRECISION allows us. */
15419 --this;
15420
15421 prec = chars_in_text (last, this - last);
15422 if (precision > 0 && prec > precision - n)
15423 prec = precision - n;
15424
15425 if (frame_title_ptr)
15426 n += store_frame_title (last, 0, prec);
15427 else if (!NILP (mode_line_string_list))
15428 {
15429 int bytepos = last - lisp_string;
15430 int charpos = string_byte_to_char (elt, bytepos);
15431 n += store_mode_line_string (NULL,
15432 Fsubstring (elt, make_number (charpos),
15433 make_number (charpos + prec)),
15434 0, 0, 0, Qnil);
15435 }
15436 else
15437 {
15438 int bytepos = last - lisp_string;
15439 int charpos = string_byte_to_char (elt, bytepos);
15440 n += display_string (NULL, elt, Qnil, 0, charpos,
15441 it, 0, prec, 0,
15442 STRING_MULTIBYTE (elt));
15443 }
15444 }
15445 else /* c == '%' */
15446 {
15447 const unsigned char *percent_position = this;
15448
15449 /* Get the specified minimum width. Zero means
15450 don't pad. */
15451 field = 0;
15452 while ((c = *this++) >= '0' && c <= '9')
15453 field = field * 10 + c - '0';
15454
15455 /* Don't pad beyond the total padding allowed. */
15456 if (field_width - n > 0 && field > field_width - n)
15457 field = field_width - n;
15458
15459 /* Note that either PRECISION <= 0 or N < PRECISION. */
15460 prec = precision - n;
15461
15462 if (c == 'M')
15463 n += display_mode_element (it, depth, field, prec,
15464 Vglobal_mode_string, props,
15465 risky);
15466 else if (c != 0)
15467 {
15468 int multibyte;
15469 int bytepos, charpos;
15470 unsigned char *spec;
15471
15472 bytepos = percent_position - lisp_string;
15473 charpos = (STRING_MULTIBYTE (elt)
15474 ? string_byte_to_char (elt, bytepos)
15475 : bytepos);
15476
15477 spec
15478 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15479
15480 if (frame_title_ptr)
15481 n += store_frame_title (spec, field, prec);
15482 else if (!NILP (mode_line_string_list))
15483 {
15484 int len = strlen (spec);
15485 Lisp_Object tem = make_string (spec, len);
15486 props = Ftext_properties_at (make_number (charpos), elt);
15487 /* Should only keep face property in props */
15488 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15489 }
15490 else
15491 {
15492 int nglyphs_before, nwritten;
15493
15494 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15495 nwritten = display_string (spec, Qnil, elt,
15496 charpos, 0, it,
15497 field, prec, 0,
15498 multibyte);
15499
15500 /* Assign to the glyphs written above the
15501 string where the `%x' came from, position
15502 of the `%'. */
15503 if (nwritten > 0)
15504 {
15505 struct glyph *glyph
15506 = (it->glyph_row->glyphs[TEXT_AREA]
15507 + nglyphs_before);
15508 int i;
15509
15510 for (i = 0; i < nwritten; ++i)
15511 {
15512 glyph[i].object = elt;
15513 glyph[i].charpos = charpos;
15514 }
15515
15516 n += nwritten;
15517 }
15518 }
15519 }
15520 else /* c == 0 */
15521 break;
15522 }
15523 }
15524 }
15525 break;
15526
15527 case Lisp_Symbol:
15528 /* A symbol: process the value of the symbol recursively
15529 as if it appeared here directly. Avoid error if symbol void.
15530 Special case: if value of symbol is a string, output the string
15531 literally. */
15532 {
15533 register Lisp_Object tem;
15534
15535 /* If the variable is not marked as risky to set
15536 then its contents are risky to use. */
15537 if (NILP (Fget (elt, Qrisky_local_variable)))
15538 risky = 1;
15539
15540 tem = Fboundp (elt);
15541 if (!NILP (tem))
15542 {
15543 tem = Fsymbol_value (elt);
15544 /* If value is a string, output that string literally:
15545 don't check for % within it. */
15546 if (STRINGP (tem))
15547 literal = 1;
15548
15549 if (!EQ (tem, elt))
15550 {
15551 /* Give up right away for nil or t. */
15552 elt = tem;
15553 goto tail_recurse;
15554 }
15555 }
15556 }
15557 break;
15558
15559 case Lisp_Cons:
15560 {
15561 register Lisp_Object car, tem;
15562
15563 /* A cons cell: five distinct cases.
15564 If first element is :eval or :propertize, do something special.
15565 If first element is a string or a cons, process all the elements
15566 and effectively concatenate them.
15567 If first element is a negative number, truncate displaying cdr to
15568 at most that many characters. If positive, pad (with spaces)
15569 to at least that many characters.
15570 If first element is a symbol, process the cadr or caddr recursively
15571 according to whether the symbol's value is non-nil or nil. */
15572 car = XCAR (elt);
15573 if (EQ (car, QCeval))
15574 {
15575 /* An element of the form (:eval FORM) means evaluate FORM
15576 and use the result as mode line elements. */
15577
15578 if (risky)
15579 break;
15580
15581 if (CONSP (XCDR (elt)))
15582 {
15583 Lisp_Object spec;
15584 spec = safe_eval (XCAR (XCDR (elt)));
15585 n += display_mode_element (it, depth, field_width - n,
15586 precision - n, spec, props,
15587 risky);
15588 }
15589 }
15590 else if (EQ (car, QCpropertize))
15591 {
15592 /* An element of the form (:propertize ELT PROPS...)
15593 means display ELT but applying properties PROPS. */
15594
15595 if (risky)
15596 break;
15597
15598 if (CONSP (XCDR (elt)))
15599 n += display_mode_element (it, depth, field_width - n,
15600 precision - n, XCAR (XCDR (elt)),
15601 XCDR (XCDR (elt)), risky);
15602 }
15603 else if (SYMBOLP (car))
15604 {
15605 tem = Fboundp (car);
15606 elt = XCDR (elt);
15607 if (!CONSP (elt))
15608 goto invalid;
15609 /* elt is now the cdr, and we know it is a cons cell.
15610 Use its car if CAR has a non-nil value. */
15611 if (!NILP (tem))
15612 {
15613 tem = Fsymbol_value (car);
15614 if (!NILP (tem))
15615 {
15616 elt = XCAR (elt);
15617 goto tail_recurse;
15618 }
15619 }
15620 /* Symbol's value is nil (or symbol is unbound)
15621 Get the cddr of the original list
15622 and if possible find the caddr and use that. */
15623 elt = XCDR (elt);
15624 if (NILP (elt))
15625 break;
15626 else if (!CONSP (elt))
15627 goto invalid;
15628 elt = XCAR (elt);
15629 goto tail_recurse;
15630 }
15631 else if (INTEGERP (car))
15632 {
15633 register int lim = XINT (car);
15634 elt = XCDR (elt);
15635 if (lim < 0)
15636 {
15637 /* Negative int means reduce maximum width. */
15638 if (precision <= 0)
15639 precision = -lim;
15640 else
15641 precision = min (precision, -lim);
15642 }
15643 else if (lim > 0)
15644 {
15645 /* Padding specified. Don't let it be more than
15646 current maximum. */
15647 if (precision > 0)
15648 lim = min (precision, lim);
15649
15650 /* If that's more padding than already wanted, queue it.
15651 But don't reduce padding already specified even if
15652 that is beyond the current truncation point. */
15653 field_width = max (lim, field_width);
15654 }
15655 goto tail_recurse;
15656 }
15657 else if (STRINGP (car) || CONSP (car))
15658 {
15659 register int limit = 50;
15660 /* Limit is to protect against circular lists. */
15661 while (CONSP (elt)
15662 && --limit > 0
15663 && (precision <= 0 || n < precision))
15664 {
15665 n += display_mode_element (it, depth, field_width - n,
15666 precision - n, XCAR (elt),
15667 props, risky);
15668 elt = XCDR (elt);
15669 }
15670 }
15671 }
15672 break;
15673
15674 default:
15675 invalid:
15676 elt = build_string ("*invalid*");
15677 goto tail_recurse;
15678 }
15679
15680 /* Pad to FIELD_WIDTH. */
15681 if (field_width > 0 && n < field_width)
15682 {
15683 if (frame_title_ptr)
15684 n += store_frame_title ("", field_width - n, 0);
15685 else if (!NILP (mode_line_string_list))
15686 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15687 else
15688 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15689 0, 0, 0);
15690 }
15691
15692 return n;
15693 }
15694
15695 /* Store a mode-line string element in mode_line_string_list.
15696
15697 If STRING is non-null, display that C string. Otherwise, the Lisp
15698 string LISP_STRING is displayed.
15699
15700 FIELD_WIDTH is the minimum number of output glyphs to produce.
15701 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15702 with spaces. FIELD_WIDTH <= 0 means don't pad.
15703
15704 PRECISION is the maximum number of characters to output from
15705 STRING. PRECISION <= 0 means don't truncate the string.
15706
15707 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15708 properties to the string.
15709
15710 PROPS are the properties to add to the string.
15711 The mode_line_string_face face property is always added to the string.
15712 */
15713
15714 static int
15715 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15716 char *string;
15717 Lisp_Object lisp_string;
15718 int copy_string;
15719 int field_width;
15720 int precision;
15721 Lisp_Object props;
15722 {
15723 int len;
15724 int n = 0;
15725
15726 if (string != NULL)
15727 {
15728 len = strlen (string);
15729 if (precision > 0 && len > precision)
15730 len = precision;
15731 lisp_string = make_string (string, len);
15732 if (NILP (props))
15733 props = mode_line_string_face_prop;
15734 else if (!NILP (mode_line_string_face))
15735 {
15736 Lisp_Object face = Fplist_get (props, Qface);
15737 props = Fcopy_sequence (props);
15738 if (NILP (face))
15739 face = mode_line_string_face;
15740 else
15741 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15742 props = Fplist_put (props, Qface, face);
15743 }
15744 Fadd_text_properties (make_number (0), make_number (len),
15745 props, lisp_string);
15746 }
15747 else
15748 {
15749 len = XFASTINT (Flength (lisp_string));
15750 if (precision > 0 && len > precision)
15751 {
15752 len = precision;
15753 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15754 precision = -1;
15755 }
15756 if (!NILP (mode_line_string_face))
15757 {
15758 Lisp_Object face;
15759 if (NILP (props))
15760 props = Ftext_properties_at (make_number (0), lisp_string);
15761 face = Fplist_get (props, Qface);
15762 if (NILP (face))
15763 face = mode_line_string_face;
15764 else
15765 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15766 props = Fcons (Qface, Fcons (face, Qnil));
15767 if (copy_string)
15768 lisp_string = Fcopy_sequence (lisp_string);
15769 }
15770 if (!NILP (props))
15771 Fadd_text_properties (make_number (0), make_number (len),
15772 props, lisp_string);
15773 }
15774
15775 if (len > 0)
15776 {
15777 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15778 n += len;
15779 }
15780
15781 if (field_width > len)
15782 {
15783 field_width -= len;
15784 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15785 if (!NILP (props))
15786 Fadd_text_properties (make_number (0), make_number (field_width),
15787 props, lisp_string);
15788 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15789 n += field_width;
15790 }
15791
15792 return n;
15793 }
15794
15795
15796 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15797 0, 3, 0,
15798 doc: /* Return the mode-line of selected window as a string.
15799 First optional arg FORMAT specifies a different format string (see
15800 `mode-line-format' for details) to use. If FORMAT is t, return
15801 the buffer's header-line. Second optional arg WINDOW specifies a
15802 different window to use as the context for the formatting.
15803 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15804 (format, window, no_props)
15805 Lisp_Object format, window, no_props;
15806 {
15807 struct it it;
15808 int len;
15809 struct window *w;
15810 struct buffer *old_buffer = NULL;
15811 enum face_id face_id = DEFAULT_FACE_ID;
15812
15813 if (NILP (window))
15814 window = selected_window;
15815 CHECK_WINDOW (window);
15816 w = XWINDOW (window);
15817 CHECK_BUFFER (w->buffer);
15818
15819 if (XBUFFER (w->buffer) != current_buffer)
15820 {
15821 old_buffer = current_buffer;
15822 set_buffer_internal_1 (XBUFFER (w->buffer));
15823 }
15824
15825 if (NILP (format) || EQ (format, Qt))
15826 {
15827 face_id = (NILP (format)
15828 ? CURRENT_MODE_LINE_FACE_ID (w)
15829 : HEADER_LINE_FACE_ID);
15830 format = (NILP (format)
15831 ? current_buffer->mode_line_format
15832 : current_buffer->header_line_format);
15833 }
15834
15835 init_iterator (&it, w, -1, -1, NULL, face_id);
15836
15837 if (NILP (no_props))
15838 {
15839 mode_line_string_face
15840 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15841 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15842 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15843
15844 mode_line_string_face_prop
15845 = (NILP (mode_line_string_face) ? Qnil
15846 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15847
15848 /* We need a dummy last element in mode_line_string_list to
15849 indicate we are building the propertized mode-line string.
15850 Using mode_line_string_face_prop here GC protects it. */
15851 mode_line_string_list
15852 = Fcons (mode_line_string_face_prop, Qnil);
15853 frame_title_ptr = NULL;
15854 }
15855 else
15856 {
15857 mode_line_string_face_prop = Qnil;
15858 mode_line_string_list = Qnil;
15859 frame_title_ptr = frame_title_buf;
15860 }
15861
15862 push_frame_kboard (it.f);
15863 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15864 pop_frame_kboard ();
15865
15866 if (old_buffer)
15867 set_buffer_internal_1 (old_buffer);
15868
15869 if (NILP (no_props))
15870 {
15871 Lisp_Object str;
15872 mode_line_string_list = Fnreverse (mode_line_string_list);
15873 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15874 make_string ("", 0));
15875 mode_line_string_face_prop = Qnil;
15876 mode_line_string_list = Qnil;
15877 return str;
15878 }
15879
15880 len = frame_title_ptr - frame_title_buf;
15881 if (len > 0 && frame_title_ptr[-1] == '-')
15882 {
15883 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15884 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15885 ;
15886 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15887 if (len > frame_title_ptr - frame_title_buf)
15888 len = frame_title_ptr - frame_title_buf;
15889 }
15890
15891 frame_title_ptr = NULL;
15892 return make_string (frame_title_buf, len);
15893 }
15894
15895 /* Write a null-terminated, right justified decimal representation of
15896 the positive integer D to BUF using a minimal field width WIDTH. */
15897
15898 static void
15899 pint2str (buf, width, d)
15900 register char *buf;
15901 register int width;
15902 register int d;
15903 {
15904 register char *p = buf;
15905
15906 if (d <= 0)
15907 *p++ = '0';
15908 else
15909 {
15910 while (d > 0)
15911 {
15912 *p++ = d % 10 + '0';
15913 d /= 10;
15914 }
15915 }
15916
15917 for (width -= (int) (p - buf); width > 0; --width)
15918 *p++ = ' ';
15919 *p-- = '\0';
15920 while (p > buf)
15921 {
15922 d = *buf;
15923 *buf++ = *p;
15924 *p-- = d;
15925 }
15926 }
15927
15928 /* Write a null-terminated, right justified decimal and "human
15929 readable" representation of the nonnegative integer D to BUF using
15930 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15931
15932 static const char power_letter[] =
15933 {
15934 0, /* not used */
15935 'k', /* kilo */
15936 'M', /* mega */
15937 'G', /* giga */
15938 'T', /* tera */
15939 'P', /* peta */
15940 'E', /* exa */
15941 'Z', /* zetta */
15942 'Y' /* yotta */
15943 };
15944
15945 static void
15946 pint2hrstr (buf, width, d)
15947 char *buf;
15948 int width;
15949 int d;
15950 {
15951 /* We aim to represent the nonnegative integer D as
15952 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15953 int quotient = d;
15954 int remainder = 0;
15955 /* -1 means: do not use TENTHS. */
15956 int tenths = -1;
15957 int exponent = 0;
15958
15959 /* Length of QUOTIENT.TENTHS as a string. */
15960 int length;
15961
15962 char * psuffix;
15963 char * p;
15964
15965 if (1000 <= quotient)
15966 {
15967 /* Scale to the appropriate EXPONENT. */
15968 do
15969 {
15970 remainder = quotient % 1000;
15971 quotient /= 1000;
15972 exponent++;
15973 }
15974 while (1000 <= quotient);
15975
15976 /* Round to nearest and decide whether to use TENTHS or not. */
15977 if (quotient <= 9)
15978 {
15979 tenths = remainder / 100;
15980 if (50 <= remainder % 100)
15981 if (tenths < 9)
15982 tenths++;
15983 else
15984 {
15985 quotient++;
15986 if (quotient == 10)
15987 tenths = -1;
15988 else
15989 tenths = 0;
15990 }
15991 }
15992 else
15993 if (500 <= remainder)
15994 if (quotient < 999)
15995 quotient++;
15996 else
15997 {
15998 quotient = 1;
15999 exponent++;
16000 tenths = 0;
16001 }
16002 }
16003
16004 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16005 if (tenths == -1 && quotient <= 99)
16006 if (quotient <= 9)
16007 length = 1;
16008 else
16009 length = 2;
16010 else
16011 length = 3;
16012 p = psuffix = buf + max (width, length);
16013
16014 /* Print EXPONENT. */
16015 if (exponent)
16016 *psuffix++ = power_letter[exponent];
16017 *psuffix = '\0';
16018
16019 /* Print TENTHS. */
16020 if (tenths >= 0)
16021 {
16022 *--p = '0' + tenths;
16023 *--p = '.';
16024 }
16025
16026 /* Print QUOTIENT. */
16027 do
16028 {
16029 int digit = quotient % 10;
16030 *--p = '0' + digit;
16031 }
16032 while ((quotient /= 10) != 0);
16033
16034 /* Print leading spaces. */
16035 while (buf < p)
16036 *--p = ' ';
16037 }
16038
16039 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16040 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16041 type of CODING_SYSTEM. Return updated pointer into BUF. */
16042
16043 static unsigned char invalid_eol_type[] = "(*invalid*)";
16044
16045 static char *
16046 decode_mode_spec_coding (coding_system, buf, eol_flag)
16047 Lisp_Object coding_system;
16048 register char *buf;
16049 int eol_flag;
16050 {
16051 Lisp_Object val;
16052 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16053 const unsigned char *eol_str;
16054 int eol_str_len;
16055 /* The EOL conversion we are using. */
16056 Lisp_Object eoltype;
16057
16058 val = Fget (coding_system, Qcoding_system);
16059 eoltype = Qnil;
16060
16061 if (!VECTORP (val)) /* Not yet decided. */
16062 {
16063 if (multibyte)
16064 *buf++ = '-';
16065 if (eol_flag)
16066 eoltype = eol_mnemonic_undecided;
16067 /* Don't mention EOL conversion if it isn't decided. */
16068 }
16069 else
16070 {
16071 Lisp_Object eolvalue;
16072
16073 eolvalue = Fget (coding_system, Qeol_type);
16074
16075 if (multibyte)
16076 *buf++ = XFASTINT (AREF (val, 1));
16077
16078 if (eol_flag)
16079 {
16080 /* The EOL conversion that is normal on this system. */
16081
16082 if (NILP (eolvalue)) /* Not yet decided. */
16083 eoltype = eol_mnemonic_undecided;
16084 else if (VECTORP (eolvalue)) /* Not yet decided. */
16085 eoltype = eol_mnemonic_undecided;
16086 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16087 eoltype = (XFASTINT (eolvalue) == 0
16088 ? eol_mnemonic_unix
16089 : (XFASTINT (eolvalue) == 1
16090 ? eol_mnemonic_dos : eol_mnemonic_mac));
16091 }
16092 }
16093
16094 if (eol_flag)
16095 {
16096 /* Mention the EOL conversion if it is not the usual one. */
16097 if (STRINGP (eoltype))
16098 {
16099 eol_str = SDATA (eoltype);
16100 eol_str_len = SBYTES (eoltype);
16101 }
16102 else if (INTEGERP (eoltype)
16103 && CHAR_VALID_P (XINT (eoltype), 0))
16104 {
16105 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16106 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16107 eol_str = tmp;
16108 }
16109 else
16110 {
16111 eol_str = invalid_eol_type;
16112 eol_str_len = sizeof (invalid_eol_type) - 1;
16113 }
16114 bcopy (eol_str, buf, eol_str_len);
16115 buf += eol_str_len;
16116 }
16117
16118 return buf;
16119 }
16120
16121 /* Return a string for the output of a mode line %-spec for window W,
16122 generated by character C. PRECISION >= 0 means don't return a
16123 string longer than that value. FIELD_WIDTH > 0 means pad the
16124 string returned with spaces to that value. Return 1 in *MULTIBYTE
16125 if the result is multibyte text. */
16126
16127 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16128
16129 static char *
16130 decode_mode_spec (w, c, field_width, precision, multibyte)
16131 struct window *w;
16132 register int c;
16133 int field_width, precision;
16134 int *multibyte;
16135 {
16136 Lisp_Object obj;
16137 struct frame *f = XFRAME (WINDOW_FRAME (w));
16138 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16139 struct buffer *b = XBUFFER (w->buffer);
16140
16141 obj = Qnil;
16142 *multibyte = 0;
16143
16144 switch (c)
16145 {
16146 case '*':
16147 if (!NILP (b->read_only))
16148 return "%";
16149 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16150 return "*";
16151 return "-";
16152
16153 case '+':
16154 /* This differs from %* only for a modified read-only buffer. */
16155 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16156 return "*";
16157 if (!NILP (b->read_only))
16158 return "%";
16159 return "-";
16160
16161 case '&':
16162 /* This differs from %* in ignoring read-only-ness. */
16163 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16164 return "*";
16165 return "-";
16166
16167 case '%':
16168 return "%";
16169
16170 case '[':
16171 {
16172 int i;
16173 char *p;
16174
16175 if (command_loop_level > 5)
16176 return "[[[... ";
16177 p = decode_mode_spec_buf;
16178 for (i = 0; i < command_loop_level; i++)
16179 *p++ = '[';
16180 *p = 0;
16181 return decode_mode_spec_buf;
16182 }
16183
16184 case ']':
16185 {
16186 int i;
16187 char *p;
16188
16189 if (command_loop_level > 5)
16190 return " ...]]]";
16191 p = decode_mode_spec_buf;
16192 for (i = 0; i < command_loop_level; i++)
16193 *p++ = ']';
16194 *p = 0;
16195 return decode_mode_spec_buf;
16196 }
16197
16198 case '-':
16199 {
16200 register int i;
16201
16202 /* Let lots_of_dashes be a string of infinite length. */
16203 if (!NILP (mode_line_string_list))
16204 return "--";
16205 if (field_width <= 0
16206 || field_width > sizeof (lots_of_dashes))
16207 {
16208 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16209 decode_mode_spec_buf[i] = '-';
16210 decode_mode_spec_buf[i] = '\0';
16211 return decode_mode_spec_buf;
16212 }
16213 else
16214 return lots_of_dashes;
16215 }
16216
16217 case 'b':
16218 obj = b->name;
16219 break;
16220
16221 case 'c':
16222 {
16223 int col = (int) current_column (); /* iftc */
16224 w->column_number_displayed = make_number (col);
16225 pint2str (decode_mode_spec_buf, field_width, col);
16226 return decode_mode_spec_buf;
16227 }
16228
16229 case 'F':
16230 /* %F displays the frame name. */
16231 if (!NILP (f->title))
16232 return (char *) SDATA (f->title);
16233 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16234 return (char *) SDATA (f->name);
16235 return "Emacs";
16236
16237 case 'f':
16238 obj = b->filename;
16239 break;
16240
16241 case 'i':
16242 {
16243 int size = ZV - BEGV;
16244 pint2str (decode_mode_spec_buf, field_width, size);
16245 return decode_mode_spec_buf;
16246 }
16247
16248 case 'I':
16249 {
16250 int size = ZV - BEGV;
16251 pint2hrstr (decode_mode_spec_buf, field_width, size);
16252 return decode_mode_spec_buf;
16253 }
16254
16255 case 'l':
16256 {
16257 int startpos = XMARKER (w->start)->charpos;
16258 int startpos_byte = marker_byte_position (w->start);
16259 int line, linepos, linepos_byte, topline;
16260 int nlines, junk;
16261 int height = WINDOW_TOTAL_LINES (w);
16262
16263 /* If we decided that this buffer isn't suitable for line numbers,
16264 don't forget that too fast. */
16265 if (EQ (w->base_line_pos, w->buffer))
16266 goto no_value;
16267 /* But do forget it, if the window shows a different buffer now. */
16268 else if (BUFFERP (w->base_line_pos))
16269 w->base_line_pos = Qnil;
16270
16271 /* If the buffer is very big, don't waste time. */
16272 if (INTEGERP (Vline_number_display_limit)
16273 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16274 {
16275 w->base_line_pos = Qnil;
16276 w->base_line_number = Qnil;
16277 goto no_value;
16278 }
16279
16280 if (!NILP (w->base_line_number)
16281 && !NILP (w->base_line_pos)
16282 && XFASTINT (w->base_line_pos) <= startpos)
16283 {
16284 line = XFASTINT (w->base_line_number);
16285 linepos = XFASTINT (w->base_line_pos);
16286 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16287 }
16288 else
16289 {
16290 line = 1;
16291 linepos = BUF_BEGV (b);
16292 linepos_byte = BUF_BEGV_BYTE (b);
16293 }
16294
16295 /* Count lines from base line to window start position. */
16296 nlines = display_count_lines (linepos, linepos_byte,
16297 startpos_byte,
16298 startpos, &junk);
16299
16300 topline = nlines + line;
16301
16302 /* Determine a new base line, if the old one is too close
16303 or too far away, or if we did not have one.
16304 "Too close" means it's plausible a scroll-down would
16305 go back past it. */
16306 if (startpos == BUF_BEGV (b))
16307 {
16308 w->base_line_number = make_number (topline);
16309 w->base_line_pos = make_number (BUF_BEGV (b));
16310 }
16311 else if (nlines < height + 25 || nlines > height * 3 + 50
16312 || linepos == BUF_BEGV (b))
16313 {
16314 int limit = BUF_BEGV (b);
16315 int limit_byte = BUF_BEGV_BYTE (b);
16316 int position;
16317 int distance = (height * 2 + 30) * line_number_display_limit_width;
16318
16319 if (startpos - distance > limit)
16320 {
16321 limit = startpos - distance;
16322 limit_byte = CHAR_TO_BYTE (limit);
16323 }
16324
16325 nlines = display_count_lines (startpos, startpos_byte,
16326 limit_byte,
16327 - (height * 2 + 30),
16328 &position);
16329 /* If we couldn't find the lines we wanted within
16330 line_number_display_limit_width chars per line,
16331 give up on line numbers for this window. */
16332 if (position == limit_byte && limit == startpos - distance)
16333 {
16334 w->base_line_pos = w->buffer;
16335 w->base_line_number = Qnil;
16336 goto no_value;
16337 }
16338
16339 w->base_line_number = make_number (topline - nlines);
16340 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16341 }
16342
16343 /* Now count lines from the start pos to point. */
16344 nlines = display_count_lines (startpos, startpos_byte,
16345 PT_BYTE, PT, &junk);
16346
16347 /* Record that we did display the line number. */
16348 line_number_displayed = 1;
16349
16350 /* Make the string to show. */
16351 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16352 return decode_mode_spec_buf;
16353 no_value:
16354 {
16355 char* p = decode_mode_spec_buf;
16356 int pad = field_width - 2;
16357 while (pad-- > 0)
16358 *p++ = ' ';
16359 *p++ = '?';
16360 *p++ = '?';
16361 *p = '\0';
16362 return decode_mode_spec_buf;
16363 }
16364 }
16365 break;
16366
16367 case 'm':
16368 obj = b->mode_name;
16369 break;
16370
16371 case 'n':
16372 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16373 return " Narrow";
16374 break;
16375
16376 case 'p':
16377 {
16378 int pos = marker_position (w->start);
16379 int total = BUF_ZV (b) - BUF_BEGV (b);
16380
16381 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16382 {
16383 if (pos <= BUF_BEGV (b))
16384 return "All";
16385 else
16386 return "Bottom";
16387 }
16388 else if (pos <= BUF_BEGV (b))
16389 return "Top";
16390 else
16391 {
16392 if (total > 1000000)
16393 /* Do it differently for a large value, to avoid overflow. */
16394 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16395 else
16396 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16397 /* We can't normally display a 3-digit number,
16398 so get us a 2-digit number that is close. */
16399 if (total == 100)
16400 total = 99;
16401 sprintf (decode_mode_spec_buf, "%2d%%", total);
16402 return decode_mode_spec_buf;
16403 }
16404 }
16405
16406 /* Display percentage of size above the bottom of the screen. */
16407 case 'P':
16408 {
16409 int toppos = marker_position (w->start);
16410 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16411 int total = BUF_ZV (b) - BUF_BEGV (b);
16412
16413 if (botpos >= BUF_ZV (b))
16414 {
16415 if (toppos <= BUF_BEGV (b))
16416 return "All";
16417 else
16418 return "Bottom";
16419 }
16420 else
16421 {
16422 if (total > 1000000)
16423 /* Do it differently for a large value, to avoid overflow. */
16424 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16425 else
16426 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16427 /* We can't normally display a 3-digit number,
16428 so get us a 2-digit number that is close. */
16429 if (total == 100)
16430 total = 99;
16431 if (toppos <= BUF_BEGV (b))
16432 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16433 else
16434 sprintf (decode_mode_spec_buf, "%2d%%", total);
16435 return decode_mode_spec_buf;
16436 }
16437 }
16438
16439 case 's':
16440 /* status of process */
16441 obj = Fget_buffer_process (w->buffer);
16442 if (NILP (obj))
16443 return "no process";
16444 #ifdef subprocesses
16445 obj = Fsymbol_name (Fprocess_status (obj));
16446 #endif
16447 break;
16448
16449 case 't': /* indicate TEXT or BINARY */
16450 #ifdef MODE_LINE_BINARY_TEXT
16451 return MODE_LINE_BINARY_TEXT (b);
16452 #else
16453 return "T";
16454 #endif
16455
16456 case 'z':
16457 /* coding-system (not including end-of-line format) */
16458 case 'Z':
16459 /* coding-system (including end-of-line type) */
16460 {
16461 int eol_flag = (c == 'Z');
16462 char *p = decode_mode_spec_buf;
16463
16464 if (! FRAME_WINDOW_P (f))
16465 {
16466 /* No need to mention EOL here--the terminal never needs
16467 to do EOL conversion. */
16468 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16469 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16470 }
16471 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16472 p, eol_flag);
16473
16474 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16475 #ifdef subprocesses
16476 obj = Fget_buffer_process (Fcurrent_buffer ());
16477 if (PROCESSP (obj))
16478 {
16479 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16480 p, eol_flag);
16481 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16482 p, eol_flag);
16483 }
16484 #endif /* subprocesses */
16485 #endif /* 0 */
16486 *p = 0;
16487 return decode_mode_spec_buf;
16488 }
16489 }
16490
16491 if (STRINGP (obj))
16492 {
16493 *multibyte = STRING_MULTIBYTE (obj);
16494 return (char *) SDATA (obj);
16495 }
16496 else
16497 return "";
16498 }
16499
16500
16501 /* Count up to COUNT lines starting from START / START_BYTE.
16502 But don't go beyond LIMIT_BYTE.
16503 Return the number of lines thus found (always nonnegative).
16504
16505 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16506
16507 static int
16508 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16509 int start, start_byte, limit_byte, count;
16510 int *byte_pos_ptr;
16511 {
16512 register unsigned char *cursor;
16513 unsigned char *base;
16514
16515 register int ceiling;
16516 register unsigned char *ceiling_addr;
16517 int orig_count = count;
16518
16519 /* If we are not in selective display mode,
16520 check only for newlines. */
16521 int selective_display = (!NILP (current_buffer->selective_display)
16522 && !INTEGERP (current_buffer->selective_display));
16523
16524 if (count > 0)
16525 {
16526 while (start_byte < limit_byte)
16527 {
16528 ceiling = BUFFER_CEILING_OF (start_byte);
16529 ceiling = min (limit_byte - 1, ceiling);
16530 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16531 base = (cursor = BYTE_POS_ADDR (start_byte));
16532 while (1)
16533 {
16534 if (selective_display)
16535 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16536 ;
16537 else
16538 while (*cursor != '\n' && ++cursor != ceiling_addr)
16539 ;
16540
16541 if (cursor != ceiling_addr)
16542 {
16543 if (--count == 0)
16544 {
16545 start_byte += cursor - base + 1;
16546 *byte_pos_ptr = start_byte;
16547 return orig_count;
16548 }
16549 else
16550 if (++cursor == ceiling_addr)
16551 break;
16552 }
16553 else
16554 break;
16555 }
16556 start_byte += cursor - base;
16557 }
16558 }
16559 else
16560 {
16561 while (start_byte > limit_byte)
16562 {
16563 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16564 ceiling = max (limit_byte, ceiling);
16565 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16566 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16567 while (1)
16568 {
16569 if (selective_display)
16570 while (--cursor != ceiling_addr
16571 && *cursor != '\n' && *cursor != 015)
16572 ;
16573 else
16574 while (--cursor != ceiling_addr && *cursor != '\n')
16575 ;
16576
16577 if (cursor != ceiling_addr)
16578 {
16579 if (++count == 0)
16580 {
16581 start_byte += cursor - base + 1;
16582 *byte_pos_ptr = start_byte;
16583 /* When scanning backwards, we should
16584 not count the newline posterior to which we stop. */
16585 return - orig_count - 1;
16586 }
16587 }
16588 else
16589 break;
16590 }
16591 /* Here we add 1 to compensate for the last decrement
16592 of CURSOR, which took it past the valid range. */
16593 start_byte += cursor - base + 1;
16594 }
16595 }
16596
16597 *byte_pos_ptr = limit_byte;
16598
16599 if (count < 0)
16600 return - orig_count + count;
16601 return orig_count - count;
16602
16603 }
16604
16605
16606 \f
16607 /***********************************************************************
16608 Displaying strings
16609 ***********************************************************************/
16610
16611 /* Display a NUL-terminated string, starting with index START.
16612
16613 If STRING is non-null, display that C string. Otherwise, the Lisp
16614 string LISP_STRING is displayed.
16615
16616 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16617 FACE_STRING. Display STRING or LISP_STRING with the face at
16618 FACE_STRING_POS in FACE_STRING:
16619
16620 Display the string in the environment given by IT, but use the
16621 standard display table, temporarily.
16622
16623 FIELD_WIDTH is the minimum number of output glyphs to produce.
16624 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16625 with spaces. If STRING has more characters, more than FIELD_WIDTH
16626 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16627
16628 PRECISION is the maximum number of characters to output from
16629 STRING. PRECISION < 0 means don't truncate the string.
16630
16631 This is roughly equivalent to printf format specifiers:
16632
16633 FIELD_WIDTH PRECISION PRINTF
16634 ----------------------------------------
16635 -1 -1 %s
16636 -1 10 %.10s
16637 10 -1 %10s
16638 20 10 %20.10s
16639
16640 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16641 display them, and < 0 means obey the current buffer's value of
16642 enable_multibyte_characters.
16643
16644 Value is the number of glyphs produced. */
16645
16646 static int
16647 display_string (string, lisp_string, face_string, face_string_pos,
16648 start, it, field_width, precision, max_x, multibyte)
16649 unsigned char *string;
16650 Lisp_Object lisp_string;
16651 Lisp_Object face_string;
16652 int face_string_pos;
16653 int start;
16654 struct it *it;
16655 int field_width, precision, max_x;
16656 int multibyte;
16657 {
16658 int hpos_at_start = it->hpos;
16659 int saved_face_id = it->face_id;
16660 struct glyph_row *row = it->glyph_row;
16661
16662 /* Initialize the iterator IT for iteration over STRING beginning
16663 with index START. */
16664 reseat_to_string (it, string, lisp_string, start,
16665 precision, field_width, multibyte);
16666
16667 /* If displaying STRING, set up the face of the iterator
16668 from LISP_STRING, if that's given. */
16669 if (STRINGP (face_string))
16670 {
16671 int endptr;
16672 struct face *face;
16673
16674 it->face_id
16675 = face_at_string_position (it->w, face_string, face_string_pos,
16676 0, it->region_beg_charpos,
16677 it->region_end_charpos,
16678 &endptr, it->base_face_id, 0);
16679 face = FACE_FROM_ID (it->f, it->face_id);
16680 it->face_box_p = face->box != FACE_NO_BOX;
16681 }
16682
16683 /* Set max_x to the maximum allowed X position. Don't let it go
16684 beyond the right edge of the window. */
16685 if (max_x <= 0)
16686 max_x = it->last_visible_x;
16687 else
16688 max_x = min (max_x, it->last_visible_x);
16689
16690 /* Skip over display elements that are not visible. because IT->w is
16691 hscrolled. */
16692 if (it->current_x < it->first_visible_x)
16693 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16694 MOVE_TO_POS | MOVE_TO_X);
16695
16696 row->ascent = it->max_ascent;
16697 row->height = it->max_ascent + it->max_descent;
16698 row->phys_ascent = it->max_phys_ascent;
16699 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16700
16701 /* This condition is for the case that we are called with current_x
16702 past last_visible_x. */
16703 while (it->current_x < max_x)
16704 {
16705 int x_before, x, n_glyphs_before, i, nglyphs;
16706
16707 /* Get the next display element. */
16708 if (!get_next_display_element (it))
16709 break;
16710
16711 /* Produce glyphs. */
16712 x_before = it->current_x;
16713 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16714 PRODUCE_GLYPHS (it);
16715
16716 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16717 i = 0;
16718 x = x_before;
16719 while (i < nglyphs)
16720 {
16721 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16722
16723 if (!it->truncate_lines_p
16724 && x + glyph->pixel_width > max_x)
16725 {
16726 /* End of continued line or max_x reached. */
16727 if (CHAR_GLYPH_PADDING_P (*glyph))
16728 {
16729 /* A wide character is unbreakable. */
16730 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16731 it->current_x = x_before;
16732 }
16733 else
16734 {
16735 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16736 it->current_x = x;
16737 }
16738 break;
16739 }
16740 else if (x + glyph->pixel_width > it->first_visible_x)
16741 {
16742 /* Glyph is at least partially visible. */
16743 ++it->hpos;
16744 if (x < it->first_visible_x)
16745 it->glyph_row->x = x - it->first_visible_x;
16746 }
16747 else
16748 {
16749 /* Glyph is off the left margin of the display area.
16750 Should not happen. */
16751 abort ();
16752 }
16753
16754 row->ascent = max (row->ascent, it->max_ascent);
16755 row->height = max (row->height, it->max_ascent + it->max_descent);
16756 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16757 row->phys_height = max (row->phys_height,
16758 it->max_phys_ascent + it->max_phys_descent);
16759 x += glyph->pixel_width;
16760 ++i;
16761 }
16762
16763 /* Stop if max_x reached. */
16764 if (i < nglyphs)
16765 break;
16766
16767 /* Stop at line ends. */
16768 if (ITERATOR_AT_END_OF_LINE_P (it))
16769 {
16770 it->continuation_lines_width = 0;
16771 break;
16772 }
16773
16774 set_iterator_to_next (it, 1);
16775
16776 /* Stop if truncating at the right edge. */
16777 if (it->truncate_lines_p
16778 && it->current_x >= it->last_visible_x)
16779 {
16780 /* Add truncation mark, but don't do it if the line is
16781 truncated at a padding space. */
16782 if (IT_CHARPOS (*it) < it->string_nchars)
16783 {
16784 if (!FRAME_WINDOW_P (it->f))
16785 {
16786 int i, n;
16787
16788 if (it->current_x > it->last_visible_x)
16789 {
16790 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16791 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16792 break;
16793 for (n = row->used[TEXT_AREA]; i < n; ++i)
16794 {
16795 row->used[TEXT_AREA] = i;
16796 produce_special_glyphs (it, IT_TRUNCATION);
16797 }
16798 }
16799 produce_special_glyphs (it, IT_TRUNCATION);
16800 }
16801 it->glyph_row->truncated_on_right_p = 1;
16802 }
16803 break;
16804 }
16805 }
16806
16807 /* Maybe insert a truncation at the left. */
16808 if (it->first_visible_x
16809 && IT_CHARPOS (*it) > 0)
16810 {
16811 if (!FRAME_WINDOW_P (it->f))
16812 insert_left_trunc_glyphs (it);
16813 it->glyph_row->truncated_on_left_p = 1;
16814 }
16815
16816 it->face_id = saved_face_id;
16817
16818 /* Value is number of columns displayed. */
16819 return it->hpos - hpos_at_start;
16820 }
16821
16822
16823 \f
16824 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16825 appears as an element of LIST or as the car of an element of LIST.
16826 If PROPVAL is a list, compare each element against LIST in that
16827 way, and return 1/2 if any element of PROPVAL is found in LIST.
16828 Otherwise return 0. This function cannot quit.
16829 The return value is 2 if the text is invisible but with an ellipsis
16830 and 1 if it's invisible and without an ellipsis. */
16831
16832 int
16833 invisible_p (propval, list)
16834 register Lisp_Object propval;
16835 Lisp_Object list;
16836 {
16837 register Lisp_Object tail, proptail;
16838
16839 for (tail = list; CONSP (tail); tail = XCDR (tail))
16840 {
16841 register Lisp_Object tem;
16842 tem = XCAR (tail);
16843 if (EQ (propval, tem))
16844 return 1;
16845 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16846 return NILP (XCDR (tem)) ? 1 : 2;
16847 }
16848
16849 if (CONSP (propval))
16850 {
16851 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16852 {
16853 Lisp_Object propelt;
16854 propelt = XCAR (proptail);
16855 for (tail = list; CONSP (tail); tail = XCDR (tail))
16856 {
16857 register Lisp_Object tem;
16858 tem = XCAR (tail);
16859 if (EQ (propelt, tem))
16860 return 1;
16861 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16862 return NILP (XCDR (tem)) ? 1 : 2;
16863 }
16864 }
16865 }
16866
16867 return 0;
16868 }
16869
16870 /* Calculate a width or height in pixels from a specification using
16871 the following elements:
16872
16873 SPEC ::=
16874 NUM - a (fractional) multiple of the default font width/height
16875 (NUM) - specifies exactly NUM pixels
16876 UNIT - a fixed number of pixels, see below.
16877 ELEMENT - size of a display element in pixels, see below.
16878 (NUM . SPEC) - equals NUM * SPEC
16879 (+ SPEC SPEC ...) - add pixel values
16880 (- SPEC SPEC ...) - subtract pixel values
16881 (- SPEC) - negate pixel value
16882
16883 NUM ::=
16884 INT or FLOAT - a number constant
16885 SYMBOL - use symbol's (buffer local) variable binding.
16886
16887 UNIT ::=
16888 in - pixels per inch *)
16889 mm - pixels per 1/1000 meter *)
16890 cm - pixels per 1/100 meter *)
16891 width - width of current font in pixels.
16892 height - height of current font in pixels.
16893
16894 *) using the ratio(s) defined in display-pixels-per-inch.
16895
16896 ELEMENT ::=
16897
16898 left-fringe - left fringe width in pixels
16899 right-fringe - right fringe width in pixels
16900
16901 left-margin - left margin width in pixels
16902 right-margin - right margin width in pixels
16903
16904 scroll-bar - scroll-bar area width in pixels
16905
16906 Examples:
16907
16908 Pixels corresponding to 5 inches:
16909 (5 . in)
16910
16911 Total width of non-text areas on left side of window (if scroll-bar is on left):
16912 '(space :width (+ left-fringe left-margin scroll-bar))
16913
16914 Align to first text column (in header line):
16915 '(space :align-to 0)
16916
16917 Align to middle of text area minus half the width of variable `my-image'
16918 containing a loaded image:
16919 '(space :align-to (0.5 . (- text my-image)))
16920
16921 Width of left margin minus width of 1 character in the default font:
16922 '(space :width (- left-margin 1))
16923
16924 Width of left margin minus width of 2 characters in the current font:
16925 '(space :width (- left-margin (2 . width)))
16926
16927 Center 1 character over left-margin (in header line):
16928 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16929
16930 Different ways to express width of left fringe plus left margin minus one pixel:
16931 '(space :width (- (+ left-fringe left-margin) (1)))
16932 '(space :width (+ left-fringe left-margin (- (1))))
16933 '(space :width (+ left-fringe left-margin (-1)))
16934
16935 */
16936
16937 #define NUMVAL(X) \
16938 ((INTEGERP (X) || FLOATP (X)) \
16939 ? XFLOATINT (X) \
16940 : - 1)
16941
16942 int
16943 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
16944 double *res;
16945 struct it *it;
16946 Lisp_Object prop;
16947 void *font;
16948 int width_p, *align_to;
16949 {
16950 double pixels;
16951
16952 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16953 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16954
16955 if (NILP (prop))
16956 return OK_PIXELS (0);
16957
16958 if (SYMBOLP (prop))
16959 {
16960 if (SCHARS (SYMBOL_NAME (prop)) == 2)
16961 {
16962 char *unit = SDATA (SYMBOL_NAME (prop));
16963
16964 if (unit[0] == 'i' && unit[1] == 'n')
16965 pixels = 1.0;
16966 else if (unit[0] == 'm' && unit[1] == 'm')
16967 pixels = 25.4;
16968 else if (unit[0] == 'c' && unit[1] == 'm')
16969 pixels = 2.54;
16970 else
16971 pixels = 0;
16972 if (pixels > 0)
16973 {
16974 double ppi;
16975 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
16976 || (CONSP (Vdisplay_pixels_per_inch)
16977 && (ppi = (width_p
16978 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
16979 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
16980 ppi > 0)))
16981 return OK_PIXELS (ppi / pixels);
16982
16983 return 0;
16984 }
16985 }
16986
16987 #ifdef HAVE_WINDOW_SYSTEM
16988 if (EQ (prop, Qheight))
16989 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
16990 if (EQ (prop, Qwidth))
16991 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
16992 #else
16993 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
16994 return OK_PIXELS (1);
16995 #endif
16996
16997 if (EQ (prop, Qtext))
16998 return OK_PIXELS (width_p
16999 ? window_box_width (it->w, TEXT_AREA)
17000 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17001
17002 if (align_to && *align_to < 0)
17003 {
17004 *res = 0;
17005 if (EQ (prop, Qleft))
17006 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17007 if (EQ (prop, Qright))
17008 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17009 if (EQ (prop, Qcenter))
17010 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17011 + window_box_width (it->w, TEXT_AREA) / 2);
17012 if (EQ (prop, Qleft_fringe))
17013 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17014 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17015 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17016 if (EQ (prop, Qright_fringe))
17017 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17018 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17019 : window_box_right_offset (it->w, TEXT_AREA));
17020 if (EQ (prop, Qleft_margin))
17021 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17022 if (EQ (prop, Qright_margin))
17023 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17024 if (EQ (prop, Qscroll_bar))
17025 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17026 ? 0
17027 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17028 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17029 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17030 : 0)));
17031 }
17032 else
17033 {
17034 if (EQ (prop, Qleft_fringe))
17035 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17036 if (EQ (prop, Qright_fringe))
17037 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17038 if (EQ (prop, Qleft_margin))
17039 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17040 if (EQ (prop, Qright_margin))
17041 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17042 if (EQ (prop, Qscroll_bar))
17043 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17044 }
17045
17046 prop = Fbuffer_local_value (prop, it->w->buffer);
17047 }
17048
17049 if (INTEGERP (prop) || FLOATP (prop))
17050 {
17051 int base_unit = (width_p
17052 ? FRAME_COLUMN_WIDTH (it->f)
17053 : FRAME_LINE_HEIGHT (it->f));
17054 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17055 }
17056
17057 if (CONSP (prop))
17058 {
17059 Lisp_Object car = XCAR (prop);
17060 Lisp_Object cdr = XCDR (prop);
17061
17062 if (SYMBOLP (car))
17063 {
17064 #ifdef HAVE_WINDOW_SYSTEM
17065 if (valid_image_p (prop))
17066 {
17067 int id = lookup_image (it->f, prop);
17068 struct image *img = IMAGE_FROM_ID (it->f, id);
17069
17070 return OK_PIXELS (width_p ? img->width : img->height);
17071 }
17072 #endif
17073 if (EQ (car, Qplus) || EQ (car, Qminus))
17074 {
17075 int first = 1;
17076 double px;
17077
17078 pixels = 0;
17079 while (CONSP (cdr))
17080 {
17081 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17082 font, width_p, align_to))
17083 return 0;
17084 if (first)
17085 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17086 else
17087 pixels += px;
17088 cdr = XCDR (cdr);
17089 }
17090 if (EQ (car, Qminus))
17091 pixels = -pixels;
17092 return OK_PIXELS (pixels);
17093 }
17094
17095 car = Fbuffer_local_value (car, it->w->buffer);
17096 }
17097
17098 if (INTEGERP (car) || FLOATP (car))
17099 {
17100 double fact;
17101 pixels = XFLOATINT (car);
17102 if (NILP (cdr))
17103 return OK_PIXELS (pixels);
17104 if (calc_pixel_width_or_height (&fact, it, cdr,
17105 font, width_p, align_to))
17106 return OK_PIXELS (pixels * fact);
17107 return 0;
17108 }
17109
17110 return 0;
17111 }
17112
17113 return 0;
17114 }
17115
17116 \f
17117 /***********************************************************************
17118 Glyph Display
17119 ***********************************************************************/
17120
17121 #ifdef HAVE_WINDOW_SYSTEM
17122
17123 #if GLYPH_DEBUG
17124
17125 void
17126 dump_glyph_string (s)
17127 struct glyph_string *s;
17128 {
17129 fprintf (stderr, "glyph string\n");
17130 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17131 s->x, s->y, s->width, s->height);
17132 fprintf (stderr, " ybase = %d\n", s->ybase);
17133 fprintf (stderr, " hl = %d\n", s->hl);
17134 fprintf (stderr, " left overhang = %d, right = %d\n",
17135 s->left_overhang, s->right_overhang);
17136 fprintf (stderr, " nchars = %d\n", s->nchars);
17137 fprintf (stderr, " extends to end of line = %d\n",
17138 s->extends_to_end_of_line_p);
17139 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17140 fprintf (stderr, " bg width = %d\n", s->background_width);
17141 }
17142
17143 #endif /* GLYPH_DEBUG */
17144
17145 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17146 of XChar2b structures for S; it can't be allocated in
17147 init_glyph_string because it must be allocated via `alloca'. W
17148 is the window on which S is drawn. ROW and AREA are the glyph row
17149 and area within the row from which S is constructed. START is the
17150 index of the first glyph structure covered by S. HL is a
17151 face-override for drawing S. */
17152
17153 #ifdef HAVE_NTGUI
17154 #define OPTIONAL_HDC(hdc) hdc,
17155 #define DECLARE_HDC(hdc) HDC hdc;
17156 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17157 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17158 #endif
17159
17160 #ifndef OPTIONAL_HDC
17161 #define OPTIONAL_HDC(hdc)
17162 #define DECLARE_HDC(hdc)
17163 #define ALLOCATE_HDC(hdc, f)
17164 #define RELEASE_HDC(hdc, f)
17165 #endif
17166
17167 static void
17168 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17169 struct glyph_string *s;
17170 DECLARE_HDC (hdc)
17171 XChar2b *char2b;
17172 struct window *w;
17173 struct glyph_row *row;
17174 enum glyph_row_area area;
17175 int start;
17176 enum draw_glyphs_face hl;
17177 {
17178 bzero (s, sizeof *s);
17179 s->w = w;
17180 s->f = XFRAME (w->frame);
17181 #ifdef HAVE_NTGUI
17182 s->hdc = hdc;
17183 #endif
17184 s->display = FRAME_X_DISPLAY (s->f);
17185 s->window = FRAME_X_WINDOW (s->f);
17186 s->char2b = char2b;
17187 s->hl = hl;
17188 s->row = row;
17189 s->area = area;
17190 s->first_glyph = row->glyphs[area] + start;
17191 s->height = row->height;
17192 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17193
17194 /* Display the internal border below the tool-bar window. */
17195 if (s->w == XWINDOW (s->f->tool_bar_window))
17196 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17197
17198 s->ybase = s->y + row->ascent;
17199 }
17200
17201
17202 /* Append the list of glyph strings with head H and tail T to the list
17203 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17204
17205 static INLINE void
17206 append_glyph_string_lists (head, tail, h, t)
17207 struct glyph_string **head, **tail;
17208 struct glyph_string *h, *t;
17209 {
17210 if (h)
17211 {
17212 if (*head)
17213 (*tail)->next = h;
17214 else
17215 *head = h;
17216 h->prev = *tail;
17217 *tail = t;
17218 }
17219 }
17220
17221
17222 /* Prepend the list of glyph strings with head H and tail T to the
17223 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17224 result. */
17225
17226 static INLINE void
17227 prepend_glyph_string_lists (head, tail, h, t)
17228 struct glyph_string **head, **tail;
17229 struct glyph_string *h, *t;
17230 {
17231 if (h)
17232 {
17233 if (*head)
17234 (*head)->prev = t;
17235 else
17236 *tail = t;
17237 t->next = *head;
17238 *head = h;
17239 }
17240 }
17241
17242
17243 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17244 Set *HEAD and *TAIL to the resulting list. */
17245
17246 static INLINE void
17247 append_glyph_string (head, tail, s)
17248 struct glyph_string **head, **tail;
17249 struct glyph_string *s;
17250 {
17251 s->next = s->prev = NULL;
17252 append_glyph_string_lists (head, tail, s, s);
17253 }
17254
17255
17256 /* Get face and two-byte form of character glyph GLYPH on frame F.
17257 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17258 a pointer to a realized face that is ready for display. */
17259
17260 static INLINE struct face *
17261 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17262 struct frame *f;
17263 struct glyph *glyph;
17264 XChar2b *char2b;
17265 int *two_byte_p;
17266 {
17267 struct face *face;
17268
17269 xassert (glyph->type == CHAR_GLYPH);
17270 face = FACE_FROM_ID (f, glyph->face_id);
17271
17272 if (two_byte_p)
17273 *two_byte_p = 0;
17274
17275 if (!glyph->multibyte_p)
17276 {
17277 /* Unibyte case. We don't have to encode, but we have to make
17278 sure to use a face suitable for unibyte. */
17279 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17280 }
17281 else if (glyph->u.ch < 128
17282 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17283 {
17284 /* Case of ASCII in a face known to fit ASCII. */
17285 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17286 }
17287 else
17288 {
17289 int c1, c2, charset;
17290
17291 /* Split characters into bytes. If c2 is -1 afterwards, C is
17292 really a one-byte character so that byte1 is zero. */
17293 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17294 if (c2 > 0)
17295 STORE_XCHAR2B (char2b, c1, c2);
17296 else
17297 STORE_XCHAR2B (char2b, 0, c1);
17298
17299 /* Maybe encode the character in *CHAR2B. */
17300 if (charset != CHARSET_ASCII)
17301 {
17302 struct font_info *font_info
17303 = FONT_INFO_FROM_ID (f, face->font_info_id);
17304 if (font_info)
17305 glyph->font_type
17306 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17307 }
17308 }
17309
17310 /* Make sure X resources of the face are allocated. */
17311 xassert (face != NULL);
17312 PREPARE_FACE_FOR_DISPLAY (f, face);
17313 return face;
17314 }
17315
17316
17317 /* Fill glyph string S with composition components specified by S->cmp.
17318
17319 FACES is an array of faces for all components of this composition.
17320 S->gidx is the index of the first component for S.
17321 OVERLAPS_P non-zero means S should draw the foreground only, and
17322 use its physical height for clipping.
17323
17324 Value is the index of a component not in S. */
17325
17326 static int
17327 fill_composite_glyph_string (s, faces, overlaps_p)
17328 struct glyph_string *s;
17329 struct face **faces;
17330 int overlaps_p;
17331 {
17332 int i;
17333
17334 xassert (s);
17335
17336 s->for_overlaps_p = overlaps_p;
17337
17338 s->face = faces[s->gidx];
17339 s->font = s->face->font;
17340 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17341
17342 /* For all glyphs of this composition, starting at the offset
17343 S->gidx, until we reach the end of the definition or encounter a
17344 glyph that requires the different face, add it to S. */
17345 ++s->nchars;
17346 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17347 ++s->nchars;
17348
17349 /* All glyph strings for the same composition has the same width,
17350 i.e. the width set for the first component of the composition. */
17351
17352 s->width = s->first_glyph->pixel_width;
17353
17354 /* If the specified font could not be loaded, use the frame's
17355 default font, but record the fact that we couldn't load it in
17356 the glyph string so that we can draw rectangles for the
17357 characters of the glyph string. */
17358 if (s->font == NULL)
17359 {
17360 s->font_not_found_p = 1;
17361 s->font = FRAME_FONT (s->f);
17362 }
17363
17364 /* Adjust base line for subscript/superscript text. */
17365 s->ybase += s->first_glyph->voffset;
17366
17367 xassert (s->face && s->face->gc);
17368
17369 /* This glyph string must always be drawn with 16-bit functions. */
17370 s->two_byte_p = 1;
17371
17372 return s->gidx + s->nchars;
17373 }
17374
17375
17376 /* Fill glyph string S from a sequence of character glyphs.
17377
17378 FACE_ID is the face id of the string. START is the index of the
17379 first glyph to consider, END is the index of the last + 1.
17380 OVERLAPS_P non-zero means S should draw the foreground only, and
17381 use its physical height for clipping.
17382
17383 Value is the index of the first glyph not in S. */
17384
17385 static int
17386 fill_glyph_string (s, face_id, start, end, overlaps_p)
17387 struct glyph_string *s;
17388 int face_id;
17389 int start, end, overlaps_p;
17390 {
17391 struct glyph *glyph, *last;
17392 int voffset;
17393 int glyph_not_available_p;
17394
17395 xassert (s->f == XFRAME (s->w->frame));
17396 xassert (s->nchars == 0);
17397 xassert (start >= 0 && end > start);
17398
17399 s->for_overlaps_p = overlaps_p,
17400 glyph = s->row->glyphs[s->area] + start;
17401 last = s->row->glyphs[s->area] + end;
17402 voffset = glyph->voffset;
17403
17404 glyph_not_available_p = glyph->glyph_not_available_p;
17405
17406 while (glyph < last
17407 && glyph->type == CHAR_GLYPH
17408 && glyph->voffset == voffset
17409 /* Same face id implies same font, nowadays. */
17410 && glyph->face_id == face_id
17411 && glyph->glyph_not_available_p == glyph_not_available_p)
17412 {
17413 int two_byte_p;
17414
17415 s->face = get_glyph_face_and_encoding (s->f, glyph,
17416 s->char2b + s->nchars,
17417 &two_byte_p);
17418 s->two_byte_p = two_byte_p;
17419 ++s->nchars;
17420 xassert (s->nchars <= end - start);
17421 s->width += glyph->pixel_width;
17422 ++glyph;
17423 }
17424
17425 s->font = s->face->font;
17426 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17427
17428 /* If the specified font could not be loaded, use the frame's font,
17429 but record the fact that we couldn't load it in
17430 S->font_not_found_p so that we can draw rectangles for the
17431 characters of the glyph string. */
17432 if (s->font == NULL || glyph_not_available_p)
17433 {
17434 s->font_not_found_p = 1;
17435 s->font = FRAME_FONT (s->f);
17436 }
17437
17438 /* Adjust base line for subscript/superscript text. */
17439 s->ybase += voffset;
17440
17441 xassert (s->face && s->face->gc);
17442 return glyph - s->row->glyphs[s->area];
17443 }
17444
17445
17446 /* Fill glyph string S from image glyph S->first_glyph. */
17447
17448 static void
17449 fill_image_glyph_string (s)
17450 struct glyph_string *s;
17451 {
17452 xassert (s->first_glyph->type == IMAGE_GLYPH);
17453 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17454 xassert (s->img);
17455 s->slice = s->first_glyph->slice;
17456 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17457 s->font = s->face->font;
17458 s->width = s->first_glyph->pixel_width;
17459
17460 /* Adjust base line for subscript/superscript text. */
17461 s->ybase += s->first_glyph->voffset;
17462 }
17463
17464
17465 /* Fill glyph string S from a sequence of stretch glyphs.
17466
17467 ROW is the glyph row in which the glyphs are found, AREA is the
17468 area within the row. START is the index of the first glyph to
17469 consider, END is the index of the last + 1.
17470
17471 Value is the index of the first glyph not in S. */
17472
17473 static int
17474 fill_stretch_glyph_string (s, row, area, start, end)
17475 struct glyph_string *s;
17476 struct glyph_row *row;
17477 enum glyph_row_area area;
17478 int start, end;
17479 {
17480 struct glyph *glyph, *last;
17481 int voffset, face_id;
17482
17483 xassert (s->first_glyph->type == STRETCH_GLYPH);
17484
17485 glyph = s->row->glyphs[s->area] + start;
17486 last = s->row->glyphs[s->area] + end;
17487 face_id = glyph->face_id;
17488 s->face = FACE_FROM_ID (s->f, face_id);
17489 s->font = s->face->font;
17490 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17491 s->width = glyph->pixel_width;
17492 voffset = glyph->voffset;
17493
17494 for (++glyph;
17495 (glyph < last
17496 && glyph->type == STRETCH_GLYPH
17497 && glyph->voffset == voffset
17498 && glyph->face_id == face_id);
17499 ++glyph)
17500 s->width += glyph->pixel_width;
17501
17502 /* Adjust base line for subscript/superscript text. */
17503 s->ybase += voffset;
17504
17505 /* The case that face->gc == 0 is handled when drawing the glyph
17506 string by calling PREPARE_FACE_FOR_DISPLAY. */
17507 xassert (s->face);
17508 return glyph - s->row->glyphs[s->area];
17509 }
17510
17511
17512 /* EXPORT for RIF:
17513 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17514 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17515 assumed to be zero. */
17516
17517 void
17518 x_get_glyph_overhangs (glyph, f, left, right)
17519 struct glyph *glyph;
17520 struct frame *f;
17521 int *left, *right;
17522 {
17523 *left = *right = 0;
17524
17525 if (glyph->type == CHAR_GLYPH)
17526 {
17527 XFontStruct *font;
17528 struct face *face;
17529 struct font_info *font_info;
17530 XChar2b char2b;
17531 XCharStruct *pcm;
17532
17533 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17534 font = face->font;
17535 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17536 if (font /* ++KFS: Should this be font_info ? */
17537 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17538 {
17539 if (pcm->rbearing > pcm->width)
17540 *right = pcm->rbearing - pcm->width;
17541 if (pcm->lbearing < 0)
17542 *left = -pcm->lbearing;
17543 }
17544 }
17545 }
17546
17547
17548 /* Return the index of the first glyph preceding glyph string S that
17549 is overwritten by S because of S's left overhang. Value is -1
17550 if no glyphs are overwritten. */
17551
17552 static int
17553 left_overwritten (s)
17554 struct glyph_string *s;
17555 {
17556 int k;
17557
17558 if (s->left_overhang)
17559 {
17560 int x = 0, i;
17561 struct glyph *glyphs = s->row->glyphs[s->area];
17562 int first = s->first_glyph - glyphs;
17563
17564 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17565 x -= glyphs[i].pixel_width;
17566
17567 k = i + 1;
17568 }
17569 else
17570 k = -1;
17571
17572 return k;
17573 }
17574
17575
17576 /* Return the index of the first glyph preceding glyph string S that
17577 is overwriting S because of its right overhang. Value is -1 if no
17578 glyph in front of S overwrites S. */
17579
17580 static int
17581 left_overwriting (s)
17582 struct glyph_string *s;
17583 {
17584 int i, k, x;
17585 struct glyph *glyphs = s->row->glyphs[s->area];
17586 int first = s->first_glyph - glyphs;
17587
17588 k = -1;
17589 x = 0;
17590 for (i = first - 1; i >= 0; --i)
17591 {
17592 int left, right;
17593 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17594 if (x + right > 0)
17595 k = i;
17596 x -= glyphs[i].pixel_width;
17597 }
17598
17599 return k;
17600 }
17601
17602
17603 /* Return the index of the last glyph following glyph string S that is
17604 not overwritten by S because of S's right overhang. Value is -1 if
17605 no such glyph is found. */
17606
17607 static int
17608 right_overwritten (s)
17609 struct glyph_string *s;
17610 {
17611 int k = -1;
17612
17613 if (s->right_overhang)
17614 {
17615 int x = 0, i;
17616 struct glyph *glyphs = s->row->glyphs[s->area];
17617 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17618 int end = s->row->used[s->area];
17619
17620 for (i = first; i < end && s->right_overhang > x; ++i)
17621 x += glyphs[i].pixel_width;
17622
17623 k = i;
17624 }
17625
17626 return k;
17627 }
17628
17629
17630 /* Return the index of the last glyph following glyph string S that
17631 overwrites S because of its left overhang. Value is negative
17632 if no such glyph is found. */
17633
17634 static int
17635 right_overwriting (s)
17636 struct glyph_string *s;
17637 {
17638 int i, k, x;
17639 int end = s->row->used[s->area];
17640 struct glyph *glyphs = s->row->glyphs[s->area];
17641 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17642
17643 k = -1;
17644 x = 0;
17645 for (i = first; i < end; ++i)
17646 {
17647 int left, right;
17648 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17649 if (x - left < 0)
17650 k = i;
17651 x += glyphs[i].pixel_width;
17652 }
17653
17654 return k;
17655 }
17656
17657
17658 /* Get face and two-byte form of character C in face FACE_ID on frame
17659 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17660 means we want to display multibyte text. DISPLAY_P non-zero means
17661 make sure that X resources for the face returned are allocated.
17662 Value is a pointer to a realized face that is ready for display if
17663 DISPLAY_P is non-zero. */
17664
17665 static INLINE struct face *
17666 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17667 struct frame *f;
17668 int c, face_id;
17669 XChar2b *char2b;
17670 int multibyte_p, display_p;
17671 {
17672 struct face *face = FACE_FROM_ID (f, face_id);
17673
17674 if (!multibyte_p)
17675 {
17676 /* Unibyte case. We don't have to encode, but we have to make
17677 sure to use a face suitable for unibyte. */
17678 STORE_XCHAR2B (char2b, 0, c);
17679 face_id = FACE_FOR_CHAR (f, face, c);
17680 face = FACE_FROM_ID (f, face_id);
17681 }
17682 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17683 {
17684 /* Case of ASCII in a face known to fit ASCII. */
17685 STORE_XCHAR2B (char2b, 0, c);
17686 }
17687 else
17688 {
17689 int c1, c2, charset;
17690
17691 /* Split characters into bytes. If c2 is -1 afterwards, C is
17692 really a one-byte character so that byte1 is zero. */
17693 SPLIT_CHAR (c, charset, c1, c2);
17694 if (c2 > 0)
17695 STORE_XCHAR2B (char2b, c1, c2);
17696 else
17697 STORE_XCHAR2B (char2b, 0, c1);
17698
17699 /* Maybe encode the character in *CHAR2B. */
17700 if (face->font != NULL)
17701 {
17702 struct font_info *font_info
17703 = FONT_INFO_FROM_ID (f, face->font_info_id);
17704 if (font_info)
17705 rif->encode_char (c, char2b, font_info, 0);
17706 }
17707 }
17708
17709 /* Make sure X resources of the face are allocated. */
17710 #ifdef HAVE_X_WINDOWS
17711 if (display_p)
17712 #endif
17713 {
17714 xassert (face != NULL);
17715 PREPARE_FACE_FOR_DISPLAY (f, face);
17716 }
17717
17718 return face;
17719 }
17720
17721
17722 /* Set background width of glyph string S. START is the index of the
17723 first glyph following S. LAST_X is the right-most x-position + 1
17724 in the drawing area. */
17725
17726 static INLINE void
17727 set_glyph_string_background_width (s, start, last_x)
17728 struct glyph_string *s;
17729 int start;
17730 int last_x;
17731 {
17732 /* If the face of this glyph string has to be drawn to the end of
17733 the drawing area, set S->extends_to_end_of_line_p. */
17734 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17735
17736 if (start == s->row->used[s->area]
17737 && s->area == TEXT_AREA
17738 && ((s->hl == DRAW_NORMAL_TEXT
17739 && (s->row->fill_line_p
17740 || s->face->background != default_face->background
17741 || s->face->stipple != default_face->stipple
17742 || s->row->mouse_face_p))
17743 || s->hl == DRAW_MOUSE_FACE
17744 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17745 && s->row->fill_line_p)))
17746 s->extends_to_end_of_line_p = 1;
17747
17748 /* If S extends its face to the end of the line, set its
17749 background_width to the distance to the right edge of the drawing
17750 area. */
17751 if (s->extends_to_end_of_line_p)
17752 s->background_width = last_x - s->x + 1;
17753 else
17754 s->background_width = s->width;
17755 }
17756
17757
17758 /* Compute overhangs and x-positions for glyph string S and its
17759 predecessors, or successors. X is the starting x-position for S.
17760 BACKWARD_P non-zero means process predecessors. */
17761
17762 static void
17763 compute_overhangs_and_x (s, x, backward_p)
17764 struct glyph_string *s;
17765 int x;
17766 int backward_p;
17767 {
17768 if (backward_p)
17769 {
17770 while (s)
17771 {
17772 if (rif->compute_glyph_string_overhangs)
17773 rif->compute_glyph_string_overhangs (s);
17774 x -= s->width;
17775 s->x = x;
17776 s = s->prev;
17777 }
17778 }
17779 else
17780 {
17781 while (s)
17782 {
17783 if (rif->compute_glyph_string_overhangs)
17784 rif->compute_glyph_string_overhangs (s);
17785 s->x = x;
17786 x += s->width;
17787 s = s->next;
17788 }
17789 }
17790 }
17791
17792
17793
17794 /* The following macros are only called from draw_glyphs below.
17795 They reference the following parameters of that function directly:
17796 `w', `row', `area', and `overlap_p'
17797 as well as the following local variables:
17798 `s', `f', and `hdc' (in W32) */
17799
17800 #ifdef HAVE_NTGUI
17801 /* On W32, silently add local `hdc' variable to argument list of
17802 init_glyph_string. */
17803 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17804 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17805 #else
17806 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17807 init_glyph_string (s, char2b, w, row, area, start, hl)
17808 #endif
17809
17810 /* Add a glyph string for a stretch glyph to the list of strings
17811 between HEAD and TAIL. START is the index of the stretch glyph in
17812 row area AREA of glyph row ROW. END is the index of the last glyph
17813 in that glyph row area. X is the current output position assigned
17814 to the new glyph string constructed. HL overrides that face of the
17815 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17816 is the right-most x-position of the drawing area. */
17817
17818 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17819 and below -- keep them on one line. */
17820 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17821 do \
17822 { \
17823 s = (struct glyph_string *) alloca (sizeof *s); \
17824 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17825 START = fill_stretch_glyph_string (s, row, area, START, END); \
17826 append_glyph_string (&HEAD, &TAIL, s); \
17827 s->x = (X); \
17828 } \
17829 while (0)
17830
17831
17832 /* Add a glyph string for an image glyph to the list of strings
17833 between HEAD and TAIL. START is the index of the image glyph in
17834 row area AREA of glyph row ROW. END is the index of the last glyph
17835 in that glyph row area. X is the current output position assigned
17836 to the new glyph string constructed. HL overrides that face of the
17837 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17838 is the right-most x-position of the drawing area. */
17839
17840 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17841 do \
17842 { \
17843 s = (struct glyph_string *) alloca (sizeof *s); \
17844 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17845 fill_image_glyph_string (s); \
17846 append_glyph_string (&HEAD, &TAIL, s); \
17847 ++START; \
17848 s->x = (X); \
17849 } \
17850 while (0)
17851
17852
17853 /* Add a glyph string for a sequence of character glyphs to the list
17854 of strings between HEAD and TAIL. START is the index of the first
17855 glyph in row area AREA of glyph row ROW that is part of the new
17856 glyph string. END is the index of the last glyph in that glyph row
17857 area. X is the current output position assigned to the new glyph
17858 string constructed. HL overrides that face of the glyph; e.g. it
17859 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17860 right-most x-position of the drawing area. */
17861
17862 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17863 do \
17864 { \
17865 int c, face_id; \
17866 XChar2b *char2b; \
17867 \
17868 c = (row)->glyphs[area][START].u.ch; \
17869 face_id = (row)->glyphs[area][START].face_id; \
17870 \
17871 s = (struct glyph_string *) alloca (sizeof *s); \
17872 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17873 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17874 append_glyph_string (&HEAD, &TAIL, s); \
17875 s->x = (X); \
17876 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17877 } \
17878 while (0)
17879
17880
17881 /* Add a glyph string for a composite sequence to the list of strings
17882 between HEAD and TAIL. START is the index of the first glyph in
17883 row area AREA of glyph row ROW that is part of the new glyph
17884 string. END is the index of the last glyph in that glyph row area.
17885 X is the current output position assigned to the new glyph string
17886 constructed. HL overrides that face of the glyph; e.g. it is
17887 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17888 x-position of the drawing area. */
17889
17890 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17891 do { \
17892 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17893 int face_id = (row)->glyphs[area][START].face_id; \
17894 struct face *base_face = FACE_FROM_ID (f, face_id); \
17895 struct composition *cmp = composition_table[cmp_id]; \
17896 int glyph_len = cmp->glyph_len; \
17897 XChar2b *char2b; \
17898 struct face **faces; \
17899 struct glyph_string *first_s = NULL; \
17900 int n; \
17901 \
17902 base_face = base_face->ascii_face; \
17903 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17904 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17905 /* At first, fill in `char2b' and `faces'. */ \
17906 for (n = 0; n < glyph_len; n++) \
17907 { \
17908 int c = COMPOSITION_GLYPH (cmp, n); \
17909 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17910 faces[n] = FACE_FROM_ID (f, this_face_id); \
17911 get_char_face_and_encoding (f, c, this_face_id, \
17912 char2b + n, 1, 1); \
17913 } \
17914 \
17915 /* Make glyph_strings for each glyph sequence that is drawable by \
17916 the same face, and append them to HEAD/TAIL. */ \
17917 for (n = 0; n < cmp->glyph_len;) \
17918 { \
17919 s = (struct glyph_string *) alloca (sizeof *s); \
17920 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17921 append_glyph_string (&(HEAD), &(TAIL), s); \
17922 s->cmp = cmp; \
17923 s->gidx = n; \
17924 s->x = (X); \
17925 \
17926 if (n == 0) \
17927 first_s = s; \
17928 \
17929 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17930 } \
17931 \
17932 ++START; \
17933 s = first_s; \
17934 } while (0)
17935
17936
17937 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17938 of AREA of glyph row ROW on window W between indices START and END.
17939 HL overrides the face for drawing glyph strings, e.g. it is
17940 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17941 x-positions of the drawing area.
17942
17943 This is an ugly monster macro construct because we must use alloca
17944 to allocate glyph strings (because draw_glyphs can be called
17945 asynchronously). */
17946
17947 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17948 do \
17949 { \
17950 HEAD = TAIL = NULL; \
17951 while (START < END) \
17952 { \
17953 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17954 switch (first_glyph->type) \
17955 { \
17956 case CHAR_GLYPH: \
17957 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17958 HL, X, LAST_X); \
17959 break; \
17960 \
17961 case COMPOSITE_GLYPH: \
17962 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17963 HL, X, LAST_X); \
17964 break; \
17965 \
17966 case STRETCH_GLYPH: \
17967 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17968 HL, X, LAST_X); \
17969 break; \
17970 \
17971 case IMAGE_GLYPH: \
17972 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17973 HL, X, LAST_X); \
17974 break; \
17975 \
17976 default: \
17977 abort (); \
17978 } \
17979 \
17980 set_glyph_string_background_width (s, START, LAST_X); \
17981 (X) += s->width; \
17982 } \
17983 } \
17984 while (0)
17985
17986
17987 /* Draw glyphs between START and END in AREA of ROW on window W,
17988 starting at x-position X. X is relative to AREA in W. HL is a
17989 face-override with the following meaning:
17990
17991 DRAW_NORMAL_TEXT draw normally
17992 DRAW_CURSOR draw in cursor face
17993 DRAW_MOUSE_FACE draw in mouse face.
17994 DRAW_INVERSE_VIDEO draw in mode line face
17995 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17996 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17997
17998 If OVERLAPS_P is non-zero, draw only the foreground of characters
17999 and clip to the physical height of ROW.
18000
18001 Value is the x-position reached, relative to AREA of W. */
18002
18003 static int
18004 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18005 struct window *w;
18006 int x;
18007 struct glyph_row *row;
18008 enum glyph_row_area area;
18009 int start, end;
18010 enum draw_glyphs_face hl;
18011 int overlaps_p;
18012 {
18013 struct glyph_string *head, *tail;
18014 struct glyph_string *s;
18015 int last_x, area_width;
18016 int x_reached;
18017 int i, j;
18018 struct frame *f = XFRAME (WINDOW_FRAME (w));
18019 DECLARE_HDC (hdc);
18020
18021 ALLOCATE_HDC (hdc, f);
18022
18023 /* Let's rather be paranoid than getting a SEGV. */
18024 end = min (end, row->used[area]);
18025 start = max (0, start);
18026 start = min (end, start);
18027
18028 /* Translate X to frame coordinates. Set last_x to the right
18029 end of the drawing area. */
18030 if (row->full_width_p)
18031 {
18032 /* X is relative to the left edge of W, without scroll bars
18033 or fringes. */
18034 x += WINDOW_LEFT_EDGE_X (w);
18035 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18036 }
18037 else
18038 {
18039 int area_left = window_box_left (w, area);
18040 x += area_left;
18041 area_width = window_box_width (w, area);
18042 last_x = area_left + area_width;
18043 }
18044
18045 /* Build a doubly-linked list of glyph_string structures between
18046 head and tail from what we have to draw. Note that the macro
18047 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18048 the reason we use a separate variable `i'. */
18049 i = start;
18050 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18051 if (tail)
18052 x_reached = tail->x + tail->background_width;
18053 else
18054 x_reached = x;
18055
18056 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18057 the row, redraw some glyphs in front or following the glyph
18058 strings built above. */
18059 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18060 {
18061 int dummy_x = 0;
18062 struct glyph_string *h, *t;
18063
18064 /* Compute overhangs for all glyph strings. */
18065 if (rif->compute_glyph_string_overhangs)
18066 for (s = head; s; s = s->next)
18067 rif->compute_glyph_string_overhangs (s);
18068
18069 /* Prepend glyph strings for glyphs in front of the first glyph
18070 string that are overwritten because of the first glyph
18071 string's left overhang. The background of all strings
18072 prepended must be drawn because the first glyph string
18073 draws over it. */
18074 i = left_overwritten (head);
18075 if (i >= 0)
18076 {
18077 j = i;
18078 BUILD_GLYPH_STRINGS (j, start, h, t,
18079 DRAW_NORMAL_TEXT, dummy_x, last_x);
18080 start = i;
18081 compute_overhangs_and_x (t, head->x, 1);
18082 prepend_glyph_string_lists (&head, &tail, h, t);
18083 }
18084
18085 /* Prepend glyph strings for glyphs in front of the first glyph
18086 string that overwrite that glyph string because of their
18087 right overhang. For these strings, only the foreground must
18088 be drawn, because it draws over the glyph string at `head'.
18089 The background must not be drawn because this would overwrite
18090 right overhangs of preceding glyphs for which no glyph
18091 strings exist. */
18092 i = left_overwriting (head);
18093 if (i >= 0)
18094 {
18095 BUILD_GLYPH_STRINGS (i, start, h, t,
18096 DRAW_NORMAL_TEXT, dummy_x, last_x);
18097 for (s = h; s; s = s->next)
18098 s->background_filled_p = 1;
18099 compute_overhangs_and_x (t, head->x, 1);
18100 prepend_glyph_string_lists (&head, &tail, h, t);
18101 }
18102
18103 /* Append glyphs strings for glyphs following the last glyph
18104 string tail that are overwritten by tail. The background of
18105 these strings has to be drawn because tail's foreground draws
18106 over it. */
18107 i = right_overwritten (tail);
18108 if (i >= 0)
18109 {
18110 BUILD_GLYPH_STRINGS (end, i, h, t,
18111 DRAW_NORMAL_TEXT, x, last_x);
18112 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18113 append_glyph_string_lists (&head, &tail, h, t);
18114 }
18115
18116 /* Append glyph strings for glyphs following the last glyph
18117 string tail that overwrite tail. The foreground of such
18118 glyphs has to be drawn because it writes into the background
18119 of tail. The background must not be drawn because it could
18120 paint over the foreground of following glyphs. */
18121 i = right_overwriting (tail);
18122 if (i >= 0)
18123 {
18124 BUILD_GLYPH_STRINGS (end, i, h, t,
18125 DRAW_NORMAL_TEXT, x, last_x);
18126 for (s = h; s; s = s->next)
18127 s->background_filled_p = 1;
18128 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18129 append_glyph_string_lists (&head, &tail, h, t);
18130 }
18131 }
18132
18133 /* Draw all strings. */
18134 for (s = head; s; s = s->next)
18135 rif->draw_glyph_string (s);
18136
18137 if (area == TEXT_AREA
18138 && !row->full_width_p
18139 /* When drawing overlapping rows, only the glyph strings'
18140 foreground is drawn, which doesn't erase a cursor
18141 completely. */
18142 && !overlaps_p)
18143 {
18144 int x0 = head ? head->x : x;
18145 int x1 = tail ? tail->x + tail->background_width : x;
18146
18147 int text_left = window_box_left (w, TEXT_AREA);
18148 x0 -= text_left;
18149 x1 -= text_left;
18150
18151 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18152 row->y, MATRIX_ROW_BOTTOM_Y (row));
18153 }
18154
18155 /* Value is the x-position up to which drawn, relative to AREA of W.
18156 This doesn't include parts drawn because of overhangs. */
18157 if (row->full_width_p)
18158 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18159 else
18160 x_reached -= window_box_left (w, area);
18161
18162 RELEASE_HDC (hdc, f);
18163
18164 return x_reached;
18165 }
18166
18167
18168 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18169 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18170
18171 static INLINE void
18172 append_glyph (it)
18173 struct it *it;
18174 {
18175 struct glyph *glyph;
18176 enum glyph_row_area area = it->area;
18177
18178 xassert (it->glyph_row);
18179 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18180
18181 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18182 if (glyph < it->glyph_row->glyphs[area + 1])
18183 {
18184 glyph->charpos = CHARPOS (it->position);
18185 glyph->object = it->object;
18186 glyph->pixel_width = it->pixel_width;
18187 glyph->ascent = it->ascent;
18188 glyph->descent = it->descent;
18189 glyph->voffset = it->voffset;
18190 glyph->type = CHAR_GLYPH;
18191 glyph->multibyte_p = it->multibyte_p;
18192 glyph->left_box_line_p = it->start_of_box_run_p;
18193 glyph->right_box_line_p = it->end_of_box_run_p;
18194 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18195 || it->phys_descent > it->descent);
18196 glyph->padding_p = 0;
18197 glyph->glyph_not_available_p = it->glyph_not_available_p;
18198 glyph->face_id = it->face_id;
18199 glyph->u.ch = it->char_to_display;
18200 glyph->slice = null_glyph_slice;
18201 glyph->font_type = FONT_TYPE_UNKNOWN;
18202 ++it->glyph_row->used[area];
18203 }
18204 else if (!fonts_changed_p)
18205 {
18206 it->w->ncols_scale_factor++;
18207 fonts_changed_p = 1;
18208 }
18209 }
18210
18211 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18212 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18213
18214 static INLINE void
18215 append_composite_glyph (it)
18216 struct it *it;
18217 {
18218 struct glyph *glyph;
18219 enum glyph_row_area area = it->area;
18220
18221 xassert (it->glyph_row);
18222
18223 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18224 if (glyph < it->glyph_row->glyphs[area + 1])
18225 {
18226 glyph->charpos = CHARPOS (it->position);
18227 glyph->object = it->object;
18228 glyph->pixel_width = it->pixel_width;
18229 glyph->ascent = it->ascent;
18230 glyph->descent = it->descent;
18231 glyph->voffset = it->voffset;
18232 glyph->type = COMPOSITE_GLYPH;
18233 glyph->multibyte_p = it->multibyte_p;
18234 glyph->left_box_line_p = it->start_of_box_run_p;
18235 glyph->right_box_line_p = it->end_of_box_run_p;
18236 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18237 || it->phys_descent > it->descent);
18238 glyph->padding_p = 0;
18239 glyph->glyph_not_available_p = 0;
18240 glyph->face_id = it->face_id;
18241 glyph->u.cmp_id = it->cmp_id;
18242 glyph->slice = null_glyph_slice;
18243 glyph->font_type = FONT_TYPE_UNKNOWN;
18244 ++it->glyph_row->used[area];
18245 }
18246 else if (!fonts_changed_p)
18247 {
18248 it->w->ncols_scale_factor++;
18249 fonts_changed_p = 1;
18250 }
18251 }
18252
18253
18254 /* Change IT->ascent and IT->height according to the setting of
18255 IT->voffset. */
18256
18257 static INLINE void
18258 take_vertical_position_into_account (it)
18259 struct it *it;
18260 {
18261 if (it->voffset)
18262 {
18263 if (it->voffset < 0)
18264 /* Increase the ascent so that we can display the text higher
18265 in the line. */
18266 it->ascent -= it->voffset;
18267 else
18268 /* Increase the descent so that we can display the text lower
18269 in the line. */
18270 it->descent += it->voffset;
18271 }
18272 }
18273
18274
18275 /* Produce glyphs/get display metrics for the image IT is loaded with.
18276 See the description of struct display_iterator in dispextern.h for
18277 an overview of struct display_iterator. */
18278
18279 static void
18280 produce_image_glyph (it)
18281 struct it *it;
18282 {
18283 struct image *img;
18284 struct face *face;
18285 int face_ascent, glyph_ascent;
18286 struct glyph_slice slice;
18287
18288 xassert (it->what == IT_IMAGE);
18289
18290 face = FACE_FROM_ID (it->f, it->face_id);
18291 xassert (face);
18292 /* Make sure X resources of the face is loaded. */
18293 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18294
18295 if (it->image_id < 0)
18296 {
18297 /* Fringe bitmap. */
18298 it->ascent = it->phys_ascent = 0;
18299 it->descent = it->phys_descent = 0;
18300 it->pixel_width = 0;
18301 it->nglyphs = 0;
18302 return;
18303 }
18304
18305 img = IMAGE_FROM_ID (it->f, it->image_id);
18306 xassert (img);
18307 /* Make sure X resources of the image is loaded. */
18308 prepare_image_for_display (it->f, img);
18309
18310 slice.x = slice.y = 0;
18311 slice.width = img->width;
18312 slice.height = img->height;
18313
18314 if (INTEGERP (it->slice.x))
18315 slice.x = XINT (it->slice.x);
18316 else if (FLOATP (it->slice.x))
18317 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18318
18319 if (INTEGERP (it->slice.y))
18320 slice.y = XINT (it->slice.y);
18321 else if (FLOATP (it->slice.y))
18322 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18323
18324 if (INTEGERP (it->slice.width))
18325 slice.width = XINT (it->slice.width);
18326 else if (FLOATP (it->slice.width))
18327 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18328
18329 if (INTEGERP (it->slice.height))
18330 slice.height = XINT (it->slice.height);
18331 else if (FLOATP (it->slice.height))
18332 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18333
18334 if (slice.x >= img->width)
18335 slice.x = img->width;
18336 if (slice.y >= img->height)
18337 slice.y = img->height;
18338 if (slice.x + slice.width >= img->width)
18339 slice.width = img->width - slice.x;
18340 if (slice.y + slice.height > img->height)
18341 slice.height = img->height - slice.y;
18342
18343 if (slice.width == 0 || slice.height == 0)
18344 return;
18345
18346 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18347
18348 it->descent = slice.height - glyph_ascent;
18349 if (slice.y == 0)
18350 it->descent += img->vmargin;
18351 if (slice.y + slice.height == img->height)
18352 it->descent += img->vmargin;
18353 it->phys_descent = it->descent;
18354
18355 it->pixel_width = slice.width;
18356 if (slice.x == 0)
18357 it->pixel_width += img->hmargin;
18358 if (slice.x + slice.width == img->width)
18359 it->pixel_width += img->hmargin;
18360
18361 /* It's quite possible for images to have an ascent greater than
18362 their height, so don't get confused in that case. */
18363 if (it->descent < 0)
18364 it->descent = 0;
18365
18366 #if 0 /* this breaks image tiling */
18367 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18368 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18369 if (face_ascent > it->ascent)
18370 it->ascent = it->phys_ascent = face_ascent;
18371 #endif
18372
18373 it->nglyphs = 1;
18374
18375 if (face->box != FACE_NO_BOX)
18376 {
18377 if (face->box_line_width > 0)
18378 {
18379 if (slice.y == 0)
18380 it->ascent += face->box_line_width;
18381 if (slice.y + slice.height == img->height)
18382 it->descent += face->box_line_width;
18383 }
18384
18385 if (it->start_of_box_run_p && slice.x == 0)
18386 it->pixel_width += abs (face->box_line_width);
18387 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18388 it->pixel_width += abs (face->box_line_width);
18389 }
18390
18391 take_vertical_position_into_account (it);
18392
18393 if (it->glyph_row)
18394 {
18395 struct glyph *glyph;
18396 enum glyph_row_area area = it->area;
18397
18398 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18399 if (glyph < it->glyph_row->glyphs[area + 1])
18400 {
18401 glyph->charpos = CHARPOS (it->position);
18402 glyph->object = it->object;
18403 glyph->pixel_width = it->pixel_width;
18404 glyph->ascent = glyph_ascent;
18405 glyph->descent = it->descent;
18406 glyph->voffset = it->voffset;
18407 glyph->type = IMAGE_GLYPH;
18408 glyph->multibyte_p = it->multibyte_p;
18409 glyph->left_box_line_p = it->start_of_box_run_p;
18410 glyph->right_box_line_p = it->end_of_box_run_p;
18411 glyph->overlaps_vertically_p = 0;
18412 glyph->padding_p = 0;
18413 glyph->glyph_not_available_p = 0;
18414 glyph->face_id = it->face_id;
18415 glyph->u.img_id = img->id;
18416 glyph->slice = slice;
18417 glyph->font_type = FONT_TYPE_UNKNOWN;
18418 ++it->glyph_row->used[area];
18419 }
18420 else if (!fonts_changed_p)
18421 {
18422 it->w->ncols_scale_factor++;
18423 fonts_changed_p = 1;
18424 }
18425 }
18426 }
18427
18428
18429 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18430 of the glyph, WIDTH and HEIGHT are the width and height of the
18431 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18432
18433 static void
18434 append_stretch_glyph (it, object, width, height, ascent)
18435 struct it *it;
18436 Lisp_Object object;
18437 int width, height;
18438 int ascent;
18439 {
18440 struct glyph *glyph;
18441 enum glyph_row_area area = it->area;
18442
18443 xassert (ascent >= 0 && ascent <= height);
18444
18445 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18446 if (glyph < it->glyph_row->glyphs[area + 1])
18447 {
18448 glyph->charpos = CHARPOS (it->position);
18449 glyph->object = object;
18450 glyph->pixel_width = width;
18451 glyph->ascent = ascent;
18452 glyph->descent = height - ascent;
18453 glyph->voffset = it->voffset;
18454 glyph->type = STRETCH_GLYPH;
18455 glyph->multibyte_p = it->multibyte_p;
18456 glyph->left_box_line_p = it->start_of_box_run_p;
18457 glyph->right_box_line_p = it->end_of_box_run_p;
18458 glyph->overlaps_vertically_p = 0;
18459 glyph->padding_p = 0;
18460 glyph->glyph_not_available_p = 0;
18461 glyph->face_id = it->face_id;
18462 glyph->u.stretch.ascent = ascent;
18463 glyph->u.stretch.height = height;
18464 glyph->slice = null_glyph_slice;
18465 glyph->font_type = FONT_TYPE_UNKNOWN;
18466 ++it->glyph_row->used[area];
18467 }
18468 else if (!fonts_changed_p)
18469 {
18470 it->w->ncols_scale_factor++;
18471 fonts_changed_p = 1;
18472 }
18473 }
18474
18475
18476 /* Produce a stretch glyph for iterator IT. IT->object is the value
18477 of the glyph property displayed. The value must be a list
18478 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18479 being recognized:
18480
18481 1. `:width WIDTH' specifies that the space should be WIDTH *
18482 canonical char width wide. WIDTH may be an integer or floating
18483 point number.
18484
18485 2. `:relative-width FACTOR' specifies that the width of the stretch
18486 should be computed from the width of the first character having the
18487 `glyph' property, and should be FACTOR times that width.
18488
18489 3. `:align-to HPOS' specifies that the space should be wide enough
18490 to reach HPOS, a value in canonical character units.
18491
18492 Exactly one of the above pairs must be present.
18493
18494 4. `:height HEIGHT' specifies that the height of the stretch produced
18495 should be HEIGHT, measured in canonical character units.
18496
18497 5. `:relative-height FACTOR' specifies that the height of the
18498 stretch should be FACTOR times the height of the characters having
18499 the glyph property.
18500
18501 Either none or exactly one of 4 or 5 must be present.
18502
18503 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18504 of the stretch should be used for the ascent of the stretch.
18505 ASCENT must be in the range 0 <= ASCENT <= 100. */
18506
18507 static void
18508 produce_stretch_glyph (it)
18509 struct it *it;
18510 {
18511 /* (space :width WIDTH :height HEIGHT ...) */
18512 Lisp_Object prop, plist;
18513 int width = 0, height = 0, align_to = -1;
18514 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18515 int ascent = 0;
18516 double tem;
18517 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18518 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18519
18520 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18521
18522 /* List should start with `space'. */
18523 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18524 plist = XCDR (it->object);
18525
18526 /* Compute the width of the stretch. */
18527 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18528 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18529 {
18530 /* Absolute width `:width WIDTH' specified and valid. */
18531 zero_width_ok_p = 1;
18532 width = (int)tem;
18533 }
18534 else if (prop = Fplist_get (plist, QCrelative_width),
18535 NUMVAL (prop) > 0)
18536 {
18537 /* Relative width `:relative-width FACTOR' specified and valid.
18538 Compute the width of the characters having the `glyph'
18539 property. */
18540 struct it it2;
18541 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18542
18543 it2 = *it;
18544 if (it->multibyte_p)
18545 {
18546 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18547 - IT_BYTEPOS (*it));
18548 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18549 }
18550 else
18551 it2.c = *p, it2.len = 1;
18552
18553 it2.glyph_row = NULL;
18554 it2.what = IT_CHARACTER;
18555 x_produce_glyphs (&it2);
18556 width = NUMVAL (prop) * it2.pixel_width;
18557 }
18558 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18559 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18560 {
18561 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18562 align_to = (align_to < 0
18563 ? 0
18564 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18565 else if (align_to < 0)
18566 align_to = window_box_left_offset (it->w, TEXT_AREA);
18567 width = max (0, (int)tem + align_to - it->current_x);
18568 zero_width_ok_p = 1;
18569 }
18570 else
18571 /* Nothing specified -> width defaults to canonical char width. */
18572 width = FRAME_COLUMN_WIDTH (it->f);
18573
18574 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18575 width = 1;
18576
18577 /* Compute height. */
18578 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18579 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18580 {
18581 height = (int)tem;
18582 zero_height_ok_p = 1;
18583 }
18584 else if (prop = Fplist_get (plist, QCrelative_height),
18585 NUMVAL (prop) > 0)
18586 height = FONT_HEIGHT (font) * NUMVAL (prop);
18587 else
18588 height = FONT_HEIGHT (font);
18589
18590 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18591 height = 1;
18592
18593 /* Compute percentage of height used for ascent. If
18594 `:ascent ASCENT' is present and valid, use that. Otherwise,
18595 derive the ascent from the font in use. */
18596 if (prop = Fplist_get (plist, QCascent),
18597 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18598 ascent = height * NUMVAL (prop) / 100.0;
18599 else if (!NILP (prop)
18600 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18601 ascent = min (max (0, (int)tem), height);
18602 else
18603 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18604
18605 if (width > 0 && height > 0 && it->glyph_row)
18606 {
18607 Lisp_Object object = it->stack[it->sp - 1].string;
18608 if (!STRINGP (object))
18609 object = it->w->buffer;
18610 append_stretch_glyph (it, object, width, height, ascent);
18611 }
18612
18613 it->pixel_width = width;
18614 it->ascent = it->phys_ascent = ascent;
18615 it->descent = it->phys_descent = height - it->ascent;
18616 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18617
18618 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18619 {
18620 if (face->box_line_width > 0)
18621 {
18622 it->ascent += face->box_line_width;
18623 it->descent += face->box_line_width;
18624 }
18625
18626 if (it->start_of_box_run_p)
18627 it->pixel_width += abs (face->box_line_width);
18628 if (it->end_of_box_run_p)
18629 it->pixel_width += abs (face->box_line_width);
18630 }
18631
18632 take_vertical_position_into_account (it);
18633 }
18634
18635 /* Calculate line-height and line-spacing properties.
18636 An integer value specifies explicit pixel value.
18637 A float value specifies relative value to current face height.
18638 A cons (float . face-name) specifies relative value to
18639 height of specified face font.
18640
18641 Returns height in pixels, or nil. */
18642
18643 static Lisp_Object
18644 calc_line_height_property (it, prop, font, boff, total)
18645 struct it *it;
18646 Lisp_Object prop;
18647 XFontStruct *font;
18648 int boff, *total;
18649 {
18650 Lisp_Object position, val;
18651 Lisp_Object face_name = Qnil;
18652 int ascent, descent, height, override;
18653
18654 if (STRINGP (it->object))
18655 position = make_number (IT_STRING_CHARPOS (*it));
18656 else
18657 position = make_number (IT_CHARPOS (*it));
18658
18659 val = Fget_char_property (position, prop, it->object);
18660
18661 if (NILP (val))
18662 return val;
18663
18664 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18665 {
18666 *total = 1;
18667 val = XCDR (val);
18668 }
18669
18670 if (INTEGERP (val))
18671 return val;
18672
18673 if (CONSP (val))
18674 {
18675 face_name = XCDR (val);
18676 val = XCAR (val);
18677 }
18678 else if (SYMBOLP (val))
18679 {
18680 face_name = val;
18681 val = Qnil;
18682 }
18683
18684 override = EQ (prop, Qline_height);
18685
18686 if (NILP (face_name))
18687 {
18688 font = FRAME_FONT (it->f);
18689 boff = FRAME_BASELINE_OFFSET (it->f);
18690 }
18691 else if (EQ (face_name, Qt))
18692 {
18693 override = 0;
18694 }
18695 else
18696 {
18697 int face_id;
18698 struct face *face;
18699 struct font_info *font_info;
18700
18701 face_id = lookup_named_face (it->f, face_name, ' ');
18702 if (face_id < 0)
18703 return make_number (-1);
18704
18705 face = FACE_FROM_ID (it->f, face_id);
18706 font = face->font;
18707 if (font == NULL)
18708 return make_number (-1);
18709
18710 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18711 boff = font_info->baseline_offset;
18712 if (font_info->vertical_centering)
18713 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18714 }
18715
18716 ascent = FONT_BASE (font) + boff;
18717 descent = FONT_DESCENT (font) - boff;
18718
18719 if (override)
18720 {
18721 it->override_ascent = ascent;
18722 it->override_descent = descent;
18723 it->override_boff = boff;
18724 }
18725
18726 height = ascent + descent;
18727 if (FLOATP (val))
18728 height = (int)(XFLOAT_DATA (val) * height);
18729 else if (INTEGERP (val))
18730 height *= XINT (val);
18731
18732 return make_number (height);
18733 }
18734
18735
18736 /* RIF:
18737 Produce glyphs/get display metrics for the display element IT is
18738 loaded with. See the description of struct display_iterator in
18739 dispextern.h for an overview of struct display_iterator. */
18740
18741 void
18742 x_produce_glyphs (it)
18743 struct it *it;
18744 {
18745 int extra_line_spacing = it->extra_line_spacing;
18746
18747 it->glyph_not_available_p = 0;
18748
18749 if (it->what == IT_CHARACTER)
18750 {
18751 XChar2b char2b;
18752 XFontStruct *font;
18753 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18754 XCharStruct *pcm;
18755 int font_not_found_p;
18756 struct font_info *font_info;
18757 int boff; /* baseline offset */
18758 /* We may change it->multibyte_p upon unibyte<->multibyte
18759 conversion. So, save the current value now and restore it
18760 later.
18761
18762 Note: It seems that we don't have to record multibyte_p in
18763 struct glyph because the character code itself tells if or
18764 not the character is multibyte. Thus, in the future, we must
18765 consider eliminating the field `multibyte_p' in the struct
18766 glyph. */
18767 int saved_multibyte_p = it->multibyte_p;
18768
18769 /* Maybe translate single-byte characters to multibyte, or the
18770 other way. */
18771 it->char_to_display = it->c;
18772 if (!ASCII_BYTE_P (it->c))
18773 {
18774 if (unibyte_display_via_language_environment
18775 && SINGLE_BYTE_CHAR_P (it->c)
18776 && (it->c >= 0240
18777 || !NILP (Vnonascii_translation_table)))
18778 {
18779 it->char_to_display = unibyte_char_to_multibyte (it->c);
18780 it->multibyte_p = 1;
18781 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18782 face = FACE_FROM_ID (it->f, it->face_id);
18783 }
18784 else if (!SINGLE_BYTE_CHAR_P (it->c)
18785 && !it->multibyte_p)
18786 {
18787 it->multibyte_p = 1;
18788 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18789 face = FACE_FROM_ID (it->f, it->face_id);
18790 }
18791 }
18792
18793 /* Get font to use. Encode IT->char_to_display. */
18794 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18795 &char2b, it->multibyte_p, 0);
18796 font = face->font;
18797
18798 /* When no suitable font found, use the default font. */
18799 font_not_found_p = font == NULL;
18800 if (font_not_found_p)
18801 {
18802 font = FRAME_FONT (it->f);
18803 boff = FRAME_BASELINE_OFFSET (it->f);
18804 font_info = NULL;
18805 }
18806 else
18807 {
18808 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18809 boff = font_info->baseline_offset;
18810 if (font_info->vertical_centering)
18811 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18812 }
18813
18814 if (it->char_to_display >= ' '
18815 && (!it->multibyte_p || it->char_to_display < 128))
18816 {
18817 /* Either unibyte or ASCII. */
18818 int stretched_p;
18819
18820 it->nglyphs = 1;
18821
18822 pcm = rif->per_char_metric (font, &char2b,
18823 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18824
18825 if (it->override_ascent >= 0)
18826 {
18827 it->ascent = it->override_ascent;
18828 it->descent = it->override_descent;
18829 boff = it->override_boff;
18830 }
18831 else
18832 {
18833 it->ascent = FONT_BASE (font) + boff;
18834 it->descent = FONT_DESCENT (font) - boff;
18835 }
18836
18837 if (pcm)
18838 {
18839 it->phys_ascent = pcm->ascent + boff;
18840 it->phys_descent = pcm->descent - boff;
18841 it->pixel_width = pcm->width;
18842 }
18843 else
18844 {
18845 it->glyph_not_available_p = 1;
18846 it->phys_ascent = it->ascent;
18847 it->phys_descent = it->descent;
18848 it->pixel_width = FONT_WIDTH (font);
18849 }
18850
18851 if (it->constrain_row_ascent_descent_p)
18852 {
18853 if (it->descent > it->max_descent)
18854 {
18855 it->ascent += it->descent - it->max_descent;
18856 it->descent = it->max_descent;
18857 }
18858 if (it->ascent > it->max_ascent)
18859 {
18860 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18861 it->ascent = it->max_ascent;
18862 }
18863 it->phys_ascent = min (it->phys_ascent, it->ascent);
18864 it->phys_descent = min (it->phys_descent, it->descent);
18865 extra_line_spacing = 0;
18866 }
18867
18868 /* If this is a space inside a region of text with
18869 `space-width' property, change its width. */
18870 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18871 if (stretched_p)
18872 it->pixel_width *= XFLOATINT (it->space_width);
18873
18874 /* If face has a box, add the box thickness to the character
18875 height. If character has a box line to the left and/or
18876 right, add the box line width to the character's width. */
18877 if (face->box != FACE_NO_BOX)
18878 {
18879 int thick = face->box_line_width;
18880
18881 if (thick > 0)
18882 {
18883 it->ascent += thick;
18884 it->descent += thick;
18885 }
18886 else
18887 thick = -thick;
18888
18889 if (it->start_of_box_run_p)
18890 it->pixel_width += thick;
18891 if (it->end_of_box_run_p)
18892 it->pixel_width += thick;
18893 }
18894
18895 /* If face has an overline, add the height of the overline
18896 (1 pixel) and a 1 pixel margin to the character height. */
18897 if (face->overline_p)
18898 it->ascent += 2;
18899
18900 if (it->constrain_row_ascent_descent_p)
18901 {
18902 if (it->ascent > it->max_ascent)
18903 it->ascent = it->max_ascent;
18904 if (it->descent > it->max_descent)
18905 it->descent = it->max_descent;
18906 }
18907
18908 take_vertical_position_into_account (it);
18909
18910 /* If we have to actually produce glyphs, do it. */
18911 if (it->glyph_row)
18912 {
18913 if (stretched_p)
18914 {
18915 /* Translate a space with a `space-width' property
18916 into a stretch glyph. */
18917 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18918 / FONT_HEIGHT (font));
18919 append_stretch_glyph (it, it->object, it->pixel_width,
18920 it->ascent + it->descent, ascent);
18921 }
18922 else
18923 append_glyph (it);
18924
18925 /* If characters with lbearing or rbearing are displayed
18926 in this line, record that fact in a flag of the
18927 glyph row. This is used to optimize X output code. */
18928 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18929 it->glyph_row->contains_overlapping_glyphs_p = 1;
18930 }
18931 }
18932 else if (it->char_to_display == '\n')
18933 {
18934 /* A newline has no width but we need the height of the line.
18935 But if previous part of the line set a height, don't
18936 increase that height */
18937
18938 Lisp_Object height;
18939
18940 it->override_ascent = -1;
18941 it->pixel_width = 0;
18942 it->nglyphs = 0;
18943
18944 height = calc_line_height_property(it, Qline_height, font, boff, 0);
18945
18946 if (it->override_ascent >= 0)
18947 {
18948 it->ascent = it->override_ascent;
18949 it->descent = it->override_descent;
18950 boff = it->override_boff;
18951 }
18952 else
18953 {
18954 it->ascent = FONT_BASE (font) + boff;
18955 it->descent = FONT_DESCENT (font) - boff;
18956 }
18957
18958 if (EQ (height, make_number(0)))
18959 {
18960 if (it->descent > it->max_descent)
18961 {
18962 it->ascent += it->descent - it->max_descent;
18963 it->descent = it->max_descent;
18964 }
18965 if (it->ascent > it->max_ascent)
18966 {
18967 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18968 it->ascent = it->max_ascent;
18969 }
18970 it->phys_ascent = min (it->phys_ascent, it->ascent);
18971 it->phys_descent = min (it->phys_descent, it->descent);
18972 it->constrain_row_ascent_descent_p = 1;
18973 extra_line_spacing = 0;
18974 }
18975 else
18976 {
18977 Lisp_Object spacing;
18978 int total = 0;
18979
18980 it->phys_ascent = it->ascent;
18981 it->phys_descent = it->descent;
18982
18983 if ((it->max_ascent > 0 || it->max_descent > 0)
18984 && face->box != FACE_NO_BOX
18985 && face->box_line_width > 0)
18986 {
18987 it->ascent += face->box_line_width;
18988 it->descent += face->box_line_width;
18989 }
18990 if (!NILP (height)
18991 && XINT (height) > it->ascent + it->descent)
18992 it->ascent = XINT (height) - it->descent;
18993
18994 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
18995 if (INTEGERP (spacing))
18996 {
18997 extra_line_spacing = XINT (spacing);
18998 if (total)
18999 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19000 }
19001 }
19002 }
19003 else if (it->char_to_display == '\t')
19004 {
19005 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19006 int x = it->current_x + it->continuation_lines_width;
19007 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19008
19009 /* If the distance from the current position to the next tab
19010 stop is less than a canonical character width, use the
19011 tab stop after that. */
19012 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19013 next_tab_x += tab_width;
19014
19015 it->pixel_width = next_tab_x - x;
19016 it->nglyphs = 1;
19017 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19018 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19019
19020 if (it->glyph_row)
19021 {
19022 append_stretch_glyph (it, it->object, it->pixel_width,
19023 it->ascent + it->descent, it->ascent);
19024 }
19025 }
19026 else
19027 {
19028 /* A multi-byte character. Assume that the display width of the
19029 character is the width of the character multiplied by the
19030 width of the font. */
19031
19032 /* If we found a font, this font should give us the right
19033 metrics. If we didn't find a font, use the frame's
19034 default font and calculate the width of the character
19035 from the charset width; this is what old redisplay code
19036 did. */
19037
19038 pcm = rif->per_char_metric (font, &char2b,
19039 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19040
19041 if (font_not_found_p || !pcm)
19042 {
19043 int charset = CHAR_CHARSET (it->char_to_display);
19044
19045 it->glyph_not_available_p = 1;
19046 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19047 * CHARSET_WIDTH (charset));
19048 it->phys_ascent = FONT_BASE (font) + boff;
19049 it->phys_descent = FONT_DESCENT (font) - boff;
19050 }
19051 else
19052 {
19053 it->pixel_width = pcm->width;
19054 it->phys_ascent = pcm->ascent + boff;
19055 it->phys_descent = pcm->descent - boff;
19056 if (it->glyph_row
19057 && (pcm->lbearing < 0
19058 || pcm->rbearing > pcm->width))
19059 it->glyph_row->contains_overlapping_glyphs_p = 1;
19060 }
19061 it->nglyphs = 1;
19062 it->ascent = FONT_BASE (font) + boff;
19063 it->descent = FONT_DESCENT (font) - boff;
19064 if (face->box != FACE_NO_BOX)
19065 {
19066 int thick = face->box_line_width;
19067
19068 if (thick > 0)
19069 {
19070 it->ascent += thick;
19071 it->descent += thick;
19072 }
19073 else
19074 thick = - thick;
19075
19076 if (it->start_of_box_run_p)
19077 it->pixel_width += thick;
19078 if (it->end_of_box_run_p)
19079 it->pixel_width += thick;
19080 }
19081
19082 /* If face has an overline, add the height of the overline
19083 (1 pixel) and a 1 pixel margin to the character height. */
19084 if (face->overline_p)
19085 it->ascent += 2;
19086
19087 take_vertical_position_into_account (it);
19088
19089 if (it->glyph_row)
19090 append_glyph (it);
19091 }
19092 it->multibyte_p = saved_multibyte_p;
19093 }
19094 else if (it->what == IT_COMPOSITION)
19095 {
19096 /* Note: A composition is represented as one glyph in the
19097 glyph matrix. There are no padding glyphs. */
19098 XChar2b char2b;
19099 XFontStruct *font;
19100 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19101 XCharStruct *pcm;
19102 int font_not_found_p;
19103 struct font_info *font_info;
19104 int boff; /* baseline offset */
19105 struct composition *cmp = composition_table[it->cmp_id];
19106
19107 /* Maybe translate single-byte characters to multibyte. */
19108 it->char_to_display = it->c;
19109 if (unibyte_display_via_language_environment
19110 && SINGLE_BYTE_CHAR_P (it->c)
19111 && (it->c >= 0240
19112 || (it->c >= 0200
19113 && !NILP (Vnonascii_translation_table))))
19114 {
19115 it->char_to_display = unibyte_char_to_multibyte (it->c);
19116 }
19117
19118 /* Get face and font to use. Encode IT->char_to_display. */
19119 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19120 face = FACE_FROM_ID (it->f, it->face_id);
19121 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19122 &char2b, it->multibyte_p, 0);
19123 font = face->font;
19124
19125 /* When no suitable font found, use the default font. */
19126 font_not_found_p = font == NULL;
19127 if (font_not_found_p)
19128 {
19129 font = FRAME_FONT (it->f);
19130 boff = FRAME_BASELINE_OFFSET (it->f);
19131 font_info = NULL;
19132 }
19133 else
19134 {
19135 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19136 boff = font_info->baseline_offset;
19137 if (font_info->vertical_centering)
19138 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19139 }
19140
19141 /* There are no padding glyphs, so there is only one glyph to
19142 produce for the composition. Important is that pixel_width,
19143 ascent and descent are the values of what is drawn by
19144 draw_glyphs (i.e. the values of the overall glyphs composed). */
19145 it->nglyphs = 1;
19146
19147 /* If we have not yet calculated pixel size data of glyphs of
19148 the composition for the current face font, calculate them
19149 now. Theoretically, we have to check all fonts for the
19150 glyphs, but that requires much time and memory space. So,
19151 here we check only the font of the first glyph. This leads
19152 to incorrect display very rarely, and C-l (recenter) can
19153 correct the display anyway. */
19154 if (cmp->font != (void *) font)
19155 {
19156 /* Ascent and descent of the font of the first character of
19157 this composition (adjusted by baseline offset). Ascent
19158 and descent of overall glyphs should not be less than
19159 them respectively. */
19160 int font_ascent = FONT_BASE (font) + boff;
19161 int font_descent = FONT_DESCENT (font) - boff;
19162 /* Bounding box of the overall glyphs. */
19163 int leftmost, rightmost, lowest, highest;
19164 int i, width, ascent, descent;
19165
19166 cmp->font = (void *) font;
19167
19168 /* Initialize the bounding box. */
19169 if (font_info
19170 && (pcm = rif->per_char_metric (font, &char2b,
19171 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19172 {
19173 width = pcm->width;
19174 ascent = pcm->ascent;
19175 descent = pcm->descent;
19176 }
19177 else
19178 {
19179 width = FONT_WIDTH (font);
19180 ascent = FONT_BASE (font);
19181 descent = FONT_DESCENT (font);
19182 }
19183
19184 rightmost = width;
19185 lowest = - descent + boff;
19186 highest = ascent + boff;
19187 leftmost = 0;
19188
19189 if (font_info
19190 && font_info->default_ascent
19191 && CHAR_TABLE_P (Vuse_default_ascent)
19192 && !NILP (Faref (Vuse_default_ascent,
19193 make_number (it->char_to_display))))
19194 highest = font_info->default_ascent + boff;
19195
19196 /* Draw the first glyph at the normal position. It may be
19197 shifted to right later if some other glyphs are drawn at
19198 the left. */
19199 cmp->offsets[0] = 0;
19200 cmp->offsets[1] = boff;
19201
19202 /* Set cmp->offsets for the remaining glyphs. */
19203 for (i = 1; i < cmp->glyph_len; i++)
19204 {
19205 int left, right, btm, top;
19206 int ch = COMPOSITION_GLYPH (cmp, i);
19207 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19208
19209 face = FACE_FROM_ID (it->f, face_id);
19210 get_char_face_and_encoding (it->f, ch, face->id,
19211 &char2b, it->multibyte_p, 0);
19212 font = face->font;
19213 if (font == NULL)
19214 {
19215 font = FRAME_FONT (it->f);
19216 boff = FRAME_BASELINE_OFFSET (it->f);
19217 font_info = NULL;
19218 }
19219 else
19220 {
19221 font_info
19222 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19223 boff = font_info->baseline_offset;
19224 if (font_info->vertical_centering)
19225 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19226 }
19227
19228 if (font_info
19229 && (pcm = rif->per_char_metric (font, &char2b,
19230 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19231 {
19232 width = pcm->width;
19233 ascent = pcm->ascent;
19234 descent = pcm->descent;
19235 }
19236 else
19237 {
19238 width = FONT_WIDTH (font);
19239 ascent = 1;
19240 descent = 0;
19241 }
19242
19243 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19244 {
19245 /* Relative composition with or without
19246 alternate chars. */
19247 left = (leftmost + rightmost - width) / 2;
19248 btm = - descent + boff;
19249 if (font_info && font_info->relative_compose
19250 && (! CHAR_TABLE_P (Vignore_relative_composition)
19251 || NILP (Faref (Vignore_relative_composition,
19252 make_number (ch)))))
19253 {
19254
19255 if (- descent >= font_info->relative_compose)
19256 /* One extra pixel between two glyphs. */
19257 btm = highest + 1;
19258 else if (ascent <= 0)
19259 /* One extra pixel between two glyphs. */
19260 btm = lowest - 1 - ascent - descent;
19261 }
19262 }
19263 else
19264 {
19265 /* A composition rule is specified by an integer
19266 value that encodes global and new reference
19267 points (GREF and NREF). GREF and NREF are
19268 specified by numbers as below:
19269
19270 0---1---2 -- ascent
19271 | |
19272 | |
19273 | |
19274 9--10--11 -- center
19275 | |
19276 ---3---4---5--- baseline
19277 | |
19278 6---7---8 -- descent
19279 */
19280 int rule = COMPOSITION_RULE (cmp, i);
19281 int gref, nref, grefx, grefy, nrefx, nrefy;
19282
19283 COMPOSITION_DECODE_RULE (rule, gref, nref);
19284 grefx = gref % 3, nrefx = nref % 3;
19285 grefy = gref / 3, nrefy = nref / 3;
19286
19287 left = (leftmost
19288 + grefx * (rightmost - leftmost) / 2
19289 - nrefx * width / 2);
19290 btm = ((grefy == 0 ? highest
19291 : grefy == 1 ? 0
19292 : grefy == 2 ? lowest
19293 : (highest + lowest) / 2)
19294 - (nrefy == 0 ? ascent + descent
19295 : nrefy == 1 ? descent - boff
19296 : nrefy == 2 ? 0
19297 : (ascent + descent) / 2));
19298 }
19299
19300 cmp->offsets[i * 2] = left;
19301 cmp->offsets[i * 2 + 1] = btm + descent;
19302
19303 /* Update the bounding box of the overall glyphs. */
19304 right = left + width;
19305 top = btm + descent + ascent;
19306 if (left < leftmost)
19307 leftmost = left;
19308 if (right > rightmost)
19309 rightmost = right;
19310 if (top > highest)
19311 highest = top;
19312 if (btm < lowest)
19313 lowest = btm;
19314 }
19315
19316 /* If there are glyphs whose x-offsets are negative,
19317 shift all glyphs to the right and make all x-offsets
19318 non-negative. */
19319 if (leftmost < 0)
19320 {
19321 for (i = 0; i < cmp->glyph_len; i++)
19322 cmp->offsets[i * 2] -= leftmost;
19323 rightmost -= leftmost;
19324 }
19325
19326 cmp->pixel_width = rightmost;
19327 cmp->ascent = highest;
19328 cmp->descent = - lowest;
19329 if (cmp->ascent < font_ascent)
19330 cmp->ascent = font_ascent;
19331 if (cmp->descent < font_descent)
19332 cmp->descent = font_descent;
19333 }
19334
19335 it->pixel_width = cmp->pixel_width;
19336 it->ascent = it->phys_ascent = cmp->ascent;
19337 it->descent = it->phys_descent = cmp->descent;
19338
19339 if (face->box != FACE_NO_BOX)
19340 {
19341 int thick = face->box_line_width;
19342
19343 if (thick > 0)
19344 {
19345 it->ascent += thick;
19346 it->descent += thick;
19347 }
19348 else
19349 thick = - thick;
19350
19351 if (it->start_of_box_run_p)
19352 it->pixel_width += thick;
19353 if (it->end_of_box_run_p)
19354 it->pixel_width += thick;
19355 }
19356
19357 /* If face has an overline, add the height of the overline
19358 (1 pixel) and a 1 pixel margin to the character height. */
19359 if (face->overline_p)
19360 it->ascent += 2;
19361
19362 take_vertical_position_into_account (it);
19363
19364 if (it->glyph_row)
19365 append_composite_glyph (it);
19366 }
19367 else if (it->what == IT_IMAGE)
19368 produce_image_glyph (it);
19369 else if (it->what == IT_STRETCH)
19370 produce_stretch_glyph (it);
19371
19372 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19373 because this isn't true for images with `:ascent 100'. */
19374 xassert (it->ascent >= 0 && it->descent >= 0);
19375 if (it->area == TEXT_AREA)
19376 it->current_x += it->pixel_width;
19377
19378 if (extra_line_spacing > 0)
19379 it->descent += extra_line_spacing;
19380
19381 it->max_ascent = max (it->max_ascent, it->ascent);
19382 it->max_descent = max (it->max_descent, it->descent);
19383 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19384 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19385 }
19386
19387 /* EXPORT for RIF:
19388 Output LEN glyphs starting at START at the nominal cursor position.
19389 Advance the nominal cursor over the text. The global variable
19390 updated_window contains the window being updated, updated_row is
19391 the glyph row being updated, and updated_area is the area of that
19392 row being updated. */
19393
19394 void
19395 x_write_glyphs (start, len)
19396 struct glyph *start;
19397 int len;
19398 {
19399 int x, hpos;
19400
19401 xassert (updated_window && updated_row);
19402 BLOCK_INPUT;
19403
19404 /* Write glyphs. */
19405
19406 hpos = start - updated_row->glyphs[updated_area];
19407 x = draw_glyphs (updated_window, output_cursor.x,
19408 updated_row, updated_area,
19409 hpos, hpos + len,
19410 DRAW_NORMAL_TEXT, 0);
19411
19412 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19413 if (updated_area == TEXT_AREA
19414 && updated_window->phys_cursor_on_p
19415 && updated_window->phys_cursor.vpos == output_cursor.vpos
19416 && updated_window->phys_cursor.hpos >= hpos
19417 && updated_window->phys_cursor.hpos < hpos + len)
19418 updated_window->phys_cursor_on_p = 0;
19419
19420 UNBLOCK_INPUT;
19421
19422 /* Advance the output cursor. */
19423 output_cursor.hpos += len;
19424 output_cursor.x = x;
19425 }
19426
19427
19428 /* EXPORT for RIF:
19429 Insert LEN glyphs from START at the nominal cursor position. */
19430
19431 void
19432 x_insert_glyphs (start, len)
19433 struct glyph *start;
19434 int len;
19435 {
19436 struct frame *f;
19437 struct window *w;
19438 int line_height, shift_by_width, shifted_region_width;
19439 struct glyph_row *row;
19440 struct glyph *glyph;
19441 int frame_x, frame_y, hpos;
19442
19443 xassert (updated_window && updated_row);
19444 BLOCK_INPUT;
19445 w = updated_window;
19446 f = XFRAME (WINDOW_FRAME (w));
19447
19448 /* Get the height of the line we are in. */
19449 row = updated_row;
19450 line_height = row->height;
19451
19452 /* Get the width of the glyphs to insert. */
19453 shift_by_width = 0;
19454 for (glyph = start; glyph < start + len; ++glyph)
19455 shift_by_width += glyph->pixel_width;
19456
19457 /* Get the width of the region to shift right. */
19458 shifted_region_width = (window_box_width (w, updated_area)
19459 - output_cursor.x
19460 - shift_by_width);
19461
19462 /* Shift right. */
19463 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19464 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19465
19466 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19467 line_height, shift_by_width);
19468
19469 /* Write the glyphs. */
19470 hpos = start - row->glyphs[updated_area];
19471 draw_glyphs (w, output_cursor.x, row, updated_area,
19472 hpos, hpos + len,
19473 DRAW_NORMAL_TEXT, 0);
19474
19475 /* Advance the output cursor. */
19476 output_cursor.hpos += len;
19477 output_cursor.x += shift_by_width;
19478 UNBLOCK_INPUT;
19479 }
19480
19481
19482 /* EXPORT for RIF:
19483 Erase the current text line from the nominal cursor position
19484 (inclusive) to pixel column TO_X (exclusive). The idea is that
19485 everything from TO_X onward is already erased.
19486
19487 TO_X is a pixel position relative to updated_area of
19488 updated_window. TO_X == -1 means clear to the end of this area. */
19489
19490 void
19491 x_clear_end_of_line (to_x)
19492 int to_x;
19493 {
19494 struct frame *f;
19495 struct window *w = updated_window;
19496 int max_x, min_y, max_y;
19497 int from_x, from_y, to_y;
19498
19499 xassert (updated_window && updated_row);
19500 f = XFRAME (w->frame);
19501
19502 if (updated_row->full_width_p)
19503 max_x = WINDOW_TOTAL_WIDTH (w);
19504 else
19505 max_x = window_box_width (w, updated_area);
19506 max_y = window_text_bottom_y (w);
19507
19508 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19509 of window. For TO_X > 0, truncate to end of drawing area. */
19510 if (to_x == 0)
19511 return;
19512 else if (to_x < 0)
19513 to_x = max_x;
19514 else
19515 to_x = min (to_x, max_x);
19516
19517 to_y = min (max_y, output_cursor.y + updated_row->height);
19518
19519 /* Notice if the cursor will be cleared by this operation. */
19520 if (!updated_row->full_width_p)
19521 notice_overwritten_cursor (w, updated_area,
19522 output_cursor.x, -1,
19523 updated_row->y,
19524 MATRIX_ROW_BOTTOM_Y (updated_row));
19525
19526 from_x = output_cursor.x;
19527
19528 /* Translate to frame coordinates. */
19529 if (updated_row->full_width_p)
19530 {
19531 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19532 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19533 }
19534 else
19535 {
19536 int area_left = window_box_left (w, updated_area);
19537 from_x += area_left;
19538 to_x += area_left;
19539 }
19540
19541 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19542 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19543 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19544
19545 /* Prevent inadvertently clearing to end of the X window. */
19546 if (to_x > from_x && to_y > from_y)
19547 {
19548 BLOCK_INPUT;
19549 rif->clear_frame_area (f, from_x, from_y,
19550 to_x - from_x, to_y - from_y);
19551 UNBLOCK_INPUT;
19552 }
19553 }
19554
19555 #endif /* HAVE_WINDOW_SYSTEM */
19556
19557
19558 \f
19559 /***********************************************************************
19560 Cursor types
19561 ***********************************************************************/
19562
19563 /* Value is the internal representation of the specified cursor type
19564 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19565 of the bar cursor. */
19566
19567 static enum text_cursor_kinds
19568 get_specified_cursor_type (arg, width)
19569 Lisp_Object arg;
19570 int *width;
19571 {
19572 enum text_cursor_kinds type;
19573
19574 if (NILP (arg))
19575 return NO_CURSOR;
19576
19577 if (EQ (arg, Qbox))
19578 return FILLED_BOX_CURSOR;
19579
19580 if (EQ (arg, Qhollow))
19581 return HOLLOW_BOX_CURSOR;
19582
19583 if (EQ (arg, Qbar))
19584 {
19585 *width = 2;
19586 return BAR_CURSOR;
19587 }
19588
19589 if (CONSP (arg)
19590 && EQ (XCAR (arg), Qbar)
19591 && INTEGERP (XCDR (arg))
19592 && XINT (XCDR (arg)) >= 0)
19593 {
19594 *width = XINT (XCDR (arg));
19595 return BAR_CURSOR;
19596 }
19597
19598 if (EQ (arg, Qhbar))
19599 {
19600 *width = 2;
19601 return HBAR_CURSOR;
19602 }
19603
19604 if (CONSP (arg)
19605 && EQ (XCAR (arg), Qhbar)
19606 && INTEGERP (XCDR (arg))
19607 && XINT (XCDR (arg)) >= 0)
19608 {
19609 *width = XINT (XCDR (arg));
19610 return HBAR_CURSOR;
19611 }
19612
19613 /* Treat anything unknown as "hollow box cursor".
19614 It was bad to signal an error; people have trouble fixing
19615 .Xdefaults with Emacs, when it has something bad in it. */
19616 type = HOLLOW_BOX_CURSOR;
19617
19618 return type;
19619 }
19620
19621 /* Set the default cursor types for specified frame. */
19622 void
19623 set_frame_cursor_types (f, arg)
19624 struct frame *f;
19625 Lisp_Object arg;
19626 {
19627 int width;
19628 Lisp_Object tem;
19629
19630 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19631 FRAME_CURSOR_WIDTH (f) = width;
19632
19633 /* By default, set up the blink-off state depending on the on-state. */
19634
19635 tem = Fassoc (arg, Vblink_cursor_alist);
19636 if (!NILP (tem))
19637 {
19638 FRAME_BLINK_OFF_CURSOR (f)
19639 = get_specified_cursor_type (XCDR (tem), &width);
19640 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19641 }
19642 else
19643 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19644 }
19645
19646
19647 /* Return the cursor we want to be displayed in window W. Return
19648 width of bar/hbar cursor through WIDTH arg. Return with
19649 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19650 (i.e. if the `system caret' should track this cursor).
19651
19652 In a mini-buffer window, we want the cursor only to appear if we
19653 are reading input from this window. For the selected window, we
19654 want the cursor type given by the frame parameter or buffer local
19655 setting of cursor-type. If explicitly marked off, draw no cursor.
19656 In all other cases, we want a hollow box cursor. */
19657
19658 static enum text_cursor_kinds
19659 get_window_cursor_type (w, glyph, width, active_cursor)
19660 struct window *w;
19661 struct glyph *glyph;
19662 int *width;
19663 int *active_cursor;
19664 {
19665 struct frame *f = XFRAME (w->frame);
19666 struct buffer *b = XBUFFER (w->buffer);
19667 int cursor_type = DEFAULT_CURSOR;
19668 Lisp_Object alt_cursor;
19669 int non_selected = 0;
19670
19671 *active_cursor = 1;
19672
19673 /* Echo area */
19674 if (cursor_in_echo_area
19675 && FRAME_HAS_MINIBUF_P (f)
19676 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19677 {
19678 if (w == XWINDOW (echo_area_window))
19679 {
19680 *width = FRAME_CURSOR_WIDTH (f);
19681 return FRAME_DESIRED_CURSOR (f);
19682 }
19683
19684 *active_cursor = 0;
19685 non_selected = 1;
19686 }
19687
19688 /* Nonselected window or nonselected frame. */
19689 else if (w != XWINDOW (f->selected_window)
19690 #ifdef HAVE_WINDOW_SYSTEM
19691 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19692 #endif
19693 )
19694 {
19695 *active_cursor = 0;
19696
19697 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19698 return NO_CURSOR;
19699
19700 non_selected = 1;
19701 }
19702
19703 /* Never display a cursor in a window in which cursor-type is nil. */
19704 if (NILP (b->cursor_type))
19705 return NO_CURSOR;
19706
19707 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19708 if (non_selected)
19709 {
19710 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19711 return get_specified_cursor_type (alt_cursor, width);
19712 }
19713
19714 /* Get the normal cursor type for this window. */
19715 if (EQ (b->cursor_type, Qt))
19716 {
19717 cursor_type = FRAME_DESIRED_CURSOR (f);
19718 *width = FRAME_CURSOR_WIDTH (f);
19719 }
19720 else
19721 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19722
19723 /* Use normal cursor if not blinked off. */
19724 if (!w->cursor_off_p)
19725 {
19726 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19727 if (cursor_type == FILLED_BOX_CURSOR)
19728 cursor_type = HOLLOW_BOX_CURSOR;
19729 }
19730 return cursor_type;
19731 }
19732
19733 /* Cursor is blinked off, so determine how to "toggle" it. */
19734
19735 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19736 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19737 return get_specified_cursor_type (XCDR (alt_cursor), width);
19738
19739 /* Then see if frame has specified a specific blink off cursor type. */
19740 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19741 {
19742 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19743 return FRAME_BLINK_OFF_CURSOR (f);
19744 }
19745
19746 #if 0
19747 /* Some people liked having a permanently visible blinking cursor,
19748 while others had very strong opinions against it. So it was
19749 decided to remove it. KFS 2003-09-03 */
19750
19751 /* Finally perform built-in cursor blinking:
19752 filled box <-> hollow box
19753 wide [h]bar <-> narrow [h]bar
19754 narrow [h]bar <-> no cursor
19755 other type <-> no cursor */
19756
19757 if (cursor_type == FILLED_BOX_CURSOR)
19758 return HOLLOW_BOX_CURSOR;
19759
19760 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19761 {
19762 *width = 1;
19763 return cursor_type;
19764 }
19765 #endif
19766
19767 return NO_CURSOR;
19768 }
19769
19770
19771 #ifdef HAVE_WINDOW_SYSTEM
19772
19773 /* Notice when the text cursor of window W has been completely
19774 overwritten by a drawing operation that outputs glyphs in AREA
19775 starting at X0 and ending at X1 in the line starting at Y0 and
19776 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19777 the rest of the line after X0 has been written. Y coordinates
19778 are window-relative. */
19779
19780 static void
19781 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19782 struct window *w;
19783 enum glyph_row_area area;
19784 int x0, y0, x1, y1;
19785 {
19786 int cx0, cx1, cy0, cy1;
19787 struct glyph_row *row;
19788
19789 if (!w->phys_cursor_on_p)
19790 return;
19791 if (area != TEXT_AREA)
19792 return;
19793
19794 row = w->current_matrix->rows + w->phys_cursor.vpos;
19795 if (!row->displays_text_p)
19796 return;
19797
19798 if (row->cursor_in_fringe_p)
19799 {
19800 row->cursor_in_fringe_p = 0;
19801 draw_fringe_bitmap (w, row, 0);
19802 w->phys_cursor_on_p = 0;
19803 return;
19804 }
19805
19806 cx0 = w->phys_cursor.x;
19807 cx1 = cx0 + w->phys_cursor_width;
19808 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19809 return;
19810
19811 /* The cursor image will be completely removed from the
19812 screen if the output area intersects the cursor area in
19813 y-direction. When we draw in [y0 y1[, and some part of
19814 the cursor is at y < y0, that part must have been drawn
19815 before. When scrolling, the cursor is erased before
19816 actually scrolling, so we don't come here. When not
19817 scrolling, the rows above the old cursor row must have
19818 changed, and in this case these rows must have written
19819 over the cursor image.
19820
19821 Likewise if part of the cursor is below y1, with the
19822 exception of the cursor being in the first blank row at
19823 the buffer and window end because update_text_area
19824 doesn't draw that row. (Except when it does, but
19825 that's handled in update_text_area.) */
19826
19827 cy0 = w->phys_cursor.y;
19828 cy1 = cy0 + w->phys_cursor_height;
19829 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19830 return;
19831
19832 w->phys_cursor_on_p = 0;
19833 }
19834
19835 #endif /* HAVE_WINDOW_SYSTEM */
19836
19837 \f
19838 /************************************************************************
19839 Mouse Face
19840 ************************************************************************/
19841
19842 #ifdef HAVE_WINDOW_SYSTEM
19843
19844 /* EXPORT for RIF:
19845 Fix the display of area AREA of overlapping row ROW in window W. */
19846
19847 void
19848 x_fix_overlapping_area (w, row, area)
19849 struct window *w;
19850 struct glyph_row *row;
19851 enum glyph_row_area area;
19852 {
19853 int i, x;
19854
19855 BLOCK_INPUT;
19856
19857 x = 0;
19858 for (i = 0; i < row->used[area];)
19859 {
19860 if (row->glyphs[area][i].overlaps_vertically_p)
19861 {
19862 int start = i, start_x = x;
19863
19864 do
19865 {
19866 x += row->glyphs[area][i].pixel_width;
19867 ++i;
19868 }
19869 while (i < row->used[area]
19870 && row->glyphs[area][i].overlaps_vertically_p);
19871
19872 draw_glyphs (w, start_x, row, area,
19873 start, i,
19874 DRAW_NORMAL_TEXT, 1);
19875 }
19876 else
19877 {
19878 x += row->glyphs[area][i].pixel_width;
19879 ++i;
19880 }
19881 }
19882
19883 UNBLOCK_INPUT;
19884 }
19885
19886
19887 /* EXPORT:
19888 Draw the cursor glyph of window W in glyph row ROW. See the
19889 comment of draw_glyphs for the meaning of HL. */
19890
19891 void
19892 draw_phys_cursor_glyph (w, row, hl)
19893 struct window *w;
19894 struct glyph_row *row;
19895 enum draw_glyphs_face hl;
19896 {
19897 /* If cursor hpos is out of bounds, don't draw garbage. This can
19898 happen in mini-buffer windows when switching between echo area
19899 glyphs and mini-buffer. */
19900 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19901 {
19902 int on_p = w->phys_cursor_on_p;
19903 int x1;
19904 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19905 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19906 hl, 0);
19907 w->phys_cursor_on_p = on_p;
19908
19909 if (hl == DRAW_CURSOR)
19910 w->phys_cursor_width = x1 - w->phys_cursor.x;
19911 /* When we erase the cursor, and ROW is overlapped by other
19912 rows, make sure that these overlapping parts of other rows
19913 are redrawn. */
19914 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19915 {
19916 if (row > w->current_matrix->rows
19917 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19918 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19919
19920 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19921 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19922 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19923 }
19924 }
19925 }
19926
19927
19928 /* EXPORT:
19929 Erase the image of a cursor of window W from the screen. */
19930
19931 void
19932 erase_phys_cursor (w)
19933 struct window *w;
19934 {
19935 struct frame *f = XFRAME (w->frame);
19936 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19937 int hpos = w->phys_cursor.hpos;
19938 int vpos = w->phys_cursor.vpos;
19939 int mouse_face_here_p = 0;
19940 struct glyph_matrix *active_glyphs = w->current_matrix;
19941 struct glyph_row *cursor_row;
19942 struct glyph *cursor_glyph;
19943 enum draw_glyphs_face hl;
19944
19945 /* No cursor displayed or row invalidated => nothing to do on the
19946 screen. */
19947 if (w->phys_cursor_type == NO_CURSOR)
19948 goto mark_cursor_off;
19949
19950 /* VPOS >= active_glyphs->nrows means that window has been resized.
19951 Don't bother to erase the cursor. */
19952 if (vpos >= active_glyphs->nrows)
19953 goto mark_cursor_off;
19954
19955 /* If row containing cursor is marked invalid, there is nothing we
19956 can do. */
19957 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19958 if (!cursor_row->enabled_p)
19959 goto mark_cursor_off;
19960
19961 /* If row is completely invisible, don't attempt to delete a cursor which
19962 isn't there. This can happen if cursor is at top of a window, and
19963 we switch to a buffer with a header line in that window. */
19964 if (cursor_row->visible_height <= 0)
19965 goto mark_cursor_off;
19966
19967 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19968 if (cursor_row->cursor_in_fringe_p)
19969 {
19970 cursor_row->cursor_in_fringe_p = 0;
19971 draw_fringe_bitmap (w, cursor_row, 0);
19972 goto mark_cursor_off;
19973 }
19974
19975 /* This can happen when the new row is shorter than the old one.
19976 In this case, either draw_glyphs or clear_end_of_line
19977 should have cleared the cursor. Note that we wouldn't be
19978 able to erase the cursor in this case because we don't have a
19979 cursor glyph at hand. */
19980 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19981 goto mark_cursor_off;
19982
19983 /* If the cursor is in the mouse face area, redisplay that when
19984 we clear the cursor. */
19985 if (! NILP (dpyinfo->mouse_face_window)
19986 && w == XWINDOW (dpyinfo->mouse_face_window)
19987 && (vpos > dpyinfo->mouse_face_beg_row
19988 || (vpos == dpyinfo->mouse_face_beg_row
19989 && hpos >= dpyinfo->mouse_face_beg_col))
19990 && (vpos < dpyinfo->mouse_face_end_row
19991 || (vpos == dpyinfo->mouse_face_end_row
19992 && hpos < dpyinfo->mouse_face_end_col))
19993 /* Don't redraw the cursor's spot in mouse face if it is at the
19994 end of a line (on a newline). The cursor appears there, but
19995 mouse highlighting does not. */
19996 && cursor_row->used[TEXT_AREA] > hpos)
19997 mouse_face_here_p = 1;
19998
19999 /* Maybe clear the display under the cursor. */
20000 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20001 {
20002 int x, y;
20003 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20004
20005 cursor_glyph = get_phys_cursor_glyph (w);
20006 if (cursor_glyph == NULL)
20007 goto mark_cursor_off;
20008
20009 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20010 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20011
20012 rif->clear_frame_area (f, x, y,
20013 cursor_glyph->pixel_width, cursor_row->visible_height);
20014 }
20015
20016 /* Erase the cursor by redrawing the character underneath it. */
20017 if (mouse_face_here_p)
20018 hl = DRAW_MOUSE_FACE;
20019 else
20020 hl = DRAW_NORMAL_TEXT;
20021 draw_phys_cursor_glyph (w, cursor_row, hl);
20022
20023 mark_cursor_off:
20024 w->phys_cursor_on_p = 0;
20025 w->phys_cursor_type = NO_CURSOR;
20026 }
20027
20028
20029 /* EXPORT:
20030 Display or clear cursor of window W. If ON is zero, clear the
20031 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20032 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20033
20034 void
20035 display_and_set_cursor (w, on, hpos, vpos, x, y)
20036 struct window *w;
20037 int on, hpos, vpos, x, y;
20038 {
20039 struct frame *f = XFRAME (w->frame);
20040 int new_cursor_type;
20041 int new_cursor_width;
20042 int active_cursor;
20043 struct glyph_row *glyph_row;
20044 struct glyph *glyph;
20045
20046 /* This is pointless on invisible frames, and dangerous on garbaged
20047 windows and frames; in the latter case, the frame or window may
20048 be in the midst of changing its size, and x and y may be off the
20049 window. */
20050 if (! FRAME_VISIBLE_P (f)
20051 || FRAME_GARBAGED_P (f)
20052 || vpos >= w->current_matrix->nrows
20053 || hpos >= w->current_matrix->matrix_w)
20054 return;
20055
20056 /* If cursor is off and we want it off, return quickly. */
20057 if (!on && !w->phys_cursor_on_p)
20058 return;
20059
20060 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20061 /* If cursor row is not enabled, we don't really know where to
20062 display the cursor. */
20063 if (!glyph_row->enabled_p)
20064 {
20065 w->phys_cursor_on_p = 0;
20066 return;
20067 }
20068
20069 glyph = NULL;
20070 if (!glyph_row->exact_window_width_line_p
20071 || hpos < glyph_row->used[TEXT_AREA])
20072 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20073
20074 xassert (interrupt_input_blocked);
20075
20076 /* Set new_cursor_type to the cursor we want to be displayed. */
20077 new_cursor_type = get_window_cursor_type (w, glyph,
20078 &new_cursor_width, &active_cursor);
20079
20080 /* If cursor is currently being shown and we don't want it to be or
20081 it is in the wrong place, or the cursor type is not what we want,
20082 erase it. */
20083 if (w->phys_cursor_on_p
20084 && (!on
20085 || w->phys_cursor.x != x
20086 || w->phys_cursor.y != y
20087 || new_cursor_type != w->phys_cursor_type
20088 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20089 && new_cursor_width != w->phys_cursor_width)))
20090 erase_phys_cursor (w);
20091
20092 /* Don't check phys_cursor_on_p here because that flag is only set
20093 to zero in some cases where we know that the cursor has been
20094 completely erased, to avoid the extra work of erasing the cursor
20095 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20096 still not be visible, or it has only been partly erased. */
20097 if (on)
20098 {
20099 w->phys_cursor_ascent = glyph_row->ascent;
20100 w->phys_cursor_height = glyph_row->height;
20101
20102 /* Set phys_cursor_.* before x_draw_.* is called because some
20103 of them may need the information. */
20104 w->phys_cursor.x = x;
20105 w->phys_cursor.y = glyph_row->y;
20106 w->phys_cursor.hpos = hpos;
20107 w->phys_cursor.vpos = vpos;
20108 }
20109
20110 rif->draw_window_cursor (w, glyph_row, x, y,
20111 new_cursor_type, new_cursor_width,
20112 on, active_cursor);
20113 }
20114
20115
20116 /* Switch the display of W's cursor on or off, according to the value
20117 of ON. */
20118
20119 static void
20120 update_window_cursor (w, on)
20121 struct window *w;
20122 int on;
20123 {
20124 /* Don't update cursor in windows whose frame is in the process
20125 of being deleted. */
20126 if (w->current_matrix)
20127 {
20128 BLOCK_INPUT;
20129 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20130 w->phys_cursor.x, w->phys_cursor.y);
20131 UNBLOCK_INPUT;
20132 }
20133 }
20134
20135
20136 /* Call update_window_cursor with parameter ON_P on all leaf windows
20137 in the window tree rooted at W. */
20138
20139 static void
20140 update_cursor_in_window_tree (w, on_p)
20141 struct window *w;
20142 int on_p;
20143 {
20144 while (w)
20145 {
20146 if (!NILP (w->hchild))
20147 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20148 else if (!NILP (w->vchild))
20149 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20150 else
20151 update_window_cursor (w, on_p);
20152
20153 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20154 }
20155 }
20156
20157
20158 /* EXPORT:
20159 Display the cursor on window W, or clear it, according to ON_P.
20160 Don't change the cursor's position. */
20161
20162 void
20163 x_update_cursor (f, on_p)
20164 struct frame *f;
20165 int on_p;
20166 {
20167 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20168 }
20169
20170
20171 /* EXPORT:
20172 Clear the cursor of window W to background color, and mark the
20173 cursor as not shown. This is used when the text where the cursor
20174 is is about to be rewritten. */
20175
20176 void
20177 x_clear_cursor (w)
20178 struct window *w;
20179 {
20180 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20181 update_window_cursor (w, 0);
20182 }
20183
20184
20185 /* EXPORT:
20186 Display the active region described by mouse_face_* according to DRAW. */
20187
20188 void
20189 show_mouse_face (dpyinfo, draw)
20190 Display_Info *dpyinfo;
20191 enum draw_glyphs_face draw;
20192 {
20193 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20194 struct frame *f = XFRAME (WINDOW_FRAME (w));
20195
20196 if (/* If window is in the process of being destroyed, don't bother
20197 to do anything. */
20198 w->current_matrix != NULL
20199 /* Don't update mouse highlight if hidden */
20200 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20201 /* Recognize when we are called to operate on rows that don't exist
20202 anymore. This can happen when a window is split. */
20203 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20204 {
20205 int phys_cursor_on_p = w->phys_cursor_on_p;
20206 struct glyph_row *row, *first, *last;
20207
20208 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20209 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20210
20211 for (row = first; row <= last && row->enabled_p; ++row)
20212 {
20213 int start_hpos, end_hpos, start_x;
20214
20215 /* For all but the first row, the highlight starts at column 0. */
20216 if (row == first)
20217 {
20218 start_hpos = dpyinfo->mouse_face_beg_col;
20219 start_x = dpyinfo->mouse_face_beg_x;
20220 }
20221 else
20222 {
20223 start_hpos = 0;
20224 start_x = 0;
20225 }
20226
20227 if (row == last)
20228 end_hpos = dpyinfo->mouse_face_end_col;
20229 else
20230 end_hpos = row->used[TEXT_AREA];
20231
20232 if (end_hpos > start_hpos)
20233 {
20234 draw_glyphs (w, start_x, row, TEXT_AREA,
20235 start_hpos, end_hpos,
20236 draw, 0);
20237
20238 row->mouse_face_p
20239 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20240 }
20241 }
20242
20243 /* When we've written over the cursor, arrange for it to
20244 be displayed again. */
20245 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20246 {
20247 BLOCK_INPUT;
20248 display_and_set_cursor (w, 1,
20249 w->phys_cursor.hpos, w->phys_cursor.vpos,
20250 w->phys_cursor.x, w->phys_cursor.y);
20251 UNBLOCK_INPUT;
20252 }
20253 }
20254
20255 /* Change the mouse cursor. */
20256 if (draw == DRAW_NORMAL_TEXT)
20257 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20258 else if (draw == DRAW_MOUSE_FACE)
20259 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20260 else
20261 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20262 }
20263
20264 /* EXPORT:
20265 Clear out the mouse-highlighted active region.
20266 Redraw it un-highlighted first. Value is non-zero if mouse
20267 face was actually drawn unhighlighted. */
20268
20269 int
20270 clear_mouse_face (dpyinfo)
20271 Display_Info *dpyinfo;
20272 {
20273 int cleared = 0;
20274
20275 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20276 {
20277 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20278 cleared = 1;
20279 }
20280
20281 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20282 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20283 dpyinfo->mouse_face_window = Qnil;
20284 dpyinfo->mouse_face_overlay = Qnil;
20285 return cleared;
20286 }
20287
20288
20289 /* EXPORT:
20290 Non-zero if physical cursor of window W is within mouse face. */
20291
20292 int
20293 cursor_in_mouse_face_p (w)
20294 struct window *w;
20295 {
20296 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20297 int in_mouse_face = 0;
20298
20299 if (WINDOWP (dpyinfo->mouse_face_window)
20300 && XWINDOW (dpyinfo->mouse_face_window) == w)
20301 {
20302 int hpos = w->phys_cursor.hpos;
20303 int vpos = w->phys_cursor.vpos;
20304
20305 if (vpos >= dpyinfo->mouse_face_beg_row
20306 && vpos <= dpyinfo->mouse_face_end_row
20307 && (vpos > dpyinfo->mouse_face_beg_row
20308 || hpos >= dpyinfo->mouse_face_beg_col)
20309 && (vpos < dpyinfo->mouse_face_end_row
20310 || hpos < dpyinfo->mouse_face_end_col
20311 || dpyinfo->mouse_face_past_end))
20312 in_mouse_face = 1;
20313 }
20314
20315 return in_mouse_face;
20316 }
20317
20318
20319
20320 \f
20321 /* Find the glyph matrix position of buffer position CHARPOS in window
20322 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20323 current glyphs must be up to date. If CHARPOS is above window
20324 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20325 of last line in W. In the row containing CHARPOS, stop before glyphs
20326 having STOP as object. */
20327
20328 #if 1 /* This is a version of fast_find_position that's more correct
20329 in the presence of hscrolling, for example. I didn't install
20330 it right away because the problem fixed is minor, it failed
20331 in 20.x as well, and I think it's too risky to install
20332 so near the release of 21.1. 2001-09-25 gerd. */
20333
20334 static int
20335 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20336 struct window *w;
20337 int charpos;
20338 int *hpos, *vpos, *x, *y;
20339 Lisp_Object stop;
20340 {
20341 struct glyph_row *row, *first;
20342 struct glyph *glyph, *end;
20343 int past_end = 0;
20344
20345 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20346 row = row_containing_pos (w, charpos, first, NULL, 0);
20347 if (row == NULL)
20348 {
20349 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20350 {
20351 *x = *y = *hpos = *vpos = 0;
20352 return 1;
20353 }
20354 else
20355 {
20356 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20357 past_end = 1;
20358 }
20359 }
20360
20361 *x = row->x;
20362 *y = row->y;
20363 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20364
20365 glyph = row->glyphs[TEXT_AREA];
20366 end = glyph + row->used[TEXT_AREA];
20367
20368 /* Skip over glyphs not having an object at the start of the row.
20369 These are special glyphs like truncation marks on terminal
20370 frames. */
20371 if (row->displays_text_p)
20372 while (glyph < end
20373 && INTEGERP (glyph->object)
20374 && !EQ (stop, glyph->object)
20375 && glyph->charpos < 0)
20376 {
20377 *x += glyph->pixel_width;
20378 ++glyph;
20379 }
20380
20381 while (glyph < end
20382 && !INTEGERP (glyph->object)
20383 && !EQ (stop, glyph->object)
20384 && (!BUFFERP (glyph->object)
20385 || glyph->charpos < charpos))
20386 {
20387 *x += glyph->pixel_width;
20388 ++glyph;
20389 }
20390
20391 *hpos = glyph - row->glyphs[TEXT_AREA];
20392 return !past_end;
20393 }
20394
20395 #else /* not 1 */
20396
20397 static int
20398 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20399 struct window *w;
20400 int pos;
20401 int *hpos, *vpos, *x, *y;
20402 Lisp_Object stop;
20403 {
20404 int i;
20405 int lastcol;
20406 int maybe_next_line_p = 0;
20407 int line_start_position;
20408 int yb = window_text_bottom_y (w);
20409 struct glyph_row *row, *best_row;
20410 int row_vpos, best_row_vpos;
20411 int current_x;
20412
20413 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20414 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20415
20416 while (row->y < yb)
20417 {
20418 if (row->used[TEXT_AREA])
20419 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20420 else
20421 line_start_position = 0;
20422
20423 if (line_start_position > pos)
20424 break;
20425 /* If the position sought is the end of the buffer,
20426 don't include the blank lines at the bottom of the window. */
20427 else if (line_start_position == pos
20428 && pos == BUF_ZV (XBUFFER (w->buffer)))
20429 {
20430 maybe_next_line_p = 1;
20431 break;
20432 }
20433 else if (line_start_position > 0)
20434 {
20435 best_row = row;
20436 best_row_vpos = row_vpos;
20437 }
20438
20439 if (row->y + row->height >= yb)
20440 break;
20441
20442 ++row;
20443 ++row_vpos;
20444 }
20445
20446 /* Find the right column within BEST_ROW. */
20447 lastcol = 0;
20448 current_x = best_row->x;
20449 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20450 {
20451 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20452 int charpos = glyph->charpos;
20453
20454 if (BUFFERP (glyph->object))
20455 {
20456 if (charpos == pos)
20457 {
20458 *hpos = i;
20459 *vpos = best_row_vpos;
20460 *x = current_x;
20461 *y = best_row->y;
20462 return 1;
20463 }
20464 else if (charpos > pos)
20465 break;
20466 }
20467 else if (EQ (glyph->object, stop))
20468 break;
20469
20470 if (charpos > 0)
20471 lastcol = i;
20472 current_x += glyph->pixel_width;
20473 }
20474
20475 /* If we're looking for the end of the buffer,
20476 and we didn't find it in the line we scanned,
20477 use the start of the following line. */
20478 if (maybe_next_line_p)
20479 {
20480 ++best_row;
20481 ++best_row_vpos;
20482 lastcol = 0;
20483 current_x = best_row->x;
20484 }
20485
20486 *vpos = best_row_vpos;
20487 *hpos = lastcol + 1;
20488 *x = current_x;
20489 *y = best_row->y;
20490 return 0;
20491 }
20492
20493 #endif /* not 1 */
20494
20495
20496 /* Find the position of the glyph for position POS in OBJECT in
20497 window W's current matrix, and return in *X, *Y the pixel
20498 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20499
20500 RIGHT_P non-zero means return the position of the right edge of the
20501 glyph, RIGHT_P zero means return the left edge position.
20502
20503 If no glyph for POS exists in the matrix, return the position of
20504 the glyph with the next smaller position that is in the matrix, if
20505 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20506 exists in the matrix, return the position of the glyph with the
20507 next larger position in OBJECT.
20508
20509 Value is non-zero if a glyph was found. */
20510
20511 static int
20512 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20513 struct window *w;
20514 int pos;
20515 Lisp_Object object;
20516 int *hpos, *vpos, *x, *y;
20517 int right_p;
20518 {
20519 int yb = window_text_bottom_y (w);
20520 struct glyph_row *r;
20521 struct glyph *best_glyph = NULL;
20522 struct glyph_row *best_row = NULL;
20523 int best_x = 0;
20524
20525 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20526 r->enabled_p && r->y < yb;
20527 ++r)
20528 {
20529 struct glyph *g = r->glyphs[TEXT_AREA];
20530 struct glyph *e = g + r->used[TEXT_AREA];
20531 int gx;
20532
20533 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20534 if (EQ (g->object, object))
20535 {
20536 if (g->charpos == pos)
20537 {
20538 best_glyph = g;
20539 best_x = gx;
20540 best_row = r;
20541 goto found;
20542 }
20543 else if (best_glyph == NULL
20544 || ((abs (g->charpos - pos)
20545 < abs (best_glyph->charpos - pos))
20546 && (right_p
20547 ? g->charpos < pos
20548 : g->charpos > pos)))
20549 {
20550 best_glyph = g;
20551 best_x = gx;
20552 best_row = r;
20553 }
20554 }
20555 }
20556
20557 found:
20558
20559 if (best_glyph)
20560 {
20561 *x = best_x;
20562 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20563
20564 if (right_p)
20565 {
20566 *x += best_glyph->pixel_width;
20567 ++*hpos;
20568 }
20569
20570 *y = best_row->y;
20571 *vpos = best_row - w->current_matrix->rows;
20572 }
20573
20574 return best_glyph != NULL;
20575 }
20576
20577
20578 /* See if position X, Y is within a hot-spot of an image. */
20579
20580 static int
20581 on_hot_spot_p (hot_spot, x, y)
20582 Lisp_Object hot_spot;
20583 int x, y;
20584 {
20585 if (!CONSP (hot_spot))
20586 return 0;
20587
20588 if (EQ (XCAR (hot_spot), Qrect))
20589 {
20590 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20591 Lisp_Object rect = XCDR (hot_spot);
20592 Lisp_Object tem;
20593 if (!CONSP (rect))
20594 return 0;
20595 if (!CONSP (XCAR (rect)))
20596 return 0;
20597 if (!CONSP (XCDR (rect)))
20598 return 0;
20599 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20600 return 0;
20601 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20602 return 0;
20603 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20604 return 0;
20605 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20606 return 0;
20607 return 1;
20608 }
20609 else if (EQ (XCAR (hot_spot), Qcircle))
20610 {
20611 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20612 Lisp_Object circ = XCDR (hot_spot);
20613 Lisp_Object lr, lx0, ly0;
20614 if (CONSP (circ)
20615 && CONSP (XCAR (circ))
20616 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20617 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20618 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20619 {
20620 double r = XFLOATINT (lr);
20621 double dx = XINT (lx0) - x;
20622 double dy = XINT (ly0) - y;
20623 return (dx * dx + dy * dy <= r * r);
20624 }
20625 }
20626 else if (EQ (XCAR (hot_spot), Qpoly))
20627 {
20628 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20629 if (VECTORP (XCDR (hot_spot)))
20630 {
20631 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20632 Lisp_Object *poly = v->contents;
20633 int n = v->size;
20634 int i;
20635 int inside = 0;
20636 Lisp_Object lx, ly;
20637 int x0, y0;
20638
20639 /* Need an even number of coordinates, and at least 3 edges. */
20640 if (n < 6 || n & 1)
20641 return 0;
20642
20643 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20644 If count is odd, we are inside polygon. Pixels on edges
20645 may or may not be included depending on actual geometry of the
20646 polygon. */
20647 if ((lx = poly[n-2], !INTEGERP (lx))
20648 || (ly = poly[n-1], !INTEGERP (lx)))
20649 return 0;
20650 x0 = XINT (lx), y0 = XINT (ly);
20651 for (i = 0; i < n; i += 2)
20652 {
20653 int x1 = x0, y1 = y0;
20654 if ((lx = poly[i], !INTEGERP (lx))
20655 || (ly = poly[i+1], !INTEGERP (ly)))
20656 return 0;
20657 x0 = XINT (lx), y0 = XINT (ly);
20658
20659 /* Does this segment cross the X line? */
20660 if (x0 >= x)
20661 {
20662 if (x1 >= x)
20663 continue;
20664 }
20665 else if (x1 < x)
20666 continue;
20667 if (y > y0 && y > y1)
20668 continue;
20669 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20670 inside = !inside;
20671 }
20672 return inside;
20673 }
20674 }
20675 /* If we don't understand the format, pretend we're not in the hot-spot. */
20676 return 0;
20677 }
20678
20679 Lisp_Object
20680 find_hot_spot (map, x, y)
20681 Lisp_Object map;
20682 int x, y;
20683 {
20684 while (CONSP (map))
20685 {
20686 if (CONSP (XCAR (map))
20687 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20688 return XCAR (map);
20689 map = XCDR (map);
20690 }
20691
20692 return Qnil;
20693 }
20694
20695 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20696 3, 3, 0,
20697 doc: /* Lookup in image map MAP coordinates X and Y.
20698 An image map is an alist where each element has the format (AREA ID PLIST).
20699 An AREA is specified as either a rectangle, a circle, or a polygon:
20700 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20701 pixel coordinates of the upper left and bottom right corners.
20702 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20703 and the radius of the circle; r may be a float or integer.
20704 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20705 vector describes one corner in the polygon.
20706 Returns the alist element for the first matching AREA in MAP. */)
20707 (map, x, y)
20708 Lisp_Object map;
20709 Lisp_Object x, y;
20710 {
20711 if (NILP (map))
20712 return Qnil;
20713
20714 CHECK_NUMBER (x);
20715 CHECK_NUMBER (y);
20716
20717 return find_hot_spot (map, XINT (x), XINT (y));
20718 }
20719
20720
20721 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20722 static void
20723 define_frame_cursor1 (f, cursor, pointer)
20724 struct frame *f;
20725 Cursor cursor;
20726 Lisp_Object pointer;
20727 {
20728 if (!NILP (pointer))
20729 {
20730 if (EQ (pointer, Qarrow))
20731 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20732 else if (EQ (pointer, Qhand))
20733 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20734 else if (EQ (pointer, Qtext))
20735 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20736 else if (EQ (pointer, intern ("hdrag")))
20737 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20738 #ifdef HAVE_X_WINDOWS
20739 else if (EQ (pointer, intern ("vdrag")))
20740 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20741 #endif
20742 else if (EQ (pointer, intern ("hourglass")))
20743 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20744 else if (EQ (pointer, Qmodeline))
20745 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20746 else
20747 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20748 }
20749
20750 if (cursor != No_Cursor)
20751 rif->define_frame_cursor (f, cursor);
20752 }
20753
20754 /* Take proper action when mouse has moved to the mode or header line
20755 or marginal area AREA of window W, x-position X and y-position Y.
20756 X is relative to the start of the text display area of W, so the
20757 width of bitmap areas and scroll bars must be subtracted to get a
20758 position relative to the start of the mode line. */
20759
20760 static void
20761 note_mode_line_or_margin_highlight (w, x, y, area)
20762 struct window *w;
20763 int x, y;
20764 enum window_part area;
20765 {
20766 struct frame *f = XFRAME (w->frame);
20767 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20768 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20769 Lisp_Object pointer = Qnil;
20770 int charpos, dx, dy, width, height;
20771 Lisp_Object string, object = Qnil;
20772 Lisp_Object pos, help;
20773
20774 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20775 string = mode_line_string (w, area, &x, &y, &charpos,
20776 &object, &dx, &dy, &width, &height);
20777 else
20778 {
20779 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20780 string = marginal_area_string (w, area, &x, &y, &charpos,
20781 &object, &dx, &dy, &width, &height);
20782 }
20783
20784 help = Qnil;
20785
20786 if (IMAGEP (object))
20787 {
20788 Lisp_Object image_map, hotspot;
20789 if ((image_map = Fplist_get (XCDR (object), QCmap),
20790 !NILP (image_map))
20791 && (hotspot = find_hot_spot (image_map, dx, dy),
20792 CONSP (hotspot))
20793 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20794 {
20795 Lisp_Object area_id, plist;
20796
20797 area_id = XCAR (hotspot);
20798 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20799 If so, we could look for mouse-enter, mouse-leave
20800 properties in PLIST (and do something...). */
20801 if ((plist = XCDR (hotspot), CONSP (plist)))
20802 {
20803 pointer = Fplist_get (plist, Qpointer);
20804 if (NILP (pointer))
20805 pointer = Qhand;
20806 help = Fplist_get (plist, Qhelp_echo);
20807 if (!NILP (help))
20808 {
20809 help_echo_string = help;
20810 /* Is this correct? ++kfs */
20811 XSETWINDOW (help_echo_window, w);
20812 help_echo_object = w->buffer;
20813 help_echo_pos = charpos;
20814 }
20815 }
20816 if (NILP (pointer))
20817 pointer = Fplist_get (XCDR (object), QCpointer);
20818 }
20819 }
20820
20821 if (STRINGP (string))
20822 {
20823 pos = make_number (charpos);
20824 /* If we're on a string with `help-echo' text property, arrange
20825 for the help to be displayed. This is done by setting the
20826 global variable help_echo_string to the help string. */
20827 help = Fget_text_property (pos, Qhelp_echo, string);
20828 if (!NILP (help))
20829 {
20830 help_echo_string = help;
20831 XSETWINDOW (help_echo_window, w);
20832 help_echo_object = string;
20833 help_echo_pos = charpos;
20834 }
20835
20836 if (NILP (pointer))
20837 pointer = Fget_text_property (pos, Qpointer, string);
20838
20839 /* Change the mouse pointer according to what is under X/Y. */
20840 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20841 {
20842 Lisp_Object map;
20843 map = Fget_text_property (pos, Qlocal_map, string);
20844 if (!KEYMAPP (map))
20845 map = Fget_text_property (pos, Qkeymap, string);
20846 if (!KEYMAPP (map))
20847 cursor = dpyinfo->vertical_scroll_bar_cursor;
20848 }
20849 }
20850
20851 define_frame_cursor1 (f, cursor, pointer);
20852 }
20853
20854
20855 /* EXPORT:
20856 Take proper action when the mouse has moved to position X, Y on
20857 frame F as regards highlighting characters that have mouse-face
20858 properties. Also de-highlighting chars where the mouse was before.
20859 X and Y can be negative or out of range. */
20860
20861 void
20862 note_mouse_highlight (f, x, y)
20863 struct frame *f;
20864 int x, y;
20865 {
20866 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20867 enum window_part part;
20868 Lisp_Object window;
20869 struct window *w;
20870 Cursor cursor = No_Cursor;
20871 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20872 struct buffer *b;
20873
20874 /* When a menu is active, don't highlight because this looks odd. */
20875 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20876 if (popup_activated ())
20877 return;
20878 #endif
20879
20880 if (NILP (Vmouse_highlight)
20881 || !f->glyphs_initialized_p)
20882 return;
20883
20884 dpyinfo->mouse_face_mouse_x = x;
20885 dpyinfo->mouse_face_mouse_y = y;
20886 dpyinfo->mouse_face_mouse_frame = f;
20887
20888 if (dpyinfo->mouse_face_defer)
20889 return;
20890
20891 if (gc_in_progress)
20892 {
20893 dpyinfo->mouse_face_deferred_gc = 1;
20894 return;
20895 }
20896
20897 /* Which window is that in? */
20898 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20899
20900 /* If we were displaying active text in another window, clear that. */
20901 if (! EQ (window, dpyinfo->mouse_face_window))
20902 clear_mouse_face (dpyinfo);
20903
20904 /* Not on a window -> return. */
20905 if (!WINDOWP (window))
20906 return;
20907
20908 /* Reset help_echo_string. It will get recomputed below. */
20909 help_echo_string = Qnil;
20910
20911 /* Convert to window-relative pixel coordinates. */
20912 w = XWINDOW (window);
20913 frame_to_window_pixel_xy (w, &x, &y);
20914
20915 /* Handle tool-bar window differently since it doesn't display a
20916 buffer. */
20917 if (EQ (window, f->tool_bar_window))
20918 {
20919 note_tool_bar_highlight (f, x, y);
20920 return;
20921 }
20922
20923 /* Mouse is on the mode, header line or margin? */
20924 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20925 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20926 {
20927 note_mode_line_or_margin_highlight (w, x, y, part);
20928 return;
20929 }
20930
20931 if (part == ON_VERTICAL_BORDER)
20932 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20933 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
20934 || part == ON_SCROLL_BAR)
20935 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20936 else
20937 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20938
20939 /* Are we in a window whose display is up to date?
20940 And verify the buffer's text has not changed. */
20941 b = XBUFFER (w->buffer);
20942 if (part == ON_TEXT
20943 && EQ (w->window_end_valid, w->buffer)
20944 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20945 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20946 {
20947 int hpos, vpos, pos, i, dx, dy, area;
20948 struct glyph *glyph;
20949 Lisp_Object object;
20950 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20951 Lisp_Object *overlay_vec = NULL;
20952 int noverlays;
20953 struct buffer *obuf;
20954 int obegv, ozv, same_region;
20955
20956 /* Find the glyph under X/Y. */
20957 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20958
20959 /* Look for :pointer property on image. */
20960 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20961 {
20962 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20963 if (img != NULL && IMAGEP (img->spec))
20964 {
20965 Lisp_Object image_map, hotspot;
20966 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20967 !NILP (image_map))
20968 && (hotspot = find_hot_spot (image_map,
20969 glyph->slice.x + dx,
20970 glyph->slice.y + dy),
20971 CONSP (hotspot))
20972 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20973 {
20974 Lisp_Object area_id, plist;
20975
20976 area_id = XCAR (hotspot);
20977 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20978 If so, we could look for mouse-enter, mouse-leave
20979 properties in PLIST (and do something...). */
20980 if ((plist = XCDR (hotspot), CONSP (plist)))
20981 {
20982 pointer = Fplist_get (plist, Qpointer);
20983 if (NILP (pointer))
20984 pointer = Qhand;
20985 help_echo_string = Fplist_get (plist, Qhelp_echo);
20986 if (!NILP (help_echo_string))
20987 {
20988 help_echo_window = window;
20989 help_echo_object = glyph->object;
20990 help_echo_pos = glyph->charpos;
20991 }
20992 }
20993 }
20994 if (NILP (pointer))
20995 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20996 }
20997 }
20998
20999 /* Clear mouse face if X/Y not over text. */
21000 if (glyph == NULL
21001 || area != TEXT_AREA
21002 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21003 {
21004 if (clear_mouse_face (dpyinfo))
21005 cursor = No_Cursor;
21006 if (NILP (pointer))
21007 {
21008 if (area != TEXT_AREA)
21009 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21010 else
21011 pointer = Vvoid_text_area_pointer;
21012 }
21013 goto set_cursor;
21014 }
21015
21016 pos = glyph->charpos;
21017 object = glyph->object;
21018 if (!STRINGP (object) && !BUFFERP (object))
21019 goto set_cursor;
21020
21021 /* If we get an out-of-range value, return now; avoid an error. */
21022 if (BUFFERP (object) && pos > BUF_Z (b))
21023 goto set_cursor;
21024
21025 /* Make the window's buffer temporarily current for
21026 overlays_at and compute_char_face. */
21027 obuf = current_buffer;
21028 current_buffer = b;
21029 obegv = BEGV;
21030 ozv = ZV;
21031 BEGV = BEG;
21032 ZV = Z;
21033
21034 /* Is this char mouse-active or does it have help-echo? */
21035 position = make_number (pos);
21036
21037 if (BUFFERP (object))
21038 {
21039 /* Put all the overlays we want in a vector in overlay_vec. */
21040 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21041 /* Sort overlays into increasing priority order. */
21042 noverlays = sort_overlays (overlay_vec, noverlays, w);
21043 }
21044 else
21045 noverlays = 0;
21046
21047 same_region = (EQ (window, dpyinfo->mouse_face_window)
21048 && vpos >= dpyinfo->mouse_face_beg_row
21049 && vpos <= dpyinfo->mouse_face_end_row
21050 && (vpos > dpyinfo->mouse_face_beg_row
21051 || hpos >= dpyinfo->mouse_face_beg_col)
21052 && (vpos < dpyinfo->mouse_face_end_row
21053 || hpos < dpyinfo->mouse_face_end_col
21054 || dpyinfo->mouse_face_past_end));
21055
21056 if (same_region)
21057 cursor = No_Cursor;
21058
21059 /* Check mouse-face highlighting. */
21060 if (! same_region
21061 /* If there exists an overlay with mouse-face overlapping
21062 the one we are currently highlighting, we have to
21063 check if we enter the overlapping overlay, and then
21064 highlight only that. */
21065 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21066 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21067 {
21068 /* Find the highest priority overlay that has a mouse-face
21069 property. */
21070 overlay = Qnil;
21071 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21072 {
21073 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21074 if (!NILP (mouse_face))
21075 overlay = overlay_vec[i];
21076 }
21077
21078 /* If we're actually highlighting the same overlay as
21079 before, there's no need to do that again. */
21080 if (!NILP (overlay)
21081 && EQ (overlay, dpyinfo->mouse_face_overlay))
21082 goto check_help_echo;
21083
21084 dpyinfo->mouse_face_overlay = overlay;
21085
21086 /* Clear the display of the old active region, if any. */
21087 if (clear_mouse_face (dpyinfo))
21088 cursor = No_Cursor;
21089
21090 /* If no overlay applies, get a text property. */
21091 if (NILP (overlay))
21092 mouse_face = Fget_text_property (position, Qmouse_face, object);
21093
21094 /* Handle the overlay case. */
21095 if (!NILP (overlay))
21096 {
21097 /* Find the range of text around this char that
21098 should be active. */
21099 Lisp_Object before, after;
21100 int ignore;
21101
21102 before = Foverlay_start (overlay);
21103 after = Foverlay_end (overlay);
21104 /* Record this as the current active region. */
21105 fast_find_position (w, XFASTINT (before),
21106 &dpyinfo->mouse_face_beg_col,
21107 &dpyinfo->mouse_face_beg_row,
21108 &dpyinfo->mouse_face_beg_x,
21109 &dpyinfo->mouse_face_beg_y, Qnil);
21110
21111 dpyinfo->mouse_face_past_end
21112 = !fast_find_position (w, XFASTINT (after),
21113 &dpyinfo->mouse_face_end_col,
21114 &dpyinfo->mouse_face_end_row,
21115 &dpyinfo->mouse_face_end_x,
21116 &dpyinfo->mouse_face_end_y, Qnil);
21117 dpyinfo->mouse_face_window = window;
21118
21119 dpyinfo->mouse_face_face_id
21120 = face_at_buffer_position (w, pos, 0, 0,
21121 &ignore, pos + 1,
21122 !dpyinfo->mouse_face_hidden);
21123
21124 /* Display it as active. */
21125 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21126 cursor = No_Cursor;
21127 }
21128 /* Handle the text property case. */
21129 else if (!NILP (mouse_face) && BUFFERP (object))
21130 {
21131 /* Find the range of text around this char that
21132 should be active. */
21133 Lisp_Object before, after, beginning, end;
21134 int ignore;
21135
21136 beginning = Fmarker_position (w->start);
21137 end = make_number (BUF_Z (XBUFFER (object))
21138 - XFASTINT (w->window_end_pos));
21139 before
21140 = Fprevious_single_property_change (make_number (pos + 1),
21141 Qmouse_face,
21142 object, beginning);
21143 after
21144 = Fnext_single_property_change (position, Qmouse_face,
21145 object, end);
21146
21147 /* Record this as the current active region. */
21148 fast_find_position (w, XFASTINT (before),
21149 &dpyinfo->mouse_face_beg_col,
21150 &dpyinfo->mouse_face_beg_row,
21151 &dpyinfo->mouse_face_beg_x,
21152 &dpyinfo->mouse_face_beg_y, Qnil);
21153 dpyinfo->mouse_face_past_end
21154 = !fast_find_position (w, XFASTINT (after),
21155 &dpyinfo->mouse_face_end_col,
21156 &dpyinfo->mouse_face_end_row,
21157 &dpyinfo->mouse_face_end_x,
21158 &dpyinfo->mouse_face_end_y, Qnil);
21159 dpyinfo->mouse_face_window = window;
21160
21161 if (BUFFERP (object))
21162 dpyinfo->mouse_face_face_id
21163 = face_at_buffer_position (w, pos, 0, 0,
21164 &ignore, pos + 1,
21165 !dpyinfo->mouse_face_hidden);
21166
21167 /* Display it as active. */
21168 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21169 cursor = No_Cursor;
21170 }
21171 else if (!NILP (mouse_face) && STRINGP (object))
21172 {
21173 Lisp_Object b, e;
21174 int ignore;
21175
21176 b = Fprevious_single_property_change (make_number (pos + 1),
21177 Qmouse_face,
21178 object, Qnil);
21179 e = Fnext_single_property_change (position, Qmouse_face,
21180 object, Qnil);
21181 if (NILP (b))
21182 b = make_number (0);
21183 if (NILP (e))
21184 e = make_number (SCHARS (object) - 1);
21185 fast_find_string_pos (w, XINT (b), object,
21186 &dpyinfo->mouse_face_beg_col,
21187 &dpyinfo->mouse_face_beg_row,
21188 &dpyinfo->mouse_face_beg_x,
21189 &dpyinfo->mouse_face_beg_y, 0);
21190 fast_find_string_pos (w, XINT (e), object,
21191 &dpyinfo->mouse_face_end_col,
21192 &dpyinfo->mouse_face_end_row,
21193 &dpyinfo->mouse_face_end_x,
21194 &dpyinfo->mouse_face_end_y, 1);
21195 dpyinfo->mouse_face_past_end = 0;
21196 dpyinfo->mouse_face_window = window;
21197 dpyinfo->mouse_face_face_id
21198 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21199 glyph->face_id, 1);
21200 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21201 cursor = No_Cursor;
21202 }
21203 else if (STRINGP (object) && NILP (mouse_face))
21204 {
21205 /* A string which doesn't have mouse-face, but
21206 the text ``under'' it might have. */
21207 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21208 int start = MATRIX_ROW_START_CHARPOS (r);
21209
21210 pos = string_buffer_position (w, object, start);
21211 if (pos > 0)
21212 mouse_face = get_char_property_and_overlay (make_number (pos),
21213 Qmouse_face,
21214 w->buffer,
21215 &overlay);
21216 if (!NILP (mouse_face) && !NILP (overlay))
21217 {
21218 Lisp_Object before = Foverlay_start (overlay);
21219 Lisp_Object after = Foverlay_end (overlay);
21220 int ignore;
21221
21222 /* Note that we might not be able to find position
21223 BEFORE in the glyph matrix if the overlay is
21224 entirely covered by a `display' property. In
21225 this case, we overshoot. So let's stop in
21226 the glyph matrix before glyphs for OBJECT. */
21227 fast_find_position (w, XFASTINT (before),
21228 &dpyinfo->mouse_face_beg_col,
21229 &dpyinfo->mouse_face_beg_row,
21230 &dpyinfo->mouse_face_beg_x,
21231 &dpyinfo->mouse_face_beg_y,
21232 object);
21233
21234 dpyinfo->mouse_face_past_end
21235 = !fast_find_position (w, XFASTINT (after),
21236 &dpyinfo->mouse_face_end_col,
21237 &dpyinfo->mouse_face_end_row,
21238 &dpyinfo->mouse_face_end_x,
21239 &dpyinfo->mouse_face_end_y,
21240 Qnil);
21241 dpyinfo->mouse_face_window = window;
21242 dpyinfo->mouse_face_face_id
21243 = face_at_buffer_position (w, pos, 0, 0,
21244 &ignore, pos + 1,
21245 !dpyinfo->mouse_face_hidden);
21246
21247 /* Display it as active. */
21248 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21249 cursor = No_Cursor;
21250 }
21251 }
21252 }
21253
21254 check_help_echo:
21255
21256 /* Look for a `help-echo' property. */
21257 if (NILP (help_echo_string)) {
21258 Lisp_Object help, overlay;
21259
21260 /* Check overlays first. */
21261 help = overlay = Qnil;
21262 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21263 {
21264 overlay = overlay_vec[i];
21265 help = Foverlay_get (overlay, Qhelp_echo);
21266 }
21267
21268 if (!NILP (help))
21269 {
21270 help_echo_string = help;
21271 help_echo_window = window;
21272 help_echo_object = overlay;
21273 help_echo_pos = pos;
21274 }
21275 else
21276 {
21277 Lisp_Object object = glyph->object;
21278 int charpos = glyph->charpos;
21279
21280 /* Try text properties. */
21281 if (STRINGP (object)
21282 && charpos >= 0
21283 && charpos < SCHARS (object))
21284 {
21285 help = Fget_text_property (make_number (charpos),
21286 Qhelp_echo, object);
21287 if (NILP (help))
21288 {
21289 /* If the string itself doesn't specify a help-echo,
21290 see if the buffer text ``under'' it does. */
21291 struct glyph_row *r
21292 = MATRIX_ROW (w->current_matrix, vpos);
21293 int start = MATRIX_ROW_START_CHARPOS (r);
21294 int pos = string_buffer_position (w, object, start);
21295 if (pos > 0)
21296 {
21297 help = Fget_char_property (make_number (pos),
21298 Qhelp_echo, w->buffer);
21299 if (!NILP (help))
21300 {
21301 charpos = pos;
21302 object = w->buffer;
21303 }
21304 }
21305 }
21306 }
21307 else if (BUFFERP (object)
21308 && charpos >= BEGV
21309 && charpos < ZV)
21310 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21311 object);
21312
21313 if (!NILP (help))
21314 {
21315 help_echo_string = help;
21316 help_echo_window = window;
21317 help_echo_object = object;
21318 help_echo_pos = charpos;
21319 }
21320 }
21321 }
21322
21323 /* Look for a `pointer' property. */
21324 if (NILP (pointer))
21325 {
21326 /* Check overlays first. */
21327 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21328 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21329
21330 if (NILP (pointer))
21331 {
21332 Lisp_Object object = glyph->object;
21333 int charpos = glyph->charpos;
21334
21335 /* Try text properties. */
21336 if (STRINGP (object)
21337 && charpos >= 0
21338 && charpos < SCHARS (object))
21339 {
21340 pointer = Fget_text_property (make_number (charpos),
21341 Qpointer, object);
21342 if (NILP (pointer))
21343 {
21344 /* If the string itself doesn't specify a pointer,
21345 see if the buffer text ``under'' it does. */
21346 struct glyph_row *r
21347 = MATRIX_ROW (w->current_matrix, vpos);
21348 int start = MATRIX_ROW_START_CHARPOS (r);
21349 int pos = string_buffer_position (w, object, start);
21350 if (pos > 0)
21351 pointer = Fget_char_property (make_number (pos),
21352 Qpointer, w->buffer);
21353 }
21354 }
21355 else if (BUFFERP (object)
21356 && charpos >= BEGV
21357 && charpos < ZV)
21358 pointer = Fget_text_property (make_number (charpos),
21359 Qpointer, object);
21360 }
21361 }
21362
21363 BEGV = obegv;
21364 ZV = ozv;
21365 current_buffer = obuf;
21366 }
21367
21368 set_cursor:
21369
21370 define_frame_cursor1 (f, cursor, pointer);
21371 }
21372
21373
21374 /* EXPORT for RIF:
21375 Clear any mouse-face on window W. This function is part of the
21376 redisplay interface, and is called from try_window_id and similar
21377 functions to ensure the mouse-highlight is off. */
21378
21379 void
21380 x_clear_window_mouse_face (w)
21381 struct window *w;
21382 {
21383 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21384 Lisp_Object window;
21385
21386 BLOCK_INPUT;
21387 XSETWINDOW (window, w);
21388 if (EQ (window, dpyinfo->mouse_face_window))
21389 clear_mouse_face (dpyinfo);
21390 UNBLOCK_INPUT;
21391 }
21392
21393
21394 /* EXPORT:
21395 Just discard the mouse face information for frame F, if any.
21396 This is used when the size of F is changed. */
21397
21398 void
21399 cancel_mouse_face (f)
21400 struct frame *f;
21401 {
21402 Lisp_Object window;
21403 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21404
21405 window = dpyinfo->mouse_face_window;
21406 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21407 {
21408 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21409 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21410 dpyinfo->mouse_face_window = Qnil;
21411 }
21412 }
21413
21414
21415 #endif /* HAVE_WINDOW_SYSTEM */
21416
21417 \f
21418 /***********************************************************************
21419 Exposure Events
21420 ***********************************************************************/
21421
21422 #ifdef HAVE_WINDOW_SYSTEM
21423
21424 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21425 which intersects rectangle R. R is in window-relative coordinates. */
21426
21427 static void
21428 expose_area (w, row, r, area)
21429 struct window *w;
21430 struct glyph_row *row;
21431 XRectangle *r;
21432 enum glyph_row_area area;
21433 {
21434 struct glyph *first = row->glyphs[area];
21435 struct glyph *end = row->glyphs[area] + row->used[area];
21436 struct glyph *last;
21437 int first_x, start_x, x;
21438
21439 if (area == TEXT_AREA && row->fill_line_p)
21440 /* If row extends face to end of line write the whole line. */
21441 draw_glyphs (w, 0, row, area,
21442 0, row->used[area],
21443 DRAW_NORMAL_TEXT, 0);
21444 else
21445 {
21446 /* Set START_X to the window-relative start position for drawing glyphs of
21447 AREA. The first glyph of the text area can be partially visible.
21448 The first glyphs of other areas cannot. */
21449 start_x = window_box_left_offset (w, area);
21450 x = start_x;
21451 if (area == TEXT_AREA)
21452 x += row->x;
21453
21454 /* Find the first glyph that must be redrawn. */
21455 while (first < end
21456 && x + first->pixel_width < r->x)
21457 {
21458 x += first->pixel_width;
21459 ++first;
21460 }
21461
21462 /* Find the last one. */
21463 last = first;
21464 first_x = x;
21465 while (last < end
21466 && x < r->x + r->width)
21467 {
21468 x += last->pixel_width;
21469 ++last;
21470 }
21471
21472 /* Repaint. */
21473 if (last > first)
21474 draw_glyphs (w, first_x - start_x, row, area,
21475 first - row->glyphs[area], last - row->glyphs[area],
21476 DRAW_NORMAL_TEXT, 0);
21477 }
21478 }
21479
21480
21481 /* Redraw the parts of the glyph row ROW on window W intersecting
21482 rectangle R. R is in window-relative coordinates. Value is
21483 non-zero if mouse-face was overwritten. */
21484
21485 static int
21486 expose_line (w, row, r)
21487 struct window *w;
21488 struct glyph_row *row;
21489 XRectangle *r;
21490 {
21491 xassert (row->enabled_p);
21492
21493 if (row->mode_line_p || w->pseudo_window_p)
21494 draw_glyphs (w, 0, row, TEXT_AREA,
21495 0, row->used[TEXT_AREA],
21496 DRAW_NORMAL_TEXT, 0);
21497 else
21498 {
21499 if (row->used[LEFT_MARGIN_AREA])
21500 expose_area (w, row, r, LEFT_MARGIN_AREA);
21501 if (row->used[TEXT_AREA])
21502 expose_area (w, row, r, TEXT_AREA);
21503 if (row->used[RIGHT_MARGIN_AREA])
21504 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21505 draw_row_fringe_bitmaps (w, row);
21506 }
21507
21508 return row->mouse_face_p;
21509 }
21510
21511
21512 /* Redraw those parts of glyphs rows during expose event handling that
21513 overlap other rows. Redrawing of an exposed line writes over parts
21514 of lines overlapping that exposed line; this function fixes that.
21515
21516 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21517 row in W's current matrix that is exposed and overlaps other rows.
21518 LAST_OVERLAPPING_ROW is the last such row. */
21519
21520 static void
21521 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21522 struct window *w;
21523 struct glyph_row *first_overlapping_row;
21524 struct glyph_row *last_overlapping_row;
21525 {
21526 struct glyph_row *row;
21527
21528 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21529 if (row->overlapping_p)
21530 {
21531 xassert (row->enabled_p && !row->mode_line_p);
21532
21533 if (row->used[LEFT_MARGIN_AREA])
21534 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21535
21536 if (row->used[TEXT_AREA])
21537 x_fix_overlapping_area (w, row, TEXT_AREA);
21538
21539 if (row->used[RIGHT_MARGIN_AREA])
21540 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21541 }
21542 }
21543
21544
21545 /* Return non-zero if W's cursor intersects rectangle R. */
21546
21547 static int
21548 phys_cursor_in_rect_p (w, r)
21549 struct window *w;
21550 XRectangle *r;
21551 {
21552 XRectangle cr, result;
21553 struct glyph *cursor_glyph;
21554
21555 cursor_glyph = get_phys_cursor_glyph (w);
21556 if (cursor_glyph)
21557 {
21558 /* r is relative to W's box, but w->phys_cursor.x is relative
21559 to left edge of W's TEXT area. Adjust it. */
21560 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21561 cr.y = w->phys_cursor.y;
21562 cr.width = cursor_glyph->pixel_width;
21563 cr.height = w->phys_cursor_height;
21564 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21565 I assume the effect is the same -- and this is portable. */
21566 return x_intersect_rectangles (&cr, r, &result);
21567 }
21568 else
21569 return 0;
21570 }
21571
21572
21573 /* EXPORT:
21574 Draw a vertical window border to the right of window W if W doesn't
21575 have vertical scroll bars. */
21576
21577 void
21578 x_draw_vertical_border (w)
21579 struct window *w;
21580 {
21581 /* We could do better, if we knew what type of scroll-bar the adjacent
21582 windows (on either side) have... But we don't :-(
21583 However, I think this works ok. ++KFS 2003-04-25 */
21584
21585 /* Redraw borders between horizontally adjacent windows. Don't
21586 do it for frames with vertical scroll bars because either the
21587 right scroll bar of a window, or the left scroll bar of its
21588 neighbor will suffice as a border. */
21589 if (!WINDOW_RIGHTMOST_P (w)
21590 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21591 {
21592 int x0, x1, y0, y1;
21593
21594 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21595 y1 -= 1;
21596
21597 rif->draw_vertical_window_border (w, x1, y0, y1);
21598 }
21599 else if (!WINDOW_LEFTMOST_P (w)
21600 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21601 {
21602 int x0, x1, y0, y1;
21603
21604 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21605 y1 -= 1;
21606
21607 rif->draw_vertical_window_border (w, x0, y0, y1);
21608 }
21609 }
21610
21611
21612 /* Redraw the part of window W intersection rectangle FR. Pixel
21613 coordinates in FR are frame-relative. Call this function with
21614 input blocked. Value is non-zero if the exposure overwrites
21615 mouse-face. */
21616
21617 static int
21618 expose_window (w, fr)
21619 struct window *w;
21620 XRectangle *fr;
21621 {
21622 struct frame *f = XFRAME (w->frame);
21623 XRectangle wr, r;
21624 int mouse_face_overwritten_p = 0;
21625
21626 /* If window is not yet fully initialized, do nothing. This can
21627 happen when toolkit scroll bars are used and a window is split.
21628 Reconfiguring the scroll bar will generate an expose for a newly
21629 created window. */
21630 if (w->current_matrix == NULL)
21631 return 0;
21632
21633 /* When we're currently updating the window, display and current
21634 matrix usually don't agree. Arrange for a thorough display
21635 later. */
21636 if (w == updated_window)
21637 {
21638 SET_FRAME_GARBAGED (f);
21639 return 0;
21640 }
21641
21642 /* Frame-relative pixel rectangle of W. */
21643 wr.x = WINDOW_LEFT_EDGE_X (w);
21644 wr.y = WINDOW_TOP_EDGE_Y (w);
21645 wr.width = WINDOW_TOTAL_WIDTH (w);
21646 wr.height = WINDOW_TOTAL_HEIGHT (w);
21647
21648 if (x_intersect_rectangles (fr, &wr, &r))
21649 {
21650 int yb = window_text_bottom_y (w);
21651 struct glyph_row *row;
21652 int cursor_cleared_p;
21653 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21654
21655 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21656 r.x, r.y, r.width, r.height));
21657
21658 /* Convert to window coordinates. */
21659 r.x -= WINDOW_LEFT_EDGE_X (w);
21660 r.y -= WINDOW_TOP_EDGE_Y (w);
21661
21662 /* Turn off the cursor. */
21663 if (!w->pseudo_window_p
21664 && phys_cursor_in_rect_p (w, &r))
21665 {
21666 x_clear_cursor (w);
21667 cursor_cleared_p = 1;
21668 }
21669 else
21670 cursor_cleared_p = 0;
21671
21672 /* Update lines intersecting rectangle R. */
21673 first_overlapping_row = last_overlapping_row = NULL;
21674 for (row = w->current_matrix->rows;
21675 row->enabled_p;
21676 ++row)
21677 {
21678 int y0 = row->y;
21679 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21680
21681 if ((y0 >= r.y && y0 < r.y + r.height)
21682 || (y1 > r.y && y1 < r.y + r.height)
21683 || (r.y >= y0 && r.y < y1)
21684 || (r.y + r.height > y0 && r.y + r.height < y1))
21685 {
21686 if (row->overlapping_p)
21687 {
21688 if (first_overlapping_row == NULL)
21689 first_overlapping_row = row;
21690 last_overlapping_row = row;
21691 }
21692
21693 if (expose_line (w, row, &r))
21694 mouse_face_overwritten_p = 1;
21695 }
21696
21697 if (y1 >= yb)
21698 break;
21699 }
21700
21701 /* Display the mode line if there is one. */
21702 if (WINDOW_WANTS_MODELINE_P (w)
21703 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21704 row->enabled_p)
21705 && row->y < r.y + r.height)
21706 {
21707 if (expose_line (w, row, &r))
21708 mouse_face_overwritten_p = 1;
21709 }
21710
21711 if (!w->pseudo_window_p)
21712 {
21713 /* Fix the display of overlapping rows. */
21714 if (first_overlapping_row)
21715 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21716
21717 /* Draw border between windows. */
21718 x_draw_vertical_border (w);
21719
21720 /* Turn the cursor on again. */
21721 if (cursor_cleared_p)
21722 update_window_cursor (w, 1);
21723 }
21724 }
21725
21726 #ifdef HAVE_CARBON
21727 /* Display scroll bar for this window. */
21728 if (!NILP (w->vertical_scroll_bar))
21729 {
21730 /* ++KFS:
21731 If this doesn't work here (maybe some header files are missing),
21732 make a function in macterm.c and call it to do the job! */
21733 ControlHandle ch
21734 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21735
21736 Draw1Control (ch);
21737 }
21738 #endif
21739
21740 return mouse_face_overwritten_p;
21741 }
21742
21743
21744
21745 /* Redraw (parts) of all windows in the window tree rooted at W that
21746 intersect R. R contains frame pixel coordinates. Value is
21747 non-zero if the exposure overwrites mouse-face. */
21748
21749 static int
21750 expose_window_tree (w, r)
21751 struct window *w;
21752 XRectangle *r;
21753 {
21754 struct frame *f = XFRAME (w->frame);
21755 int mouse_face_overwritten_p = 0;
21756
21757 while (w && !FRAME_GARBAGED_P (f))
21758 {
21759 if (!NILP (w->hchild))
21760 mouse_face_overwritten_p
21761 |= expose_window_tree (XWINDOW (w->hchild), r);
21762 else if (!NILP (w->vchild))
21763 mouse_face_overwritten_p
21764 |= expose_window_tree (XWINDOW (w->vchild), r);
21765 else
21766 mouse_face_overwritten_p |= expose_window (w, r);
21767
21768 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21769 }
21770
21771 return mouse_face_overwritten_p;
21772 }
21773
21774
21775 /* EXPORT:
21776 Redisplay an exposed area of frame F. X and Y are the upper-left
21777 corner of the exposed rectangle. W and H are width and height of
21778 the exposed area. All are pixel values. W or H zero means redraw
21779 the entire frame. */
21780
21781 void
21782 expose_frame (f, x, y, w, h)
21783 struct frame *f;
21784 int x, y, w, h;
21785 {
21786 XRectangle r;
21787 int mouse_face_overwritten_p = 0;
21788
21789 TRACE ((stderr, "expose_frame "));
21790
21791 /* No need to redraw if frame will be redrawn soon. */
21792 if (FRAME_GARBAGED_P (f))
21793 {
21794 TRACE ((stderr, " garbaged\n"));
21795 return;
21796 }
21797
21798 #ifdef HAVE_CARBON
21799 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21800 or deactivated here, for unknown reasons, activated scroll bars
21801 are shown in deactivated frames in some instances. */
21802 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21803 activate_scroll_bars (f);
21804 else
21805 deactivate_scroll_bars (f);
21806 #endif
21807
21808 /* If basic faces haven't been realized yet, there is no point in
21809 trying to redraw anything. This can happen when we get an expose
21810 event while Emacs is starting, e.g. by moving another window. */
21811 if (FRAME_FACE_CACHE (f) == NULL
21812 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21813 {
21814 TRACE ((stderr, " no faces\n"));
21815 return;
21816 }
21817
21818 if (w == 0 || h == 0)
21819 {
21820 r.x = r.y = 0;
21821 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21822 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21823 }
21824 else
21825 {
21826 r.x = x;
21827 r.y = y;
21828 r.width = w;
21829 r.height = h;
21830 }
21831
21832 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21833 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21834
21835 if (WINDOWP (f->tool_bar_window))
21836 mouse_face_overwritten_p
21837 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21838
21839 #ifdef HAVE_X_WINDOWS
21840 #ifndef MSDOS
21841 #ifndef USE_X_TOOLKIT
21842 if (WINDOWP (f->menu_bar_window))
21843 mouse_face_overwritten_p
21844 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21845 #endif /* not USE_X_TOOLKIT */
21846 #endif
21847 #endif
21848
21849 /* Some window managers support a focus-follows-mouse style with
21850 delayed raising of frames. Imagine a partially obscured frame,
21851 and moving the mouse into partially obscured mouse-face on that
21852 frame. The visible part of the mouse-face will be highlighted,
21853 then the WM raises the obscured frame. With at least one WM, KDE
21854 2.1, Emacs is not getting any event for the raising of the frame
21855 (even tried with SubstructureRedirectMask), only Expose events.
21856 These expose events will draw text normally, i.e. not
21857 highlighted. Which means we must redo the highlight here.
21858 Subsume it under ``we love X''. --gerd 2001-08-15 */
21859 /* Included in Windows version because Windows most likely does not
21860 do the right thing if any third party tool offers
21861 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21862 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21863 {
21864 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21865 if (f == dpyinfo->mouse_face_mouse_frame)
21866 {
21867 int x = dpyinfo->mouse_face_mouse_x;
21868 int y = dpyinfo->mouse_face_mouse_y;
21869 clear_mouse_face (dpyinfo);
21870 note_mouse_highlight (f, x, y);
21871 }
21872 }
21873 }
21874
21875
21876 /* EXPORT:
21877 Determine the intersection of two rectangles R1 and R2. Return
21878 the intersection in *RESULT. Value is non-zero if RESULT is not
21879 empty. */
21880
21881 int
21882 x_intersect_rectangles (r1, r2, result)
21883 XRectangle *r1, *r2, *result;
21884 {
21885 XRectangle *left, *right;
21886 XRectangle *upper, *lower;
21887 int intersection_p = 0;
21888
21889 /* Rearrange so that R1 is the left-most rectangle. */
21890 if (r1->x < r2->x)
21891 left = r1, right = r2;
21892 else
21893 left = r2, right = r1;
21894
21895 /* X0 of the intersection is right.x0, if this is inside R1,
21896 otherwise there is no intersection. */
21897 if (right->x <= left->x + left->width)
21898 {
21899 result->x = right->x;
21900
21901 /* The right end of the intersection is the minimum of the
21902 the right ends of left and right. */
21903 result->width = (min (left->x + left->width, right->x + right->width)
21904 - result->x);
21905
21906 /* Same game for Y. */
21907 if (r1->y < r2->y)
21908 upper = r1, lower = r2;
21909 else
21910 upper = r2, lower = r1;
21911
21912 /* The upper end of the intersection is lower.y0, if this is inside
21913 of upper. Otherwise, there is no intersection. */
21914 if (lower->y <= upper->y + upper->height)
21915 {
21916 result->y = lower->y;
21917
21918 /* The lower end of the intersection is the minimum of the lower
21919 ends of upper and lower. */
21920 result->height = (min (lower->y + lower->height,
21921 upper->y + upper->height)
21922 - result->y);
21923 intersection_p = 1;
21924 }
21925 }
21926
21927 return intersection_p;
21928 }
21929
21930 #endif /* HAVE_WINDOW_SYSTEM */
21931
21932 \f
21933 /***********************************************************************
21934 Initialization
21935 ***********************************************************************/
21936
21937 void
21938 syms_of_xdisp ()
21939 {
21940 Vwith_echo_area_save_vector = Qnil;
21941 staticpro (&Vwith_echo_area_save_vector);
21942
21943 Vmessage_stack = Qnil;
21944 staticpro (&Vmessage_stack);
21945
21946 Qinhibit_redisplay = intern ("inhibit-redisplay");
21947 staticpro (&Qinhibit_redisplay);
21948
21949 message_dolog_marker1 = Fmake_marker ();
21950 staticpro (&message_dolog_marker1);
21951 message_dolog_marker2 = Fmake_marker ();
21952 staticpro (&message_dolog_marker2);
21953 message_dolog_marker3 = Fmake_marker ();
21954 staticpro (&message_dolog_marker3);
21955
21956 #if GLYPH_DEBUG
21957 defsubr (&Sdump_frame_glyph_matrix);
21958 defsubr (&Sdump_glyph_matrix);
21959 defsubr (&Sdump_glyph_row);
21960 defsubr (&Sdump_tool_bar_row);
21961 defsubr (&Strace_redisplay);
21962 defsubr (&Strace_to_stderr);
21963 #endif
21964 #ifdef HAVE_WINDOW_SYSTEM
21965 defsubr (&Stool_bar_lines_needed);
21966 defsubr (&Slookup_image_map);
21967 #endif
21968 defsubr (&Sformat_mode_line);
21969
21970 staticpro (&Qmenu_bar_update_hook);
21971 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21972
21973 staticpro (&Qoverriding_terminal_local_map);
21974 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21975
21976 staticpro (&Qoverriding_local_map);
21977 Qoverriding_local_map = intern ("overriding-local-map");
21978
21979 staticpro (&Qwindow_scroll_functions);
21980 Qwindow_scroll_functions = intern ("window-scroll-functions");
21981
21982 staticpro (&Qredisplay_end_trigger_functions);
21983 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21984
21985 staticpro (&Qinhibit_point_motion_hooks);
21986 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21987
21988 QCdata = intern (":data");
21989 staticpro (&QCdata);
21990 Qdisplay = intern ("display");
21991 staticpro (&Qdisplay);
21992 Qspace_width = intern ("space-width");
21993 staticpro (&Qspace_width);
21994 Qraise = intern ("raise");
21995 staticpro (&Qraise);
21996 Qslice = intern ("slice");
21997 staticpro (&Qslice);
21998 Qspace = intern ("space");
21999 staticpro (&Qspace);
22000 Qmargin = intern ("margin");
22001 staticpro (&Qmargin);
22002 Qpointer = intern ("pointer");
22003 staticpro (&Qpointer);
22004 Qleft_margin = intern ("left-margin");
22005 staticpro (&Qleft_margin);
22006 Qright_margin = intern ("right-margin");
22007 staticpro (&Qright_margin);
22008 Qcenter = intern ("center");
22009 staticpro (&Qcenter);
22010 Qline_height = intern ("line-height");
22011 staticpro (&Qline_height);
22012 Qtotal = intern ("total");
22013 staticpro (&Qtotal);
22014 QCalign_to = intern (":align-to");
22015 staticpro (&QCalign_to);
22016 QCrelative_width = intern (":relative-width");
22017 staticpro (&QCrelative_width);
22018 QCrelative_height = intern (":relative-height");
22019 staticpro (&QCrelative_height);
22020 QCeval = intern (":eval");
22021 staticpro (&QCeval);
22022 QCpropertize = intern (":propertize");
22023 staticpro (&QCpropertize);
22024 QCfile = intern (":file");
22025 staticpro (&QCfile);
22026 Qfontified = intern ("fontified");
22027 staticpro (&Qfontified);
22028 Qfontification_functions = intern ("fontification-functions");
22029 staticpro (&Qfontification_functions);
22030 Qtrailing_whitespace = intern ("trailing-whitespace");
22031 staticpro (&Qtrailing_whitespace);
22032 Qimage = intern ("image");
22033 staticpro (&Qimage);
22034 QCmap = intern (":map");
22035 staticpro (&QCmap);
22036 QCpointer = intern (":pointer");
22037 staticpro (&QCpointer);
22038 Qrect = intern ("rect");
22039 staticpro (&Qrect);
22040 Qcircle = intern ("circle");
22041 staticpro (&Qcircle);
22042 Qpoly = intern ("poly");
22043 staticpro (&Qpoly);
22044 Qmessage_truncate_lines = intern ("message-truncate-lines");
22045 staticpro (&Qmessage_truncate_lines);
22046 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22047 staticpro (&Qcursor_in_non_selected_windows);
22048 Qgrow_only = intern ("grow-only");
22049 staticpro (&Qgrow_only);
22050 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22051 staticpro (&Qinhibit_menubar_update);
22052 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22053 staticpro (&Qinhibit_eval_during_redisplay);
22054 Qposition = intern ("position");
22055 staticpro (&Qposition);
22056 Qbuffer_position = intern ("buffer-position");
22057 staticpro (&Qbuffer_position);
22058 Qobject = intern ("object");
22059 staticpro (&Qobject);
22060 Qbar = intern ("bar");
22061 staticpro (&Qbar);
22062 Qhbar = intern ("hbar");
22063 staticpro (&Qhbar);
22064 Qbox = intern ("box");
22065 staticpro (&Qbox);
22066 Qhollow = intern ("hollow");
22067 staticpro (&Qhollow);
22068 Qhand = intern ("hand");
22069 staticpro (&Qhand);
22070 Qarrow = intern ("arrow");
22071 staticpro (&Qarrow);
22072 Qtext = intern ("text");
22073 staticpro (&Qtext);
22074 Qrisky_local_variable = intern ("risky-local-variable");
22075 staticpro (&Qrisky_local_variable);
22076 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22077 staticpro (&Qinhibit_free_realized_faces);
22078
22079 list_of_error = Fcons (Fcons (intern ("error"),
22080 Fcons (intern ("void-variable"), Qnil)),
22081 Qnil);
22082 staticpro (&list_of_error);
22083
22084 Qlast_arrow_position = intern ("last-arrow-position");
22085 staticpro (&Qlast_arrow_position);
22086 Qlast_arrow_string = intern ("last-arrow-string");
22087 staticpro (&Qlast_arrow_string);
22088
22089 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22090 staticpro (&Qoverlay_arrow_string);
22091 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22092 staticpro (&Qoverlay_arrow_bitmap);
22093
22094 echo_buffer[0] = echo_buffer[1] = Qnil;
22095 staticpro (&echo_buffer[0]);
22096 staticpro (&echo_buffer[1]);
22097
22098 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22099 staticpro (&echo_area_buffer[0]);
22100 staticpro (&echo_area_buffer[1]);
22101
22102 Vmessages_buffer_name = build_string ("*Messages*");
22103 staticpro (&Vmessages_buffer_name);
22104
22105 mode_line_proptrans_alist = Qnil;
22106 staticpro (&mode_line_proptrans_alist);
22107
22108 mode_line_string_list = Qnil;
22109 staticpro (&mode_line_string_list);
22110
22111 help_echo_string = Qnil;
22112 staticpro (&help_echo_string);
22113 help_echo_object = Qnil;
22114 staticpro (&help_echo_object);
22115 help_echo_window = Qnil;
22116 staticpro (&help_echo_window);
22117 previous_help_echo_string = Qnil;
22118 staticpro (&previous_help_echo_string);
22119 help_echo_pos = -1;
22120
22121 #ifdef HAVE_WINDOW_SYSTEM
22122 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22123 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22124 For example, if a block cursor is over a tab, it will be drawn as
22125 wide as that tab on the display. */);
22126 x_stretch_cursor_p = 0;
22127 #endif
22128
22129 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22130 doc: /* *Non-nil means highlight trailing whitespace.
22131 The face used for trailing whitespace is `trailing-whitespace'. */);
22132 Vshow_trailing_whitespace = Qnil;
22133
22134 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22135 doc: /* *The pointer shape to show in void text areas.
22136 Nil means to show the text pointer. Other options are `arrow', `text',
22137 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22138 Vvoid_text_area_pointer = Qarrow;
22139
22140 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22141 doc: /* Non-nil means don't actually do any redisplay.
22142 This is used for internal purposes. */);
22143 Vinhibit_redisplay = Qnil;
22144
22145 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22146 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22147 Vglobal_mode_string = Qnil;
22148
22149 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22150 doc: /* Marker for where to display an arrow on top of the buffer text.
22151 This must be the beginning of a line in order to work.
22152 See also `overlay-arrow-string'. */);
22153 Voverlay_arrow_position = Qnil;
22154
22155 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22156 doc: /* String to display as an arrow in non-window frames.
22157 See also `overlay-arrow-position'. */);
22158 Voverlay_arrow_string = Qnil;
22159
22160 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22161 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22162 The symbols on this list are examined during redisplay to determine
22163 where to display overlay arrows. */);
22164 Voverlay_arrow_variable_list
22165 = Fcons (intern ("overlay-arrow-position"), Qnil);
22166
22167 DEFVAR_INT ("scroll-step", &scroll_step,
22168 doc: /* *The number of lines to try scrolling a window by when point moves out.
22169 If that fails to bring point back on frame, point is centered instead.
22170 If this is zero, point is always centered after it moves off frame.
22171 If you want scrolling to always be a line at a time, you should set
22172 `scroll-conservatively' to a large value rather than set this to 1. */);
22173
22174 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22175 doc: /* *Scroll up to this many lines, to bring point back on screen.
22176 A value of zero means to scroll the text to center point vertically
22177 in the window. */);
22178 scroll_conservatively = 0;
22179
22180 DEFVAR_INT ("scroll-margin", &scroll_margin,
22181 doc: /* *Number of lines of margin at the top and bottom of a window.
22182 Recenter the window whenever point gets within this many lines
22183 of the top or bottom of the window. */);
22184 scroll_margin = 0;
22185
22186 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22187 doc: /* Pixels per inch on current display.
22188 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22189 Vdisplay_pixels_per_inch = make_float (72.0);
22190
22191 #if GLYPH_DEBUG
22192 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22193 #endif
22194
22195 DEFVAR_BOOL ("truncate-partial-width-windows",
22196 &truncate_partial_width_windows,
22197 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22198 truncate_partial_width_windows = 1;
22199
22200 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22201 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22202 Any other value means to use the appropriate face, `mode-line',
22203 `header-line', or `menu' respectively. */);
22204 mode_line_inverse_video = 1;
22205
22206 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22207 doc: /* *Maximum buffer size for which line number should be displayed.
22208 If the buffer is bigger than this, the line number does not appear
22209 in the mode line. A value of nil means no limit. */);
22210 Vline_number_display_limit = Qnil;
22211
22212 DEFVAR_INT ("line-number-display-limit-width",
22213 &line_number_display_limit_width,
22214 doc: /* *Maximum line width (in characters) for line number display.
22215 If the average length of the lines near point is bigger than this, then the
22216 line number may be omitted from the mode line. */);
22217 line_number_display_limit_width = 200;
22218
22219 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22220 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22221 highlight_nonselected_windows = 0;
22222
22223 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22224 doc: /* Non-nil if more than one frame is visible on this display.
22225 Minibuffer-only frames don't count, but iconified frames do.
22226 This variable is not guaranteed to be accurate except while processing
22227 `frame-title-format' and `icon-title-format'. */);
22228
22229 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22230 doc: /* Template for displaying the title bar of visible frames.
22231 \(Assuming the window manager supports this feature.)
22232 This variable has the same structure as `mode-line-format' (which see),
22233 and is used only on frames for which no explicit name has been set
22234 \(see `modify-frame-parameters'). */);
22235
22236 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22237 doc: /* Template for displaying the title bar of an iconified frame.
22238 \(Assuming the window manager supports this feature.)
22239 This variable has the same structure as `mode-line-format' (which see),
22240 and is used only on frames for which no explicit name has been set
22241 \(see `modify-frame-parameters'). */);
22242 Vicon_title_format
22243 = Vframe_title_format
22244 = Fcons (intern ("multiple-frames"),
22245 Fcons (build_string ("%b"),
22246 Fcons (Fcons (empty_string,
22247 Fcons (intern ("invocation-name"),
22248 Fcons (build_string ("@"),
22249 Fcons (intern ("system-name"),
22250 Qnil)))),
22251 Qnil)));
22252
22253 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22254 doc: /* Maximum number of lines to keep in the message log buffer.
22255 If nil, disable message logging. If t, log messages but don't truncate
22256 the buffer when it becomes large. */);
22257 Vmessage_log_max = make_number (50);
22258
22259 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22260 doc: /* Functions called before redisplay, if window sizes have changed.
22261 The value should be a list of functions that take one argument.
22262 Just before redisplay, for each frame, if any of its windows have changed
22263 size since the last redisplay, or have been split or deleted,
22264 all the functions in the list are called, with the frame as argument. */);
22265 Vwindow_size_change_functions = Qnil;
22266
22267 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22268 doc: /* List of functions to call before redisplaying a window with scrolling.
22269 Each function is called with two arguments, the window
22270 and its new display-start position. Note that the value of `window-end'
22271 is not valid when these functions are called. */);
22272 Vwindow_scroll_functions = Qnil;
22273
22274 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22275 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22276 mouse_autoselect_window = 0;
22277
22278 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22279 doc: /* *Non-nil means automatically resize tool-bars.
22280 This increases a tool-bar's height if not all tool-bar items are visible.
22281 It decreases a tool-bar's height when it would display blank lines
22282 otherwise. */);
22283 auto_resize_tool_bars_p = 1;
22284
22285 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22286 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22287 auto_raise_tool_bar_buttons_p = 1;
22288
22289 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22290 doc: /* *Margin around tool-bar buttons in pixels.
22291 If an integer, use that for both horizontal and vertical margins.
22292 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22293 HORZ specifying the horizontal margin, and VERT specifying the
22294 vertical margin. */);
22295 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22296
22297 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22298 doc: /* *Relief thickness of tool-bar buttons. */);
22299 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22300
22301 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22302 doc: /* List of functions to call to fontify regions of text.
22303 Each function is called with one argument POS. Functions must
22304 fontify a region starting at POS in the current buffer, and give
22305 fontified regions the property `fontified'. */);
22306 Vfontification_functions = Qnil;
22307 Fmake_variable_buffer_local (Qfontification_functions);
22308
22309 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22310 &unibyte_display_via_language_environment,
22311 doc: /* *Non-nil means display unibyte text according to language environment.
22312 Specifically this means that unibyte non-ASCII characters
22313 are displayed by converting them to the equivalent multibyte characters
22314 according to the current language environment. As a result, they are
22315 displayed according to the current fontset. */);
22316 unibyte_display_via_language_environment = 0;
22317
22318 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22319 doc: /* *Maximum height for resizing mini-windows.
22320 If a float, it specifies a fraction of the mini-window frame's height.
22321 If an integer, it specifies a number of lines. */);
22322 Vmax_mini_window_height = make_float (0.25);
22323
22324 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22325 doc: /* *How to resize mini-windows.
22326 A value of nil means don't automatically resize mini-windows.
22327 A value of t means resize them to fit the text displayed in them.
22328 A value of `grow-only', the default, means let mini-windows grow
22329 only, until their display becomes empty, at which point the windows
22330 go back to their normal size. */);
22331 Vresize_mini_windows = Qgrow_only;
22332
22333 DEFVAR_LISP ("cursor-in-non-selected-windows",
22334 &Vcursor_in_non_selected_windows,
22335 doc: /* *Cursor type to display in non-selected windows.
22336 t means to use hollow box cursor. See `cursor-type' for other values. */);
22337 Vcursor_in_non_selected_windows = Qt;
22338
22339 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22340 doc: /* Alist specifying how to blink the cursor off.
22341 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22342 `cursor-type' frame-parameter or variable equals ON-STATE,
22343 comparing using `equal', Emacs uses OFF-STATE to specify
22344 how to blink it off. */);
22345 Vblink_cursor_alist = Qnil;
22346
22347 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22348 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22349 automatic_hscrolling_p = 1;
22350
22351 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22352 doc: /* *How many columns away from the window edge point is allowed to get
22353 before automatic hscrolling will horizontally scroll the window. */);
22354 hscroll_margin = 5;
22355
22356 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22357 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22358 When point is less than `automatic-hscroll-margin' columns from the window
22359 edge, automatic hscrolling will scroll the window by the amount of columns
22360 determined by this variable. If its value is a positive integer, scroll that
22361 many columns. If it's a positive floating-point number, it specifies the
22362 fraction of the window's width to scroll. If it's nil or zero, point will be
22363 centered horizontally after the scroll. Any other value, including negative
22364 numbers, are treated as if the value were zero.
22365
22366 Automatic hscrolling always moves point outside the scroll margin, so if
22367 point was more than scroll step columns inside the margin, the window will
22368 scroll more than the value given by the scroll step.
22369
22370 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22371 and `scroll-right' overrides this variable's effect. */);
22372 Vhscroll_step = make_number (0);
22373
22374 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22375 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22376 Bind this around calls to `message' to let it take effect. */);
22377 message_truncate_lines = 0;
22378
22379 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22380 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22381 Can be used to update submenus whose contents should vary. */);
22382 Vmenu_bar_update_hook = Qnil;
22383
22384 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22385 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22386 inhibit_menubar_update = 0;
22387
22388 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22389 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22390 inhibit_eval_during_redisplay = 0;
22391
22392 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22393 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22394 inhibit_free_realized_faces = 0;
22395
22396 #if GLYPH_DEBUG
22397 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22398 doc: /* Inhibit try_window_id display optimization. */);
22399 inhibit_try_window_id = 0;
22400
22401 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22402 doc: /* Inhibit try_window_reusing display optimization. */);
22403 inhibit_try_window_reusing = 0;
22404
22405 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22406 doc: /* Inhibit try_cursor_movement display optimization. */);
22407 inhibit_try_cursor_movement = 0;
22408 #endif /* GLYPH_DEBUG */
22409 }
22410
22411
22412 /* Initialize this module when Emacs starts. */
22413
22414 void
22415 init_xdisp ()
22416 {
22417 Lisp_Object root_window;
22418 struct window *mini_w;
22419
22420 current_header_line_height = current_mode_line_height = -1;
22421
22422 CHARPOS (this_line_start_pos) = 0;
22423
22424 mini_w = XWINDOW (minibuf_window);
22425 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22426
22427 if (!noninteractive)
22428 {
22429 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22430 int i;
22431
22432 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22433 set_window_height (root_window,
22434 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22435 0);
22436 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22437 set_window_height (minibuf_window, 1, 0);
22438
22439 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22440 mini_w->total_cols = make_number (FRAME_COLS (f));
22441
22442 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22443 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22444 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22445
22446 /* The default ellipsis glyphs `...'. */
22447 for (i = 0; i < 3; ++i)
22448 default_invis_vector[i] = make_number ('.');
22449 }
22450
22451 {
22452 /* Allocate the buffer for frame titles.
22453 Also used for `format-mode-line'. */
22454 int size = 100;
22455 frame_title_buf = (char *) xmalloc (size);
22456 frame_title_buf_end = frame_title_buf + size;
22457 frame_title_ptr = NULL;
22458 }
22459
22460 help_echo_showing_p = 0;
22461 }
22462
22463
22464 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22465 (do not change this comment) */