]> code.delx.au - gnu-emacs/blob - src/xdisp.c
*** empty log message ***
[gnu-emacs] / 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 Lisp_Object do_mouse_tracking;
219
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
222
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
231
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
241
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
247
248 Lisp_Object Qrisky_local_variable;
249
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
252
253 /* Functions called to fontify regions of text. */
254
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
257
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
261
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
264
265 int auto_raise_tool_bar_buttons_p;
266
267 /* Margin around tool bar buttons in pixels. */
268
269 Lisp_Object Vtool_bar_button_margin;
270
271 /* Thickness of shadow to draw around tool bar buttons. */
272
273 EMACS_INT tool_bar_button_relief;
274
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
277
278 int auto_resize_tool_bars_p;
279
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
283
284 int x_stretch_cursor_p;
285
286 /* Non-nil means don't actually do any redisplay. */
287
288 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
289
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
291
292 int inhibit_eval_during_redisplay;
293
294 /* Names of text properties relevant for redisplay. */
295
296 Lisp_Object Qdisplay;
297 extern Lisp_Object Qface, Qinvisible, Qwidth;
298
299 /* Symbols used in text property values. */
300
301 Lisp_Object Vdisplay_pixels_per_inch;
302 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304 Lisp_Object Qslice;
305 Lisp_Object Qcenter;
306 Lisp_Object Qmargin, Qpointer;
307 Lisp_Object Qline_height, Qtotal;
308 extern Lisp_Object Qheight;
309 extern Lisp_Object QCwidth, QCheight, QCascent;
310 extern Lisp_Object Qscroll_bar;
311 extern Lisp_Object Qcursor;
312
313 /* Non-nil means highlight trailing whitespace. */
314
315 Lisp_Object Vshow_trailing_whitespace;
316
317 #ifdef HAVE_WINDOW_SYSTEM
318 extern Lisp_Object Voverflow_newline_into_fringe;
319
320 /* Test if overflow newline into fringe. Called with iterator IT
321 at or past right window margin, and with IT->current_x set. */
322
323 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
324 (!NILP (Voverflow_newline_into_fringe) \
325 && FRAME_WINDOW_P (it->f) \
326 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
327 && it->current_x == it->last_visible_x)
328
329 #endif /* HAVE_WINDOW_SYSTEM */
330
331 /* Non-nil means show the text cursor in void text areas
332 i.e. in blank areas after eol and eob. This used to be
333 the default in 21.3. */
334
335 Lisp_Object Vvoid_text_area_pointer;
336
337 /* Name of the face used to highlight trailing whitespace. */
338
339 Lisp_Object Qtrailing_whitespace;
340
341 /* The symbol `image' which is the car of the lists used to represent
342 images in Lisp. */
343
344 Lisp_Object Qimage;
345
346 /* The image map types. */
347 Lisp_Object QCmap, QCpointer;
348 Lisp_Object Qrect, Qcircle, Qpoly;
349
350 /* Non-zero means print newline to stdout before next mini-buffer
351 message. */
352
353 int noninteractive_need_newline;
354
355 /* Non-zero means print newline to message log before next message. */
356
357 static int message_log_need_newline;
358
359 /* Three markers that message_dolog uses.
360 It could allocate them itself, but that causes trouble
361 in handling memory-full errors. */
362 static Lisp_Object message_dolog_marker1;
363 static Lisp_Object message_dolog_marker2;
364 static Lisp_Object message_dolog_marker3;
365 \f
366 /* The buffer position of the first character appearing entirely or
367 partially on the line of the selected window which contains the
368 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
369 redisplay optimization in redisplay_internal. */
370
371 static struct text_pos this_line_start_pos;
372
373 /* Number of characters past the end of the line above, including the
374 terminating newline. */
375
376 static struct text_pos this_line_end_pos;
377
378 /* The vertical positions and the height of this line. */
379
380 static int this_line_vpos;
381 static int this_line_y;
382 static int this_line_pixel_height;
383
384 /* X position at which this display line starts. Usually zero;
385 negative if first character is partially visible. */
386
387 static int this_line_start_x;
388
389 /* Buffer that this_line_.* variables are referring to. */
390
391 static struct buffer *this_line_buffer;
392
393 /* Nonzero means truncate lines in all windows less wide than the
394 frame. */
395
396 int truncate_partial_width_windows;
397
398 /* A flag to control how to display unibyte 8-bit character. */
399
400 int unibyte_display_via_language_environment;
401
402 /* Nonzero means we have more than one non-mini-buffer-only frame.
403 Not guaranteed to be accurate except while parsing
404 frame-title-format. */
405
406 int multiple_frames;
407
408 Lisp_Object Vglobal_mode_string;
409
410
411 /* List of variables (symbols) which hold markers for overlay arrows.
412 The symbols on this list are examined during redisplay to determine
413 where to display overlay arrows. */
414
415 Lisp_Object Voverlay_arrow_variable_list;
416
417 /* Marker for where to display an arrow on top of the buffer text. */
418
419 Lisp_Object Voverlay_arrow_position;
420
421 /* String to display for the arrow. Only used on terminal frames. */
422
423 Lisp_Object Voverlay_arrow_string;
424
425 /* Values of those variables at last redisplay are stored as
426 properties on `overlay-arrow-position' symbol. However, if
427 Voverlay_arrow_position is a marker, last-arrow-position is its
428 numerical position. */
429
430 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
431
432 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
433 properties on a symbol in overlay-arrow-variable-list. */
434
435 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
436
437 /* Like mode-line-format, but for the title bar on a visible frame. */
438
439 Lisp_Object Vframe_title_format;
440
441 /* Like mode-line-format, but for the title bar on an iconified frame. */
442
443 Lisp_Object Vicon_title_format;
444
445 /* List of functions to call when a window's size changes. These
446 functions get one arg, a frame on which one or more windows' sizes
447 have changed. */
448
449 static Lisp_Object Vwindow_size_change_functions;
450
451 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
452
453 /* Nonzero if overlay arrow has been displayed once in this window. */
454
455 static int overlay_arrow_seen;
456
457 /* Nonzero means highlight the region even in nonselected windows. */
458
459 int highlight_nonselected_windows;
460
461 /* If cursor motion alone moves point off frame, try scrolling this
462 many lines up or down if that will bring it back. */
463
464 static EMACS_INT scroll_step;
465
466 /* Nonzero means scroll just far enough to bring point back on the
467 screen, when appropriate. */
468
469 static EMACS_INT scroll_conservatively;
470
471 /* Recenter the window whenever point gets within this many lines of
472 the top or bottom of the window. This value is translated into a
473 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
474 that there is really a fixed pixel height scroll margin. */
475
476 EMACS_INT scroll_margin;
477
478 /* Number of windows showing the buffer of the selected window (or
479 another buffer with the same base buffer). keyboard.c refers to
480 this. */
481
482 int buffer_shared;
483
484 /* Vector containing glyphs for an ellipsis `...'. */
485
486 static Lisp_Object default_invis_vector[3];
487
488 /* Zero means display the mode-line/header-line/menu-bar in the default face
489 (this slightly odd definition is for compatibility with previous versions
490 of emacs), non-zero means display them using their respective faces.
491
492 This variable is deprecated. */
493
494 int mode_line_inverse_video;
495
496 /* Prompt to display in front of the mini-buffer contents. */
497
498 Lisp_Object minibuf_prompt;
499
500 /* Width of current mini-buffer prompt. Only set after display_line
501 of the line that contains the prompt. */
502
503 int minibuf_prompt_width;
504
505 /* This is the window where the echo area message was displayed. It
506 is always a mini-buffer window, but it may not be the same window
507 currently active as a mini-buffer. */
508
509 Lisp_Object echo_area_window;
510
511 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
512 pushes the current message and the value of
513 message_enable_multibyte on the stack, the function restore_message
514 pops the stack and displays MESSAGE again. */
515
516 Lisp_Object Vmessage_stack;
517
518 /* Nonzero means multibyte characters were enabled when the echo area
519 message was specified. */
520
521 int message_enable_multibyte;
522
523 /* Nonzero if we should redraw the mode lines on the next redisplay. */
524
525 int update_mode_lines;
526
527 /* Nonzero if window sizes or contents have changed since last
528 redisplay that finished. */
529
530 int windows_or_buffers_changed;
531
532 /* Nonzero means a frame's cursor type has been changed. */
533
534 int cursor_type_changed;
535
536 /* Nonzero after display_mode_line if %l was used and it displayed a
537 line number. */
538
539 int line_number_displayed;
540
541 /* Maximum buffer size for which to display line numbers. */
542
543 Lisp_Object Vline_number_display_limit;
544
545 /* Line width to consider when repositioning for line number display. */
546
547 static EMACS_INT line_number_display_limit_width;
548
549 /* Number of lines to keep in the message log buffer. t means
550 infinite. nil means don't log at all. */
551
552 Lisp_Object Vmessage_log_max;
553
554 /* The name of the *Messages* buffer, a string. */
555
556 static Lisp_Object Vmessages_buffer_name;
557
558 /* Current, index 0, and last displayed echo area message. Either
559 buffers from echo_buffers, or nil to indicate no message. */
560
561 Lisp_Object echo_area_buffer[2];
562
563 /* The buffers referenced from echo_area_buffer. */
564
565 static Lisp_Object echo_buffer[2];
566
567 /* A vector saved used in with_area_buffer to reduce consing. */
568
569 static Lisp_Object Vwith_echo_area_save_vector;
570
571 /* Non-zero means display_echo_area should display the last echo area
572 message again. Set by redisplay_preserve_echo_area. */
573
574 static int display_last_displayed_message_p;
575
576 /* Nonzero if echo area is being used by print; zero if being used by
577 message. */
578
579 int message_buf_print;
580
581 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
582
583 Lisp_Object Qinhibit_menubar_update;
584 int inhibit_menubar_update;
585
586 /* Maximum height for resizing mini-windows. Either a float
587 specifying a fraction of the available height, or an integer
588 specifying a number of lines. */
589
590 Lisp_Object Vmax_mini_window_height;
591
592 /* Non-zero means messages should be displayed with truncated
593 lines instead of being continued. */
594
595 int message_truncate_lines;
596 Lisp_Object Qmessage_truncate_lines;
597
598 /* Set to 1 in clear_message to make redisplay_internal aware
599 of an emptied echo area. */
600
601 static int message_cleared_p;
602
603 /* Non-zero means we want a hollow cursor in windows that are not
604 selected. Zero means there's no cursor in such windows. */
605
606 Lisp_Object Vcursor_in_non_selected_windows;
607 Lisp_Object Qcursor_in_non_selected_windows;
608
609 /* How to blink the default frame cursor off. */
610 Lisp_Object Vblink_cursor_alist;
611
612 /* A scratch glyph row with contents used for generating truncation
613 glyphs. Also used in direct_output_for_insert. */
614
615 #define MAX_SCRATCH_GLYPHS 100
616 struct glyph_row scratch_glyph_row;
617 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
618
619 /* Ascent and height of the last line processed by move_it_to. */
620
621 static int last_max_ascent, last_height;
622
623 /* Non-zero if there's a help-echo in the echo area. */
624
625 int help_echo_showing_p;
626
627 /* If >= 0, computed, exact values of mode-line and header-line height
628 to use in the macros CURRENT_MODE_LINE_HEIGHT and
629 CURRENT_HEADER_LINE_HEIGHT. */
630
631 int current_mode_line_height, current_header_line_height;
632
633 /* The maximum distance to look ahead for text properties. Values
634 that are too small let us call compute_char_face and similar
635 functions too often which is expensive. Values that are too large
636 let us call compute_char_face and alike too often because we
637 might not be interested in text properties that far away. */
638
639 #define TEXT_PROP_DISTANCE_LIMIT 100
640
641 #if GLYPH_DEBUG
642
643 /* Variables to turn off display optimizations from Lisp. */
644
645 int inhibit_try_window_id, inhibit_try_window_reusing;
646 int inhibit_try_cursor_movement;
647
648 /* Non-zero means print traces of redisplay if compiled with
649 GLYPH_DEBUG != 0. */
650
651 int trace_redisplay_p;
652
653 #endif /* GLYPH_DEBUG */
654
655 #ifdef DEBUG_TRACE_MOVE
656 /* Non-zero means trace with TRACE_MOVE to stderr. */
657 int trace_move;
658
659 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
660 #else
661 #define TRACE_MOVE(x) (void) 0
662 #endif
663
664 /* Non-zero means automatically scroll windows horizontally to make
665 point visible. */
666
667 int automatic_hscrolling_p;
668
669 /* How close to the margin can point get before the window is scrolled
670 horizontally. */
671 EMACS_INT hscroll_margin;
672
673 /* How much to scroll horizontally when point is inside the above margin. */
674 Lisp_Object Vhscroll_step;
675
676 /* The variable `resize-mini-windows'. If nil, don't resize
677 mini-windows. If t, always resize them to fit the text they
678 display. If `grow-only', let mini-windows grow only until they
679 become empty. */
680
681 Lisp_Object Vresize_mini_windows;
682
683 /* Buffer being redisplayed -- for redisplay_window_error. */
684
685 struct buffer *displayed_buffer;
686
687 /* Value returned from text property handlers (see below). */
688
689 enum prop_handled
690 {
691 HANDLED_NORMALLY,
692 HANDLED_RECOMPUTE_PROPS,
693 HANDLED_OVERLAY_STRING_CONSUMED,
694 HANDLED_RETURN
695 };
696
697 /* A description of text properties that redisplay is interested
698 in. */
699
700 struct props
701 {
702 /* The name of the property. */
703 Lisp_Object *name;
704
705 /* A unique index for the property. */
706 enum prop_idx idx;
707
708 /* A handler function called to set up iterator IT from the property
709 at IT's current position. Value is used to steer handle_stop. */
710 enum prop_handled (*handler) P_ ((struct it *it));
711 };
712
713 static enum prop_handled handle_face_prop P_ ((struct it *));
714 static enum prop_handled handle_invisible_prop P_ ((struct it *));
715 static enum prop_handled handle_display_prop P_ ((struct it *));
716 static enum prop_handled handle_composition_prop P_ ((struct it *));
717 static enum prop_handled handle_overlay_change P_ ((struct it *));
718 static enum prop_handled handle_fontified_prop P_ ((struct it *));
719
720 /* Properties handled by iterators. */
721
722 static struct props it_props[] =
723 {
724 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
725 /* Handle `face' before `display' because some sub-properties of
726 `display' need to know the face. */
727 {&Qface, FACE_PROP_IDX, handle_face_prop},
728 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
729 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
730 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
731 {NULL, 0, NULL}
732 };
733
734 /* Value is the position described by X. If X is a marker, value is
735 the marker_position of X. Otherwise, value is X. */
736
737 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
738
739 /* Enumeration returned by some move_it_.* functions internally. */
740
741 enum move_it_result
742 {
743 /* Not used. Undefined value. */
744 MOVE_UNDEFINED,
745
746 /* Move ended at the requested buffer position or ZV. */
747 MOVE_POS_MATCH_OR_ZV,
748
749 /* Move ended at the requested X pixel position. */
750 MOVE_X_REACHED,
751
752 /* Move within a line ended at the end of a line that must be
753 continued. */
754 MOVE_LINE_CONTINUED,
755
756 /* Move within a line ended at the end of a line that would
757 be displayed truncated. */
758 MOVE_LINE_TRUNCATED,
759
760 /* Move within a line ended at a line end. */
761 MOVE_NEWLINE_OR_CR
762 };
763
764 /* This counter is used to clear the face cache every once in a while
765 in redisplay_internal. It is incremented for each redisplay.
766 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
767 cleared. */
768
769 #define CLEAR_FACE_CACHE_COUNT 500
770 static int clear_face_cache_count;
771
772 /* Record the previous terminal frame we displayed. */
773
774 static struct frame *previous_terminal_frame;
775
776 /* Non-zero while redisplay_internal is in progress. */
777
778 int redisplaying_p;
779
780 /* Non-zero means don't free realized faces. Bound while freeing
781 realized faces is dangerous because glyph matrices might still
782 reference them. */
783
784 int inhibit_free_realized_faces;
785 Lisp_Object Qinhibit_free_realized_faces;
786
787 /* If a string, XTread_socket generates an event to display that string.
788 (The display is done in read_char.) */
789
790 Lisp_Object help_echo_string;
791 Lisp_Object help_echo_window;
792 Lisp_Object help_echo_object;
793 int help_echo_pos;
794
795 /* Temporary variable for XTread_socket. */
796
797 Lisp_Object previous_help_echo_string;
798
799 /* Null glyph slice */
800
801 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
802
803 \f
804 /* Function prototypes. */
805
806 static void setup_for_ellipsis P_ ((struct it *));
807 static void mark_window_display_accurate_1 P_ ((struct window *, int));
808 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
809 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
810 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
811 static int redisplay_mode_lines P_ ((Lisp_Object, int));
812 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
813
814 #if 0
815 static int invisible_text_between_p P_ ((struct it *, int, int));
816 #endif
817
818 static int next_element_from_ellipsis P_ ((struct it *));
819 static void pint2str P_ ((char *, int, int));
820 static void pint2hrstr P_ ((char *, int, int));
821 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
822 struct text_pos));
823 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
824 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
825 static void store_frame_title_char P_ ((char));
826 static int store_frame_title P_ ((const unsigned char *, int, int));
827 static void x_consider_frame_title P_ ((Lisp_Object));
828 static void handle_stop P_ ((struct it *));
829 static int tool_bar_lines_needed P_ ((struct frame *));
830 static int single_display_prop_intangible_p P_ ((Lisp_Object));
831 static void ensure_echo_area_buffers P_ ((void));
832 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
833 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
834 static int with_echo_area_buffer P_ ((struct window *, int,
835 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
836 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static void clear_garbaged_frames P_ ((void));
838 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
839 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
840 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
841 static int display_echo_area P_ ((struct window *));
842 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
843 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
844 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
845 static int string_char_and_length P_ ((const unsigned char *, int, int *));
846 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
847 struct text_pos));
848 static int compute_window_start_on_continuation_line P_ ((struct window *));
849 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
850 static void insert_left_trunc_glyphs P_ ((struct it *));
851 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
852 Lisp_Object));
853 static void extend_face_to_end_of_line P_ ((struct it *));
854 static int append_space_for_newline P_ ((struct it *, int));
855 static int make_cursor_line_fully_visible P_ ((struct window *, int));
856 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
857 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
858 static int trailing_whitespace_p P_ ((int));
859 static int message_log_check_duplicate P_ ((int, int, int, int));
860 static void push_it P_ ((struct it *));
861 static void pop_it P_ ((struct it *));
862 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
863 static void select_frame_for_redisplay P_ ((Lisp_Object));
864 static void redisplay_internal P_ ((int));
865 static int echo_area_display P_ ((int));
866 static void redisplay_windows P_ ((Lisp_Object));
867 static void redisplay_window P_ ((Lisp_Object, int));
868 static Lisp_Object redisplay_window_error ();
869 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
870 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
871 static void update_menu_bar P_ ((struct frame *, int));
872 static int try_window_reusing_current_matrix P_ ((struct window *));
873 static int try_window_id P_ ((struct window *));
874 static int display_line P_ ((struct it *));
875 static int display_mode_lines P_ ((struct window *));
876 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
877 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
878 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
879 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
880 static void display_menu_bar P_ ((struct window *));
881 static int display_count_lines P_ ((int, int, int, int, int *));
882 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
883 int, int, struct it *, int, int, int, int));
884 static void compute_line_metrics P_ ((struct it *));
885 static void run_redisplay_end_trigger_hook P_ ((struct it *));
886 static int get_overlay_strings P_ ((struct it *, int));
887 static void next_overlay_string P_ ((struct it *));
888 static void reseat P_ ((struct it *, struct text_pos, int));
889 static void reseat_1 P_ ((struct it *, struct text_pos, int));
890 static void back_to_previous_visible_line_start P_ ((struct it *));
891 static void reseat_at_previous_visible_line_start P_ ((struct it *));
892 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
893 static int next_element_from_display_vector P_ ((struct it *));
894 static int next_element_from_string P_ ((struct it *));
895 static int next_element_from_c_string P_ ((struct it *));
896 static int next_element_from_buffer P_ ((struct it *));
897 static int next_element_from_composition P_ ((struct it *));
898 static int next_element_from_image P_ ((struct it *));
899 static int next_element_from_stretch P_ ((struct it *));
900 static void load_overlay_strings P_ ((struct it *, int));
901 static int init_from_display_pos P_ ((struct it *, struct window *,
902 struct display_pos *));
903 static void reseat_to_string P_ ((struct it *, unsigned char *,
904 Lisp_Object, int, int, int, int));
905 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
906 int, int, int));
907 void move_it_vertically_backward P_ ((struct it *, int));
908 static void init_to_row_start P_ ((struct it *, struct window *,
909 struct glyph_row *));
910 static int init_to_row_end P_ ((struct it *, struct window *,
911 struct glyph_row *));
912 static void back_to_previous_line_start P_ ((struct it *));
913 static int forward_to_next_line_start P_ ((struct it *, int *));
914 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
915 Lisp_Object, int));
916 static struct text_pos string_pos P_ ((int, Lisp_Object));
917 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
918 static int number_of_chars P_ ((unsigned char *, int));
919 static void compute_stop_pos P_ ((struct it *));
920 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
921 Lisp_Object));
922 static int face_before_or_after_it_pos P_ ((struct it *, int));
923 static int next_overlay_change P_ ((int));
924 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
925 Lisp_Object, struct text_pos *,
926 int));
927 static int underlying_face_id P_ ((struct it *));
928 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
929 struct window *));
930
931 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
932 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
933
934 #ifdef HAVE_WINDOW_SYSTEM
935
936 static void update_tool_bar P_ ((struct frame *, int));
937 static void build_desired_tool_bar_string P_ ((struct frame *f));
938 static int redisplay_tool_bar P_ ((struct frame *));
939 static void display_tool_bar_line P_ ((struct it *));
940 static void notice_overwritten_cursor P_ ((struct window *,
941 enum glyph_row_area,
942 int, int, int, int));
943
944
945
946 #endif /* HAVE_WINDOW_SYSTEM */
947
948 \f
949 /***********************************************************************
950 Window display dimensions
951 ***********************************************************************/
952
953 /* Return the bottom boundary y-position for text lines in window W.
954 This is the first y position at which a line cannot start.
955 It is relative to the top of the window.
956
957 This is the height of W minus the height of a mode line, if any. */
958
959 INLINE int
960 window_text_bottom_y (w)
961 struct window *w;
962 {
963 int height = WINDOW_TOTAL_HEIGHT (w);
964
965 if (WINDOW_WANTS_MODELINE_P (w))
966 height -= CURRENT_MODE_LINE_HEIGHT (w);
967 return height;
968 }
969
970 /* Return the pixel width of display area AREA of window W. AREA < 0
971 means return the total width of W, not including fringes to
972 the left and right of the window. */
973
974 INLINE int
975 window_box_width (w, area)
976 struct window *w;
977 int area;
978 {
979 int cols = XFASTINT (w->total_cols);
980 int pixels = 0;
981
982 if (!w->pseudo_window_p)
983 {
984 cols -= WINDOW_SCROLL_BAR_COLS (w);
985
986 if (area == TEXT_AREA)
987 {
988 if (INTEGERP (w->left_margin_cols))
989 cols -= XFASTINT (w->left_margin_cols);
990 if (INTEGERP (w->right_margin_cols))
991 cols -= XFASTINT (w->right_margin_cols);
992 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
993 }
994 else if (area == LEFT_MARGIN_AREA)
995 {
996 cols = (INTEGERP (w->left_margin_cols)
997 ? XFASTINT (w->left_margin_cols) : 0);
998 pixels = 0;
999 }
1000 else if (area == RIGHT_MARGIN_AREA)
1001 {
1002 cols = (INTEGERP (w->right_margin_cols)
1003 ? XFASTINT (w->right_margin_cols) : 0);
1004 pixels = 0;
1005 }
1006 }
1007
1008 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1009 }
1010
1011
1012 /* Return the pixel height of the display area of window W, not
1013 including mode lines of W, if any. */
1014
1015 INLINE int
1016 window_box_height (w)
1017 struct window *w;
1018 {
1019 struct frame *f = XFRAME (w->frame);
1020 int height = WINDOW_TOTAL_HEIGHT (w);
1021
1022 xassert (height >= 0);
1023
1024 /* Note: the code below that determines the mode-line/header-line
1025 height is essentially the same as that contained in the macro
1026 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1027 the appropriate glyph row has its `mode_line_p' flag set,
1028 and if it doesn't, uses estimate_mode_line_height instead. */
1029
1030 if (WINDOW_WANTS_MODELINE_P (w))
1031 {
1032 struct glyph_row *ml_row
1033 = (w->current_matrix && w->current_matrix->rows
1034 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1035 : 0);
1036 if (ml_row && ml_row->mode_line_p)
1037 height -= ml_row->height;
1038 else
1039 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1040 }
1041
1042 if (WINDOW_WANTS_HEADER_LINE_P (w))
1043 {
1044 struct glyph_row *hl_row
1045 = (w->current_matrix && w->current_matrix->rows
1046 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1047 : 0);
1048 if (hl_row && hl_row->mode_line_p)
1049 height -= hl_row->height;
1050 else
1051 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1052 }
1053
1054 /* With a very small font and a mode-line that's taller than
1055 default, we might end up with a negative height. */
1056 return max (0, height);
1057 }
1058
1059 /* Return the window-relative coordinate of the left edge of display
1060 area AREA of window W. AREA < 0 means return the left edge of the
1061 whole window, to the right of the left fringe of W. */
1062
1063 INLINE int
1064 window_box_left_offset (w, area)
1065 struct window *w;
1066 int area;
1067 {
1068 int x;
1069
1070 if (w->pseudo_window_p)
1071 return 0;
1072
1073 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1074
1075 if (area == TEXT_AREA)
1076 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1077 + window_box_width (w, LEFT_MARGIN_AREA));
1078 else if (area == RIGHT_MARGIN_AREA)
1079 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1080 + window_box_width (w, LEFT_MARGIN_AREA)
1081 + window_box_width (w, TEXT_AREA)
1082 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1083 ? 0
1084 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1085 else if (area == LEFT_MARGIN_AREA
1086 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1087 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1088
1089 return x;
1090 }
1091
1092
1093 /* Return the window-relative coordinate of the right edge of display
1094 area AREA of window W. AREA < 0 means return the left edge of the
1095 whole window, to the left of the right fringe of W. */
1096
1097 INLINE int
1098 window_box_right_offset (w, area)
1099 struct window *w;
1100 int area;
1101 {
1102 return window_box_left_offset (w, area) + window_box_width (w, area);
1103 }
1104
1105 /* Return the frame-relative coordinate of the left edge of display
1106 area AREA of window W. AREA < 0 means return the left edge of the
1107 whole window, to the right of the left fringe of W. */
1108
1109 INLINE int
1110 window_box_left (w, area)
1111 struct window *w;
1112 int area;
1113 {
1114 struct frame *f = XFRAME (w->frame);
1115 int x;
1116
1117 if (w->pseudo_window_p)
1118 return FRAME_INTERNAL_BORDER_WIDTH (f);
1119
1120 x = (WINDOW_LEFT_EDGE_X (w)
1121 + window_box_left_offset (w, area));
1122
1123 return x;
1124 }
1125
1126
1127 /* Return the frame-relative coordinate of the right edge of display
1128 area AREA of window W. AREA < 0 means return the left edge of the
1129 whole window, to the left of the right fringe of W. */
1130
1131 INLINE int
1132 window_box_right (w, area)
1133 struct window *w;
1134 int area;
1135 {
1136 return window_box_left (w, area) + window_box_width (w, area);
1137 }
1138
1139 /* Get the bounding box of the display area AREA of window W, without
1140 mode lines, in frame-relative coordinates. AREA < 0 means the
1141 whole window, not including the left and right fringes of
1142 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1143 coordinates of the upper-left corner of the box. Return in
1144 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1145
1146 INLINE void
1147 window_box (w, area, box_x, box_y, box_width, box_height)
1148 struct window *w;
1149 int area;
1150 int *box_x, *box_y, *box_width, *box_height;
1151 {
1152 if (box_width)
1153 *box_width = window_box_width (w, area);
1154 if (box_height)
1155 *box_height = window_box_height (w);
1156 if (box_x)
1157 *box_x = window_box_left (w, area);
1158 if (box_y)
1159 {
1160 *box_y = WINDOW_TOP_EDGE_Y (w);
1161 if (WINDOW_WANTS_HEADER_LINE_P (w))
1162 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1163 }
1164 }
1165
1166
1167 /* Get the bounding box of the display area AREA of window W, without
1168 mode lines. AREA < 0 means the whole window, not including the
1169 left and right fringe of the window. Return in *TOP_LEFT_X
1170 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1171 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1172 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1173 box. */
1174
1175 INLINE void
1176 window_box_edges (w, area, top_left_x, top_left_y,
1177 bottom_right_x, bottom_right_y)
1178 struct window *w;
1179 int area;
1180 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1181 {
1182 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1183 bottom_right_y);
1184 *bottom_right_x += *top_left_x;
1185 *bottom_right_y += *top_left_y;
1186 }
1187
1188
1189 \f
1190 /***********************************************************************
1191 Utilities
1192 ***********************************************************************/
1193
1194 /* Return the bottom y-position of the line the iterator IT is in.
1195 This can modify IT's settings. */
1196
1197 int
1198 line_bottom_y (it)
1199 struct it *it;
1200 {
1201 int line_height = it->max_ascent + it->max_descent;
1202 int line_top_y = it->current_y;
1203
1204 if (line_height == 0)
1205 {
1206 if (last_height)
1207 line_height = last_height;
1208 else if (IT_CHARPOS (*it) < ZV)
1209 {
1210 move_it_by_lines (it, 1, 1);
1211 line_height = (it->max_ascent || it->max_descent
1212 ? it->max_ascent + it->max_descent
1213 : last_height);
1214 }
1215 else
1216 {
1217 struct glyph_row *row = it->glyph_row;
1218
1219 /* Use the default character height. */
1220 it->glyph_row = NULL;
1221 it->what = IT_CHARACTER;
1222 it->c = ' ';
1223 it->len = 1;
1224 PRODUCE_GLYPHS (it);
1225 line_height = it->ascent + it->descent;
1226 it->glyph_row = row;
1227 }
1228 }
1229
1230 return line_top_y + line_height;
1231 }
1232
1233
1234 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1235 1 if POS is visible and the line containing POS is fully visible.
1236 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1237 and header-lines heights. */
1238
1239 int
1240 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1241 struct window *w;
1242 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1243 {
1244 struct it it;
1245 struct text_pos top;
1246 int visible_p;
1247 struct buffer *old_buffer = NULL;
1248
1249 if (XBUFFER (w->buffer) != current_buffer)
1250 {
1251 old_buffer = current_buffer;
1252 set_buffer_internal_1 (XBUFFER (w->buffer));
1253 }
1254
1255 *fully = visible_p = 0;
1256 SET_TEXT_POS_FROM_MARKER (top, w->start);
1257
1258 /* Compute exact mode line heights, if requested. */
1259 if (exact_mode_line_heights_p)
1260 {
1261 if (WINDOW_WANTS_MODELINE_P (w))
1262 current_mode_line_height
1263 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1264 current_buffer->mode_line_format);
1265
1266 if (WINDOW_WANTS_HEADER_LINE_P (w))
1267 current_header_line_height
1268 = display_mode_line (w, HEADER_LINE_FACE_ID,
1269 current_buffer->header_line_format);
1270 }
1271
1272 start_display (&it, w, top);
1273 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1274 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1275
1276 /* Note that we may overshoot because of invisible text. */
1277 if (IT_CHARPOS (it) >= charpos)
1278 {
1279 int top_y = it.current_y;
1280 int bottom_y = line_bottom_y (&it);
1281 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1282
1283 if (top_y < window_top_y)
1284 visible_p = bottom_y > window_top_y;
1285 else if (top_y < it.last_visible_y)
1286 {
1287 visible_p = 1;
1288 *fully = bottom_y <= it.last_visible_y;
1289 }
1290 if (visible_p && x)
1291 {
1292 *x = it.current_x;
1293 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1294 }
1295 }
1296 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1297 {
1298 struct it it2;
1299
1300 it2 = it;
1301 move_it_by_lines (&it, 1, 0);
1302 if (charpos < IT_CHARPOS (it))
1303 {
1304 visible_p = 1;
1305 if (x)
1306 {
1307 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1308 *x = it2.current_x;
1309 *y = it2.current_y + it2.max_ascent - it2.ascent;
1310 }
1311 }
1312 }
1313
1314 if (old_buffer)
1315 set_buffer_internal_1 (old_buffer);
1316
1317 current_header_line_height = current_mode_line_height = -1;
1318
1319 return visible_p;
1320 }
1321
1322
1323 /* Return the next character from STR which is MAXLEN bytes long.
1324 Return in *LEN the length of the character. This is like
1325 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1326 we find one, we return a `?', but with the length of the invalid
1327 character. */
1328
1329 static INLINE int
1330 string_char_and_length (str, maxlen, len)
1331 const unsigned char *str;
1332 int maxlen, *len;
1333 {
1334 int c;
1335
1336 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1337 if (!CHAR_VALID_P (c, 1))
1338 /* We may not change the length here because other places in Emacs
1339 don't use this function, i.e. they silently accept invalid
1340 characters. */
1341 c = '?';
1342
1343 return c;
1344 }
1345
1346
1347
1348 /* Given a position POS containing a valid character and byte position
1349 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1350
1351 static struct text_pos
1352 string_pos_nchars_ahead (pos, string, nchars)
1353 struct text_pos pos;
1354 Lisp_Object string;
1355 int nchars;
1356 {
1357 xassert (STRINGP (string) && nchars >= 0);
1358
1359 if (STRING_MULTIBYTE (string))
1360 {
1361 int rest = SBYTES (string) - BYTEPOS (pos);
1362 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1363 int len;
1364
1365 while (nchars--)
1366 {
1367 string_char_and_length (p, rest, &len);
1368 p += len, rest -= len;
1369 xassert (rest >= 0);
1370 CHARPOS (pos) += 1;
1371 BYTEPOS (pos) += len;
1372 }
1373 }
1374 else
1375 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1376
1377 return pos;
1378 }
1379
1380
1381 /* Value is the text position, i.e. character and byte position,
1382 for character position CHARPOS in STRING. */
1383
1384 static INLINE struct text_pos
1385 string_pos (charpos, string)
1386 int charpos;
1387 Lisp_Object string;
1388 {
1389 struct text_pos pos;
1390 xassert (STRINGP (string));
1391 xassert (charpos >= 0);
1392 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1393 return pos;
1394 }
1395
1396
1397 /* Value is a text position, i.e. character and byte position, for
1398 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1399 means recognize multibyte characters. */
1400
1401 static struct text_pos
1402 c_string_pos (charpos, s, multibyte_p)
1403 int charpos;
1404 unsigned char *s;
1405 int multibyte_p;
1406 {
1407 struct text_pos pos;
1408
1409 xassert (s != NULL);
1410 xassert (charpos >= 0);
1411
1412 if (multibyte_p)
1413 {
1414 int rest = strlen (s), len;
1415
1416 SET_TEXT_POS (pos, 0, 0);
1417 while (charpos--)
1418 {
1419 string_char_and_length (s, rest, &len);
1420 s += len, rest -= len;
1421 xassert (rest >= 0);
1422 CHARPOS (pos) += 1;
1423 BYTEPOS (pos) += len;
1424 }
1425 }
1426 else
1427 SET_TEXT_POS (pos, charpos, charpos);
1428
1429 return pos;
1430 }
1431
1432
1433 /* Value is the number of characters in C string S. MULTIBYTE_P
1434 non-zero means recognize multibyte characters. */
1435
1436 static int
1437 number_of_chars (s, multibyte_p)
1438 unsigned char *s;
1439 int multibyte_p;
1440 {
1441 int nchars;
1442
1443 if (multibyte_p)
1444 {
1445 int rest = strlen (s), len;
1446 unsigned char *p = (unsigned char *) s;
1447
1448 for (nchars = 0; rest > 0; ++nchars)
1449 {
1450 string_char_and_length (p, rest, &len);
1451 rest -= len, p += len;
1452 }
1453 }
1454 else
1455 nchars = strlen (s);
1456
1457 return nchars;
1458 }
1459
1460
1461 /* Compute byte position NEWPOS->bytepos corresponding to
1462 NEWPOS->charpos. POS is a known position in string STRING.
1463 NEWPOS->charpos must be >= POS.charpos. */
1464
1465 static void
1466 compute_string_pos (newpos, pos, string)
1467 struct text_pos *newpos, pos;
1468 Lisp_Object string;
1469 {
1470 xassert (STRINGP (string));
1471 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1472
1473 if (STRING_MULTIBYTE (string))
1474 *newpos = string_pos_nchars_ahead (pos, string,
1475 CHARPOS (*newpos) - CHARPOS (pos));
1476 else
1477 BYTEPOS (*newpos) = CHARPOS (*newpos);
1478 }
1479
1480 /* EXPORT:
1481 Return an estimation of the pixel height of mode or top lines on
1482 frame F. FACE_ID specifies what line's height to estimate. */
1483
1484 int
1485 estimate_mode_line_height (f, face_id)
1486 struct frame *f;
1487 enum face_id face_id;
1488 {
1489 #ifdef HAVE_WINDOW_SYSTEM
1490 if (FRAME_WINDOW_P (f))
1491 {
1492 int height = FONT_HEIGHT (FRAME_FONT (f));
1493
1494 /* This function is called so early when Emacs starts that the face
1495 cache and mode line face are not yet initialized. */
1496 if (FRAME_FACE_CACHE (f))
1497 {
1498 struct face *face = FACE_FROM_ID (f, face_id);
1499 if (face)
1500 {
1501 if (face->font)
1502 height = FONT_HEIGHT (face->font);
1503 if (face->box_line_width > 0)
1504 height += 2 * face->box_line_width;
1505 }
1506 }
1507
1508 return height;
1509 }
1510 #endif
1511
1512 return 1;
1513 }
1514
1515 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1516 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1517 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1518 not force the value into range. */
1519
1520 void
1521 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1522 FRAME_PTR f;
1523 register int pix_x, pix_y;
1524 int *x, *y;
1525 NativeRectangle *bounds;
1526 int noclip;
1527 {
1528
1529 #ifdef HAVE_WINDOW_SYSTEM
1530 if (FRAME_WINDOW_P (f))
1531 {
1532 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1533 even for negative values. */
1534 if (pix_x < 0)
1535 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1536 if (pix_y < 0)
1537 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1538
1539 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1540 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1541
1542 if (bounds)
1543 STORE_NATIVE_RECT (*bounds,
1544 FRAME_COL_TO_PIXEL_X (f, pix_x),
1545 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1546 FRAME_COLUMN_WIDTH (f) - 1,
1547 FRAME_LINE_HEIGHT (f) - 1);
1548
1549 if (!noclip)
1550 {
1551 if (pix_x < 0)
1552 pix_x = 0;
1553 else if (pix_x > FRAME_TOTAL_COLS (f))
1554 pix_x = FRAME_TOTAL_COLS (f);
1555
1556 if (pix_y < 0)
1557 pix_y = 0;
1558 else if (pix_y > FRAME_LINES (f))
1559 pix_y = FRAME_LINES (f);
1560 }
1561 }
1562 #endif
1563
1564 *x = pix_x;
1565 *y = pix_y;
1566 }
1567
1568
1569 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1570 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1571 can't tell the positions because W's display is not up to date,
1572 return 0. */
1573
1574 int
1575 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1576 struct window *w;
1577 int hpos, vpos;
1578 int *frame_x, *frame_y;
1579 {
1580 #ifdef HAVE_WINDOW_SYSTEM
1581 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1582 {
1583 int success_p;
1584
1585 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1586 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1587
1588 if (display_completed)
1589 {
1590 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1591 struct glyph *glyph = row->glyphs[TEXT_AREA];
1592 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1593
1594 hpos = row->x;
1595 vpos = row->y;
1596 while (glyph < end)
1597 {
1598 hpos += glyph->pixel_width;
1599 ++glyph;
1600 }
1601
1602 /* If first glyph is partially visible, its first visible position is still 0. */
1603 if (hpos < 0)
1604 hpos = 0;
1605
1606 success_p = 1;
1607 }
1608 else
1609 {
1610 hpos = vpos = 0;
1611 success_p = 0;
1612 }
1613
1614 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1615 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1616 return success_p;
1617 }
1618 #endif
1619
1620 *frame_x = hpos;
1621 *frame_y = vpos;
1622 return 1;
1623 }
1624
1625
1626 #ifdef HAVE_WINDOW_SYSTEM
1627
1628 /* Find the glyph under window-relative coordinates X/Y in window W.
1629 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1630 strings. Return in *HPOS and *VPOS the row and column number of
1631 the glyph found. Return in *AREA the glyph area containing X.
1632 Value is a pointer to the glyph found or null if X/Y is not on
1633 text, or we can't tell because W's current matrix is not up to
1634 date. */
1635
1636 static struct glyph *
1637 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1638 struct window *w;
1639 int x, y;
1640 int *hpos, *vpos, *dx, *dy, *area;
1641 {
1642 struct glyph *glyph, *end;
1643 struct glyph_row *row = NULL;
1644 int x0, i;
1645
1646 /* Find row containing Y. Give up if some row is not enabled. */
1647 for (i = 0; i < w->current_matrix->nrows; ++i)
1648 {
1649 row = MATRIX_ROW (w->current_matrix, i);
1650 if (!row->enabled_p)
1651 return NULL;
1652 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1653 break;
1654 }
1655
1656 *vpos = i;
1657 *hpos = 0;
1658
1659 /* Give up if Y is not in the window. */
1660 if (i == w->current_matrix->nrows)
1661 return NULL;
1662
1663 /* Get the glyph area containing X. */
1664 if (w->pseudo_window_p)
1665 {
1666 *area = TEXT_AREA;
1667 x0 = 0;
1668 }
1669 else
1670 {
1671 if (x < window_box_left_offset (w, TEXT_AREA))
1672 {
1673 *area = LEFT_MARGIN_AREA;
1674 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1675 }
1676 else if (x < window_box_right_offset (w, TEXT_AREA))
1677 {
1678 *area = TEXT_AREA;
1679 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1680 }
1681 else
1682 {
1683 *area = RIGHT_MARGIN_AREA;
1684 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1685 }
1686 }
1687
1688 /* Find glyph containing X. */
1689 glyph = row->glyphs[*area];
1690 end = glyph + row->used[*area];
1691 x -= x0;
1692 while (glyph < end && x >= glyph->pixel_width)
1693 {
1694 x -= glyph->pixel_width;
1695 ++glyph;
1696 }
1697
1698 if (glyph == end)
1699 return NULL;
1700
1701 if (dx)
1702 {
1703 *dx = x;
1704 *dy = y - (row->y + row->ascent - glyph->ascent);
1705 }
1706
1707 *hpos = glyph - row->glyphs[*area];
1708 return glyph;
1709 }
1710
1711
1712 /* EXPORT:
1713 Convert frame-relative x/y to coordinates relative to window W.
1714 Takes pseudo-windows into account. */
1715
1716 void
1717 frame_to_window_pixel_xy (w, x, y)
1718 struct window *w;
1719 int *x, *y;
1720 {
1721 if (w->pseudo_window_p)
1722 {
1723 /* A pseudo-window is always full-width, and starts at the
1724 left edge of the frame, plus a frame border. */
1725 struct frame *f = XFRAME (w->frame);
1726 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1727 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1728 }
1729 else
1730 {
1731 *x -= WINDOW_LEFT_EDGE_X (w);
1732 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1733 }
1734 }
1735
1736 /* EXPORT:
1737 Return in *R the clipping rectangle for glyph string S. */
1738
1739 void
1740 get_glyph_string_clip_rect (s, nr)
1741 struct glyph_string *s;
1742 NativeRectangle *nr;
1743 {
1744 XRectangle r;
1745
1746 if (s->row->full_width_p)
1747 {
1748 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1749 r.x = WINDOW_LEFT_EDGE_X (s->w);
1750 r.width = WINDOW_TOTAL_WIDTH (s->w);
1751
1752 /* Unless displaying a mode or menu bar line, which are always
1753 fully visible, clip to the visible part of the row. */
1754 if (s->w->pseudo_window_p)
1755 r.height = s->row->visible_height;
1756 else
1757 r.height = s->height;
1758 }
1759 else
1760 {
1761 /* This is a text line that may be partially visible. */
1762 r.x = window_box_left (s->w, s->area);
1763 r.width = window_box_width (s->w, s->area);
1764 r.height = s->row->visible_height;
1765 }
1766
1767 /* If S draws overlapping rows, it's sufficient to use the top and
1768 bottom of the window for clipping because this glyph string
1769 intentionally draws over other lines. */
1770 if (s->for_overlaps_p)
1771 {
1772 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1773 r.height = window_text_bottom_y (s->w) - r.y;
1774 }
1775 else
1776 {
1777 /* Don't use S->y for clipping because it doesn't take partially
1778 visible lines into account. For example, it can be negative for
1779 partially visible lines at the top of a window. */
1780 if (!s->row->full_width_p
1781 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1782 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1783 else
1784 r.y = max (0, s->row->y);
1785
1786 /* If drawing a tool-bar window, draw it over the internal border
1787 at the top of the window. */
1788 if (s->w == XWINDOW (s->f->tool_bar_window))
1789 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1790 }
1791
1792 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1793
1794 /* If drawing the cursor, don't let glyph draw outside its
1795 advertised boundaries. Cleartype does this under some circumstances. */
1796 if (s->hl == DRAW_CURSOR)
1797 {
1798 struct glyph *glyph = s->first_glyph;
1799 int height;
1800
1801 if (s->x > r.x)
1802 {
1803 r.width -= s->x - r.x;
1804 r.x = s->x;
1805 }
1806 r.width = min (r.width, glyph->pixel_width);
1807
1808 /* Don't draw cursor glyph taller than our actual glyph. */
1809 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1810 if (height < r.height)
1811 {
1812 int max_y = r.y + r.height;
1813 r.y = min (max_y, s->ybase + glyph->descent - height);
1814 r.height = min (max_y - r.y, height);
1815 }
1816 }
1817
1818 #ifdef CONVERT_FROM_XRECT
1819 CONVERT_FROM_XRECT (r, *nr);
1820 #else
1821 *nr = r;
1822 #endif
1823 }
1824
1825 #endif /* HAVE_WINDOW_SYSTEM */
1826
1827 \f
1828 /***********************************************************************
1829 Lisp form evaluation
1830 ***********************************************************************/
1831
1832 /* Error handler for safe_eval and safe_call. */
1833
1834 static Lisp_Object
1835 safe_eval_handler (arg)
1836 Lisp_Object arg;
1837 {
1838 add_to_log ("Error during redisplay: %s", arg, Qnil);
1839 return Qnil;
1840 }
1841
1842
1843 /* Evaluate SEXPR and return the result, or nil if something went
1844 wrong. Prevent redisplay during the evaluation. */
1845
1846 Lisp_Object
1847 safe_eval (sexpr)
1848 Lisp_Object sexpr;
1849 {
1850 Lisp_Object val;
1851
1852 if (inhibit_eval_during_redisplay)
1853 val = Qnil;
1854 else
1855 {
1856 int count = SPECPDL_INDEX ();
1857 struct gcpro gcpro1;
1858
1859 GCPRO1 (sexpr);
1860 specbind (Qinhibit_redisplay, Qt);
1861 /* Use Qt to ensure debugger does not run,
1862 so there is no possibility of wanting to redisplay. */
1863 val = internal_condition_case_1 (Feval, sexpr, Qt,
1864 safe_eval_handler);
1865 UNGCPRO;
1866 val = unbind_to (count, val);
1867 }
1868
1869 return val;
1870 }
1871
1872
1873 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1874 Return the result, or nil if something went wrong. Prevent
1875 redisplay during the evaluation. */
1876
1877 Lisp_Object
1878 safe_call (nargs, args)
1879 int nargs;
1880 Lisp_Object *args;
1881 {
1882 Lisp_Object val;
1883
1884 if (inhibit_eval_during_redisplay)
1885 val = Qnil;
1886 else
1887 {
1888 int count = SPECPDL_INDEX ();
1889 struct gcpro gcpro1;
1890
1891 GCPRO1 (args[0]);
1892 gcpro1.nvars = nargs;
1893 specbind (Qinhibit_redisplay, Qt);
1894 /* Use Qt to ensure debugger does not run,
1895 so there is no possibility of wanting to redisplay. */
1896 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1897 safe_eval_handler);
1898 UNGCPRO;
1899 val = unbind_to (count, val);
1900 }
1901
1902 return val;
1903 }
1904
1905
1906 /* Call function FN with one argument ARG.
1907 Return the result, or nil if something went wrong. */
1908
1909 Lisp_Object
1910 safe_call1 (fn, arg)
1911 Lisp_Object fn, arg;
1912 {
1913 Lisp_Object args[2];
1914 args[0] = fn;
1915 args[1] = arg;
1916 return safe_call (2, args);
1917 }
1918
1919
1920 \f
1921 /***********************************************************************
1922 Debugging
1923 ***********************************************************************/
1924
1925 #if 0
1926
1927 /* Define CHECK_IT to perform sanity checks on iterators.
1928 This is for debugging. It is too slow to do unconditionally. */
1929
1930 static void
1931 check_it (it)
1932 struct it *it;
1933 {
1934 if (it->method == next_element_from_string)
1935 {
1936 xassert (STRINGP (it->string));
1937 xassert (IT_STRING_CHARPOS (*it) >= 0);
1938 }
1939 else
1940 {
1941 xassert (IT_STRING_CHARPOS (*it) < 0);
1942 if (it->method == next_element_from_buffer)
1943 {
1944 /* Check that character and byte positions agree. */
1945 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1946 }
1947 }
1948
1949 if (it->dpvec)
1950 xassert (it->current.dpvec_index >= 0);
1951 else
1952 xassert (it->current.dpvec_index < 0);
1953 }
1954
1955 #define CHECK_IT(IT) check_it ((IT))
1956
1957 #else /* not 0 */
1958
1959 #define CHECK_IT(IT) (void) 0
1960
1961 #endif /* not 0 */
1962
1963
1964 #if GLYPH_DEBUG
1965
1966 /* Check that the window end of window W is what we expect it
1967 to be---the last row in the current matrix displaying text. */
1968
1969 static void
1970 check_window_end (w)
1971 struct window *w;
1972 {
1973 if (!MINI_WINDOW_P (w)
1974 && !NILP (w->window_end_valid))
1975 {
1976 struct glyph_row *row;
1977 xassert ((row = MATRIX_ROW (w->current_matrix,
1978 XFASTINT (w->window_end_vpos)),
1979 !row->enabled_p
1980 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1981 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1982 }
1983 }
1984
1985 #define CHECK_WINDOW_END(W) check_window_end ((W))
1986
1987 #else /* not GLYPH_DEBUG */
1988
1989 #define CHECK_WINDOW_END(W) (void) 0
1990
1991 #endif /* not GLYPH_DEBUG */
1992
1993
1994 \f
1995 /***********************************************************************
1996 Iterator initialization
1997 ***********************************************************************/
1998
1999 /* Initialize IT for displaying current_buffer in window W, starting
2000 at character position CHARPOS. CHARPOS < 0 means that no buffer
2001 position is specified which is useful when the iterator is assigned
2002 a position later. BYTEPOS is the byte position corresponding to
2003 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2004
2005 If ROW is not null, calls to produce_glyphs with IT as parameter
2006 will produce glyphs in that row.
2007
2008 BASE_FACE_ID is the id of a base face to use. It must be one of
2009 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2010 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2011 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2012
2013 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2014 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2015 will be initialized to use the corresponding mode line glyph row of
2016 the desired matrix of W. */
2017
2018 void
2019 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2020 struct it *it;
2021 struct window *w;
2022 int charpos, bytepos;
2023 struct glyph_row *row;
2024 enum face_id base_face_id;
2025 {
2026 int highlight_region_p;
2027
2028 /* Some precondition checks. */
2029 xassert (w != NULL && it != NULL);
2030 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2031 && charpos <= ZV));
2032
2033 /* If face attributes have been changed since the last redisplay,
2034 free realized faces now because they depend on face definitions
2035 that might have changed. Don't free faces while there might be
2036 desired matrices pending which reference these faces. */
2037 if (face_change_count && !inhibit_free_realized_faces)
2038 {
2039 face_change_count = 0;
2040 free_all_realized_faces (Qnil);
2041 }
2042
2043 /* Use one of the mode line rows of W's desired matrix if
2044 appropriate. */
2045 if (row == NULL)
2046 {
2047 if (base_face_id == MODE_LINE_FACE_ID
2048 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2049 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2050 else if (base_face_id == HEADER_LINE_FACE_ID)
2051 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2052 }
2053
2054 /* Clear IT. */
2055 bzero (it, sizeof *it);
2056 it->current.overlay_string_index = -1;
2057 it->current.dpvec_index = -1;
2058 it->base_face_id = base_face_id;
2059 it->string = Qnil;
2060 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2061
2062 /* The window in which we iterate over current_buffer: */
2063 XSETWINDOW (it->window, w);
2064 it->w = w;
2065 it->f = XFRAME (w->frame);
2066
2067 /* Extra space between lines (on window systems only). */
2068 if (base_face_id == DEFAULT_FACE_ID
2069 && FRAME_WINDOW_P (it->f))
2070 {
2071 if (NATNUMP (current_buffer->extra_line_spacing))
2072 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2073 else if (FLOATP (current_buffer->extra_line_spacing))
2074 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2075 * FRAME_LINE_HEIGHT (it->f));
2076 else if (it->f->extra_line_spacing > 0)
2077 it->extra_line_spacing = it->f->extra_line_spacing;
2078 }
2079
2080 /* If realized faces have been removed, e.g. because of face
2081 attribute changes of named faces, recompute them. When running
2082 in batch mode, the face cache of Vterminal_frame is null. If
2083 we happen to get called, make a dummy face cache. */
2084 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2085 init_frame_faces (it->f);
2086 if (FRAME_FACE_CACHE (it->f)->used == 0)
2087 recompute_basic_faces (it->f);
2088
2089 /* Current value of the `slice', `space-width', and 'height' properties. */
2090 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2091 it->space_width = Qnil;
2092 it->font_height = Qnil;
2093 it->override_ascent = -1;
2094
2095 /* Are control characters displayed as `^C'? */
2096 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2097
2098 /* -1 means everything between a CR and the following line end
2099 is invisible. >0 means lines indented more than this value are
2100 invisible. */
2101 it->selective = (INTEGERP (current_buffer->selective_display)
2102 ? XFASTINT (current_buffer->selective_display)
2103 : (!NILP (current_buffer->selective_display)
2104 ? -1 : 0));
2105 it->selective_display_ellipsis_p
2106 = !NILP (current_buffer->selective_display_ellipses);
2107
2108 /* Display table to use. */
2109 it->dp = window_display_table (w);
2110
2111 /* Are multibyte characters enabled in current_buffer? */
2112 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2113
2114 /* Non-zero if we should highlight the region. */
2115 highlight_region_p
2116 = (!NILP (Vtransient_mark_mode)
2117 && !NILP (current_buffer->mark_active)
2118 && XMARKER (current_buffer->mark)->buffer != 0);
2119
2120 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2121 start and end of a visible region in window IT->w. Set both to
2122 -1 to indicate no region. */
2123 if (highlight_region_p
2124 /* Maybe highlight only in selected window. */
2125 && (/* Either show region everywhere. */
2126 highlight_nonselected_windows
2127 /* Or show region in the selected window. */
2128 || w == XWINDOW (selected_window)
2129 /* Or show the region if we are in the mini-buffer and W is
2130 the window the mini-buffer refers to. */
2131 || (MINI_WINDOW_P (XWINDOW (selected_window))
2132 && WINDOWP (minibuf_selected_window)
2133 && w == XWINDOW (minibuf_selected_window))))
2134 {
2135 int charpos = marker_position (current_buffer->mark);
2136 it->region_beg_charpos = min (PT, charpos);
2137 it->region_end_charpos = max (PT, charpos);
2138 }
2139 else
2140 it->region_beg_charpos = it->region_end_charpos = -1;
2141
2142 /* Get the position at which the redisplay_end_trigger hook should
2143 be run, if it is to be run at all. */
2144 if (MARKERP (w->redisplay_end_trigger)
2145 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2146 it->redisplay_end_trigger_charpos
2147 = marker_position (w->redisplay_end_trigger);
2148 else if (INTEGERP (w->redisplay_end_trigger))
2149 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2150
2151 /* Correct bogus values of tab_width. */
2152 it->tab_width = XINT (current_buffer->tab_width);
2153 if (it->tab_width <= 0 || it->tab_width > 1000)
2154 it->tab_width = 8;
2155
2156 /* Are lines in the display truncated? */
2157 it->truncate_lines_p
2158 = (base_face_id != DEFAULT_FACE_ID
2159 || XINT (it->w->hscroll)
2160 || (truncate_partial_width_windows
2161 && !WINDOW_FULL_WIDTH_P (it->w))
2162 || !NILP (current_buffer->truncate_lines));
2163
2164 /* Get dimensions of truncation and continuation glyphs. These are
2165 displayed as fringe bitmaps under X, so we don't need them for such
2166 frames. */
2167 if (!FRAME_WINDOW_P (it->f))
2168 {
2169 if (it->truncate_lines_p)
2170 {
2171 /* We will need the truncation glyph. */
2172 xassert (it->glyph_row == NULL);
2173 produce_special_glyphs (it, IT_TRUNCATION);
2174 it->truncation_pixel_width = it->pixel_width;
2175 }
2176 else
2177 {
2178 /* We will need the continuation glyph. */
2179 xassert (it->glyph_row == NULL);
2180 produce_special_glyphs (it, IT_CONTINUATION);
2181 it->continuation_pixel_width = it->pixel_width;
2182 }
2183
2184 /* Reset these values to zero because the produce_special_glyphs
2185 above has changed them. */
2186 it->pixel_width = it->ascent = it->descent = 0;
2187 it->phys_ascent = it->phys_descent = 0;
2188 }
2189
2190 /* Set this after getting the dimensions of truncation and
2191 continuation glyphs, so that we don't produce glyphs when calling
2192 produce_special_glyphs, above. */
2193 it->glyph_row = row;
2194 it->area = TEXT_AREA;
2195
2196 /* Get the dimensions of the display area. The display area
2197 consists of the visible window area plus a horizontally scrolled
2198 part to the left of the window. All x-values are relative to the
2199 start of this total display area. */
2200 if (base_face_id != DEFAULT_FACE_ID)
2201 {
2202 /* Mode lines, menu bar in terminal frames. */
2203 it->first_visible_x = 0;
2204 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2205 }
2206 else
2207 {
2208 it->first_visible_x
2209 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2210 it->last_visible_x = (it->first_visible_x
2211 + window_box_width (w, TEXT_AREA));
2212
2213 /* If we truncate lines, leave room for the truncator glyph(s) at
2214 the right margin. Otherwise, leave room for the continuation
2215 glyph(s). Truncation and continuation glyphs are not inserted
2216 for window-based redisplay. */
2217 if (!FRAME_WINDOW_P (it->f))
2218 {
2219 if (it->truncate_lines_p)
2220 it->last_visible_x -= it->truncation_pixel_width;
2221 else
2222 it->last_visible_x -= it->continuation_pixel_width;
2223 }
2224
2225 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2226 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2227 }
2228
2229 /* Leave room for a border glyph. */
2230 if (!FRAME_WINDOW_P (it->f)
2231 && !WINDOW_RIGHTMOST_P (it->w))
2232 it->last_visible_x -= 1;
2233
2234 it->last_visible_y = window_text_bottom_y (w);
2235
2236 /* For mode lines and alike, arrange for the first glyph having a
2237 left box line if the face specifies a box. */
2238 if (base_face_id != DEFAULT_FACE_ID)
2239 {
2240 struct face *face;
2241
2242 it->face_id = base_face_id;
2243
2244 /* If we have a boxed mode line, make the first character appear
2245 with a left box line. */
2246 face = FACE_FROM_ID (it->f, base_face_id);
2247 if (face->box != FACE_NO_BOX)
2248 it->start_of_box_run_p = 1;
2249 }
2250
2251 /* If a buffer position was specified, set the iterator there,
2252 getting overlays and face properties from that position. */
2253 if (charpos >= BUF_BEG (current_buffer))
2254 {
2255 it->end_charpos = ZV;
2256 it->face_id = -1;
2257 IT_CHARPOS (*it) = charpos;
2258
2259 /* Compute byte position if not specified. */
2260 if (bytepos < charpos)
2261 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2262 else
2263 IT_BYTEPOS (*it) = bytepos;
2264
2265 it->start = it->current;
2266
2267 /* Compute faces etc. */
2268 reseat (it, it->current.pos, 1);
2269 }
2270
2271 CHECK_IT (it);
2272 }
2273
2274
2275 /* Initialize IT for the display of window W with window start POS. */
2276
2277 void
2278 start_display (it, w, pos)
2279 struct it *it;
2280 struct window *w;
2281 struct text_pos pos;
2282 {
2283 struct glyph_row *row;
2284 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2285
2286 row = w->desired_matrix->rows + first_vpos;
2287 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2288 it->first_vpos = first_vpos;
2289
2290 if (!it->truncate_lines_p)
2291 {
2292 int start_at_line_beg_p;
2293 int first_y = it->current_y;
2294
2295 /* If window start is not at a line start, skip forward to POS to
2296 get the correct continuation lines width. */
2297 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2298 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2299 if (!start_at_line_beg_p)
2300 {
2301 int new_x;
2302
2303 reseat_at_previous_visible_line_start (it);
2304 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2305
2306 new_x = it->current_x + it->pixel_width;
2307
2308 /* If lines are continued, this line may end in the middle
2309 of a multi-glyph character (e.g. a control character
2310 displayed as \003, or in the middle of an overlay
2311 string). In this case move_it_to above will not have
2312 taken us to the start of the continuation line but to the
2313 end of the continued line. */
2314 if (it->current_x > 0
2315 && !it->truncate_lines_p /* Lines are continued. */
2316 && (/* And glyph doesn't fit on the line. */
2317 new_x > it->last_visible_x
2318 /* Or it fits exactly and we're on a window
2319 system frame. */
2320 || (new_x == it->last_visible_x
2321 && FRAME_WINDOW_P (it->f))))
2322 {
2323 if (it->current.dpvec_index >= 0
2324 || it->current.overlay_string_index >= 0)
2325 {
2326 set_iterator_to_next (it, 1);
2327 move_it_in_display_line_to (it, -1, -1, 0);
2328 }
2329
2330 it->continuation_lines_width += it->current_x;
2331 }
2332
2333 /* We're starting a new display line, not affected by the
2334 height of the continued line, so clear the appropriate
2335 fields in the iterator structure. */
2336 it->max_ascent = it->max_descent = 0;
2337 it->max_phys_ascent = it->max_phys_descent = 0;
2338
2339 it->current_y = first_y;
2340 it->vpos = 0;
2341 it->current_x = it->hpos = 0;
2342 }
2343 }
2344
2345 #if 0 /* Don't assert the following because start_display is sometimes
2346 called intentionally with a window start that is not at a
2347 line start. Please leave this code in as a comment. */
2348
2349 /* Window start should be on a line start, now. */
2350 xassert (it->continuation_lines_width
2351 || IT_CHARPOS (it) == BEGV
2352 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2353 #endif /* 0 */
2354 }
2355
2356
2357 /* Return 1 if POS is a position in ellipses displayed for invisible
2358 text. W is the window we display, for text property lookup. */
2359
2360 static int
2361 in_ellipses_for_invisible_text_p (pos, w)
2362 struct display_pos *pos;
2363 struct window *w;
2364 {
2365 Lisp_Object prop, window;
2366 int ellipses_p = 0;
2367 int charpos = CHARPOS (pos->pos);
2368
2369 /* If POS specifies a position in a display vector, this might
2370 be for an ellipsis displayed for invisible text. We won't
2371 get the iterator set up for delivering that ellipsis unless
2372 we make sure that it gets aware of the invisible text. */
2373 if (pos->dpvec_index >= 0
2374 && pos->overlay_string_index < 0
2375 && CHARPOS (pos->string_pos) < 0
2376 && charpos > BEGV
2377 && (XSETWINDOW (window, w),
2378 prop = Fget_char_property (make_number (charpos),
2379 Qinvisible, window),
2380 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2381 {
2382 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2383 window);
2384 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2385 }
2386
2387 return ellipses_p;
2388 }
2389
2390
2391 /* Initialize IT for stepping through current_buffer in window W,
2392 starting at position POS that includes overlay string and display
2393 vector/ control character translation position information. Value
2394 is zero if there are overlay strings with newlines at POS. */
2395
2396 static int
2397 init_from_display_pos (it, w, pos)
2398 struct it *it;
2399 struct window *w;
2400 struct display_pos *pos;
2401 {
2402 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2403 int i, overlay_strings_with_newlines = 0;
2404
2405 /* If POS specifies a position in a display vector, this might
2406 be for an ellipsis displayed for invisible text. We won't
2407 get the iterator set up for delivering that ellipsis unless
2408 we make sure that it gets aware of the invisible text. */
2409 if (in_ellipses_for_invisible_text_p (pos, w))
2410 {
2411 --charpos;
2412 bytepos = 0;
2413 }
2414
2415 /* Keep in mind: the call to reseat in init_iterator skips invisible
2416 text, so we might end up at a position different from POS. This
2417 is only a problem when POS is a row start after a newline and an
2418 overlay starts there with an after-string, and the overlay has an
2419 invisible property. Since we don't skip invisible text in
2420 display_line and elsewhere immediately after consuming the
2421 newline before the row start, such a POS will not be in a string,
2422 but the call to init_iterator below will move us to the
2423 after-string. */
2424 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2425
2426 for (i = 0; i < it->n_overlay_strings; ++i)
2427 {
2428 const char *s = SDATA (it->overlay_strings[i]);
2429 const char *e = s + SBYTES (it->overlay_strings[i]);
2430
2431 while (s < e && *s != '\n')
2432 ++s;
2433
2434 if (s < e)
2435 {
2436 overlay_strings_with_newlines = 1;
2437 break;
2438 }
2439 }
2440
2441 /* If position is within an overlay string, set up IT to the right
2442 overlay string. */
2443 if (pos->overlay_string_index >= 0)
2444 {
2445 int relative_index;
2446
2447 /* If the first overlay string happens to have a `display'
2448 property for an image, the iterator will be set up for that
2449 image, and we have to undo that setup first before we can
2450 correct the overlay string index. */
2451 if (it->method == next_element_from_image)
2452 pop_it (it);
2453
2454 /* We already have the first chunk of overlay strings in
2455 IT->overlay_strings. Load more until the one for
2456 pos->overlay_string_index is in IT->overlay_strings. */
2457 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2458 {
2459 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2460 it->current.overlay_string_index = 0;
2461 while (n--)
2462 {
2463 load_overlay_strings (it, 0);
2464 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2465 }
2466 }
2467
2468 it->current.overlay_string_index = pos->overlay_string_index;
2469 relative_index = (it->current.overlay_string_index
2470 % OVERLAY_STRING_CHUNK_SIZE);
2471 it->string = it->overlay_strings[relative_index];
2472 xassert (STRINGP (it->string));
2473 it->current.string_pos = pos->string_pos;
2474 it->method = next_element_from_string;
2475 }
2476
2477 #if 0 /* This is bogus because POS not having an overlay string
2478 position does not mean it's after the string. Example: A
2479 line starting with a before-string and initialization of IT
2480 to the previous row's end position. */
2481 else if (it->current.overlay_string_index >= 0)
2482 {
2483 /* If POS says we're already after an overlay string ending at
2484 POS, make sure to pop the iterator because it will be in
2485 front of that overlay string. When POS is ZV, we've thereby
2486 also ``processed'' overlay strings at ZV. */
2487 while (it->sp)
2488 pop_it (it);
2489 it->current.overlay_string_index = -1;
2490 it->method = next_element_from_buffer;
2491 if (CHARPOS (pos->pos) == ZV)
2492 it->overlay_strings_at_end_processed_p = 1;
2493 }
2494 #endif /* 0 */
2495
2496 if (CHARPOS (pos->string_pos) >= 0)
2497 {
2498 /* Recorded position is not in an overlay string, but in another
2499 string. This can only be a string from a `display' property.
2500 IT should already be filled with that string. */
2501 it->current.string_pos = pos->string_pos;
2502 xassert (STRINGP (it->string));
2503 }
2504
2505 /* Restore position in display vector translations, control
2506 character translations or ellipses. */
2507 if (pos->dpvec_index >= 0)
2508 {
2509 if (it->dpvec == NULL)
2510 get_next_display_element (it);
2511 xassert (it->dpvec && it->current.dpvec_index == 0);
2512 it->current.dpvec_index = pos->dpvec_index;
2513 }
2514
2515 CHECK_IT (it);
2516 return !overlay_strings_with_newlines;
2517 }
2518
2519
2520 /* Initialize IT for stepping through current_buffer in window W
2521 starting at ROW->start. */
2522
2523 static void
2524 init_to_row_start (it, w, row)
2525 struct it *it;
2526 struct window *w;
2527 struct glyph_row *row;
2528 {
2529 init_from_display_pos (it, w, &row->start);
2530 it->start = row->start;
2531 it->continuation_lines_width = row->continuation_lines_width;
2532 CHECK_IT (it);
2533 }
2534
2535
2536 /* Initialize IT for stepping through current_buffer in window W
2537 starting in the line following ROW, i.e. starting at ROW->end.
2538 Value is zero if there are overlay strings with newlines at ROW's
2539 end position. */
2540
2541 static int
2542 init_to_row_end (it, w, row)
2543 struct it *it;
2544 struct window *w;
2545 struct glyph_row *row;
2546 {
2547 int success = 0;
2548
2549 if (init_from_display_pos (it, w, &row->end))
2550 {
2551 if (row->continued_p)
2552 it->continuation_lines_width
2553 = row->continuation_lines_width + row->pixel_width;
2554 CHECK_IT (it);
2555 success = 1;
2556 }
2557
2558 return success;
2559 }
2560
2561
2562
2563 \f
2564 /***********************************************************************
2565 Text properties
2566 ***********************************************************************/
2567
2568 /* Called when IT reaches IT->stop_charpos. Handle text property and
2569 overlay changes. Set IT->stop_charpos to the next position where
2570 to stop. */
2571
2572 static void
2573 handle_stop (it)
2574 struct it *it;
2575 {
2576 enum prop_handled handled;
2577 int handle_overlay_change_p = 1;
2578 struct props *p;
2579
2580 it->dpvec = NULL;
2581 it->current.dpvec_index = -1;
2582
2583 do
2584 {
2585 handled = HANDLED_NORMALLY;
2586
2587 /* Call text property handlers. */
2588 for (p = it_props; p->handler; ++p)
2589 {
2590 handled = p->handler (it);
2591
2592 if (handled == HANDLED_RECOMPUTE_PROPS)
2593 break;
2594 else if (handled == HANDLED_RETURN)
2595 return;
2596 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2597 handle_overlay_change_p = 0;
2598 }
2599
2600 if (handled != HANDLED_RECOMPUTE_PROPS)
2601 {
2602 /* Don't check for overlay strings below when set to deliver
2603 characters from a display vector. */
2604 if (it->method == next_element_from_display_vector)
2605 handle_overlay_change_p = 0;
2606
2607 /* Handle overlay changes. */
2608 if (handle_overlay_change_p)
2609 handled = handle_overlay_change (it);
2610
2611 /* Determine where to stop next. */
2612 if (handled == HANDLED_NORMALLY)
2613 compute_stop_pos (it);
2614 }
2615 }
2616 while (handled == HANDLED_RECOMPUTE_PROPS);
2617 }
2618
2619
2620 /* Compute IT->stop_charpos from text property and overlay change
2621 information for IT's current position. */
2622
2623 static void
2624 compute_stop_pos (it)
2625 struct it *it;
2626 {
2627 register INTERVAL iv, next_iv;
2628 Lisp_Object object, limit, position;
2629
2630 /* If nowhere else, stop at the end. */
2631 it->stop_charpos = it->end_charpos;
2632
2633 if (STRINGP (it->string))
2634 {
2635 /* Strings are usually short, so don't limit the search for
2636 properties. */
2637 object = it->string;
2638 limit = Qnil;
2639 position = make_number (IT_STRING_CHARPOS (*it));
2640 }
2641 else
2642 {
2643 int charpos;
2644
2645 /* If next overlay change is in front of the current stop pos
2646 (which is IT->end_charpos), stop there. Note: value of
2647 next_overlay_change is point-max if no overlay change
2648 follows. */
2649 charpos = next_overlay_change (IT_CHARPOS (*it));
2650 if (charpos < it->stop_charpos)
2651 it->stop_charpos = charpos;
2652
2653 /* If showing the region, we have to stop at the region
2654 start or end because the face might change there. */
2655 if (it->region_beg_charpos > 0)
2656 {
2657 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2658 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2659 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2660 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2661 }
2662
2663 /* Set up variables for computing the stop position from text
2664 property changes. */
2665 XSETBUFFER (object, current_buffer);
2666 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2667 position = make_number (IT_CHARPOS (*it));
2668
2669 }
2670
2671 /* Get the interval containing IT's position. Value is a null
2672 interval if there isn't such an interval. */
2673 iv = validate_interval_range (object, &position, &position, 0);
2674 if (!NULL_INTERVAL_P (iv))
2675 {
2676 Lisp_Object values_here[LAST_PROP_IDX];
2677 struct props *p;
2678
2679 /* Get properties here. */
2680 for (p = it_props; p->handler; ++p)
2681 values_here[p->idx] = textget (iv->plist, *p->name);
2682
2683 /* Look for an interval following iv that has different
2684 properties. */
2685 for (next_iv = next_interval (iv);
2686 (!NULL_INTERVAL_P (next_iv)
2687 && (NILP (limit)
2688 || XFASTINT (limit) > next_iv->position));
2689 next_iv = next_interval (next_iv))
2690 {
2691 for (p = it_props; p->handler; ++p)
2692 {
2693 Lisp_Object new_value;
2694
2695 new_value = textget (next_iv->plist, *p->name);
2696 if (!EQ (values_here[p->idx], new_value))
2697 break;
2698 }
2699
2700 if (p->handler)
2701 break;
2702 }
2703
2704 if (!NULL_INTERVAL_P (next_iv))
2705 {
2706 if (INTEGERP (limit)
2707 && next_iv->position >= XFASTINT (limit))
2708 /* No text property change up to limit. */
2709 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2710 else
2711 /* Text properties change in next_iv. */
2712 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2713 }
2714 }
2715
2716 xassert (STRINGP (it->string)
2717 || (it->stop_charpos >= BEGV
2718 && it->stop_charpos >= IT_CHARPOS (*it)));
2719 }
2720
2721
2722 /* Return the position of the next overlay change after POS in
2723 current_buffer. Value is point-max if no overlay change
2724 follows. This is like `next-overlay-change' but doesn't use
2725 xmalloc. */
2726
2727 static int
2728 next_overlay_change (pos)
2729 int pos;
2730 {
2731 int noverlays;
2732 int endpos;
2733 Lisp_Object *overlays;
2734 int i;
2735
2736 /* Get all overlays at the given position. */
2737 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2738
2739 /* If any of these overlays ends before endpos,
2740 use its ending point instead. */
2741 for (i = 0; i < noverlays; ++i)
2742 {
2743 Lisp_Object oend;
2744 int oendpos;
2745
2746 oend = OVERLAY_END (overlays[i]);
2747 oendpos = OVERLAY_POSITION (oend);
2748 endpos = min (endpos, oendpos);
2749 }
2750
2751 return endpos;
2752 }
2753
2754
2755 \f
2756 /***********************************************************************
2757 Fontification
2758 ***********************************************************************/
2759
2760 /* Handle changes in the `fontified' property of the current buffer by
2761 calling hook functions from Qfontification_functions to fontify
2762 regions of text. */
2763
2764 static enum prop_handled
2765 handle_fontified_prop (it)
2766 struct it *it;
2767 {
2768 Lisp_Object prop, pos;
2769 enum prop_handled handled = HANDLED_NORMALLY;
2770
2771 /* Get the value of the `fontified' property at IT's current buffer
2772 position. (The `fontified' property doesn't have a special
2773 meaning in strings.) If the value is nil, call functions from
2774 Qfontification_functions. */
2775 if (!STRINGP (it->string)
2776 && it->s == NULL
2777 && !NILP (Vfontification_functions)
2778 && !NILP (Vrun_hooks)
2779 && (pos = make_number (IT_CHARPOS (*it)),
2780 prop = Fget_char_property (pos, Qfontified, Qnil),
2781 NILP (prop)))
2782 {
2783 int count = SPECPDL_INDEX ();
2784 Lisp_Object val;
2785
2786 val = Vfontification_functions;
2787 specbind (Qfontification_functions, Qnil);
2788
2789 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2790 safe_call1 (val, pos);
2791 else
2792 {
2793 Lisp_Object globals, fn;
2794 struct gcpro gcpro1, gcpro2;
2795
2796 globals = Qnil;
2797 GCPRO2 (val, globals);
2798
2799 for (; CONSP (val); val = XCDR (val))
2800 {
2801 fn = XCAR (val);
2802
2803 if (EQ (fn, Qt))
2804 {
2805 /* A value of t indicates this hook has a local
2806 binding; it means to run the global binding too.
2807 In a global value, t should not occur. If it
2808 does, we must ignore it to avoid an endless
2809 loop. */
2810 for (globals = Fdefault_value (Qfontification_functions);
2811 CONSP (globals);
2812 globals = XCDR (globals))
2813 {
2814 fn = XCAR (globals);
2815 if (!EQ (fn, Qt))
2816 safe_call1 (fn, pos);
2817 }
2818 }
2819 else
2820 safe_call1 (fn, pos);
2821 }
2822
2823 UNGCPRO;
2824 }
2825
2826 unbind_to (count, Qnil);
2827
2828 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2829 something. This avoids an endless loop if they failed to
2830 fontify the text for which reason ever. */
2831 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2832 handled = HANDLED_RECOMPUTE_PROPS;
2833 }
2834
2835 return handled;
2836 }
2837
2838
2839 \f
2840 /***********************************************************************
2841 Faces
2842 ***********************************************************************/
2843
2844 /* Set up iterator IT from face properties at its current position.
2845 Called from handle_stop. */
2846
2847 static enum prop_handled
2848 handle_face_prop (it)
2849 struct it *it;
2850 {
2851 int new_face_id, next_stop;
2852
2853 if (!STRINGP (it->string))
2854 {
2855 new_face_id
2856 = face_at_buffer_position (it->w,
2857 IT_CHARPOS (*it),
2858 it->region_beg_charpos,
2859 it->region_end_charpos,
2860 &next_stop,
2861 (IT_CHARPOS (*it)
2862 + TEXT_PROP_DISTANCE_LIMIT),
2863 0);
2864
2865 /* Is this a start of a run of characters with box face?
2866 Caveat: this can be called for a freshly initialized
2867 iterator; face_id is -1 in this case. We know that the new
2868 face will not change until limit, i.e. if the new face has a
2869 box, all characters up to limit will have one. But, as
2870 usual, we don't know whether limit is really the end. */
2871 if (new_face_id != it->face_id)
2872 {
2873 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2874
2875 /* If new face has a box but old face has not, this is
2876 the start of a run of characters with box, i.e. it has
2877 a shadow on the left side. The value of face_id of the
2878 iterator will be -1 if this is the initial call that gets
2879 the face. In this case, we have to look in front of IT's
2880 position and see whether there is a face != new_face_id. */
2881 it->start_of_box_run_p
2882 = (new_face->box != FACE_NO_BOX
2883 && (it->face_id >= 0
2884 || IT_CHARPOS (*it) == BEG
2885 || new_face_id != face_before_it_pos (it)));
2886 it->face_box_p = new_face->box != FACE_NO_BOX;
2887 }
2888 }
2889 else
2890 {
2891 int base_face_id, bufpos;
2892
2893 if (it->current.overlay_string_index >= 0)
2894 bufpos = IT_CHARPOS (*it);
2895 else
2896 bufpos = 0;
2897
2898 /* For strings from a buffer, i.e. overlay strings or strings
2899 from a `display' property, use the face at IT's current
2900 buffer position as the base face to merge with, so that
2901 overlay strings appear in the same face as surrounding
2902 text, unless they specify their own faces. */
2903 base_face_id = underlying_face_id (it);
2904
2905 new_face_id = face_at_string_position (it->w,
2906 it->string,
2907 IT_STRING_CHARPOS (*it),
2908 bufpos,
2909 it->region_beg_charpos,
2910 it->region_end_charpos,
2911 &next_stop,
2912 base_face_id, 0);
2913
2914 #if 0 /* This shouldn't be neccessary. Let's check it. */
2915 /* If IT is used to display a mode line we would really like to
2916 use the mode line face instead of the frame's default face. */
2917 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2918 && new_face_id == DEFAULT_FACE_ID)
2919 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2920 #endif
2921
2922 /* Is this a start of a run of characters with box? Caveat:
2923 this can be called for a freshly allocated iterator; face_id
2924 is -1 is this case. We know that the new face will not
2925 change until the next check pos, i.e. if the new face has a
2926 box, all characters up to that position will have a
2927 box. But, as usual, we don't know whether that position
2928 is really the end. */
2929 if (new_face_id != it->face_id)
2930 {
2931 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2932 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2933
2934 /* If new face has a box but old face hasn't, this is the
2935 start of a run of characters with box, i.e. it has a
2936 shadow on the left side. */
2937 it->start_of_box_run_p
2938 = new_face->box && (old_face == NULL || !old_face->box);
2939 it->face_box_p = new_face->box != FACE_NO_BOX;
2940 }
2941 }
2942
2943 it->face_id = new_face_id;
2944 return HANDLED_NORMALLY;
2945 }
2946
2947
2948 /* Return the ID of the face ``underlying'' IT's current position,
2949 which is in a string. If the iterator is associated with a
2950 buffer, return the face at IT's current buffer position.
2951 Otherwise, use the iterator's base_face_id. */
2952
2953 static int
2954 underlying_face_id (it)
2955 struct it *it;
2956 {
2957 int face_id = it->base_face_id, i;
2958
2959 xassert (STRINGP (it->string));
2960
2961 for (i = it->sp - 1; i >= 0; --i)
2962 if (NILP (it->stack[i].string))
2963 face_id = it->stack[i].face_id;
2964
2965 return face_id;
2966 }
2967
2968
2969 /* Compute the face one character before or after the current position
2970 of IT. BEFORE_P non-zero means get the face in front of IT's
2971 position. Value is the id of the face. */
2972
2973 static int
2974 face_before_or_after_it_pos (it, before_p)
2975 struct it *it;
2976 int before_p;
2977 {
2978 int face_id, limit;
2979 int next_check_charpos;
2980 struct text_pos pos;
2981
2982 xassert (it->s == NULL);
2983
2984 if (STRINGP (it->string))
2985 {
2986 int bufpos, base_face_id;
2987
2988 /* No face change past the end of the string (for the case
2989 we are padding with spaces). No face change before the
2990 string start. */
2991 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2992 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2993 return it->face_id;
2994
2995 /* Set pos to the position before or after IT's current position. */
2996 if (before_p)
2997 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2998 else
2999 /* For composition, we must check the character after the
3000 composition. */
3001 pos = (it->what == IT_COMPOSITION
3002 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3003 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3004
3005 if (it->current.overlay_string_index >= 0)
3006 bufpos = IT_CHARPOS (*it);
3007 else
3008 bufpos = 0;
3009
3010 base_face_id = underlying_face_id (it);
3011
3012 /* Get the face for ASCII, or unibyte. */
3013 face_id = face_at_string_position (it->w,
3014 it->string,
3015 CHARPOS (pos),
3016 bufpos,
3017 it->region_beg_charpos,
3018 it->region_end_charpos,
3019 &next_check_charpos,
3020 base_face_id, 0);
3021
3022 /* Correct the face for charsets different from ASCII. Do it
3023 for the multibyte case only. The face returned above is
3024 suitable for unibyte text if IT->string is unibyte. */
3025 if (STRING_MULTIBYTE (it->string))
3026 {
3027 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3028 int rest = SBYTES (it->string) - BYTEPOS (pos);
3029 int c, len;
3030 struct face *face = FACE_FROM_ID (it->f, face_id);
3031
3032 c = string_char_and_length (p, rest, &len);
3033 face_id = FACE_FOR_CHAR (it->f, face, c);
3034 }
3035 }
3036 else
3037 {
3038 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3039 || (IT_CHARPOS (*it) <= BEGV && before_p))
3040 return it->face_id;
3041
3042 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3043 pos = it->current.pos;
3044
3045 if (before_p)
3046 DEC_TEXT_POS (pos, it->multibyte_p);
3047 else
3048 {
3049 if (it->what == IT_COMPOSITION)
3050 /* For composition, we must check the position after the
3051 composition. */
3052 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3053 else
3054 INC_TEXT_POS (pos, it->multibyte_p);
3055 }
3056
3057 /* Determine face for CHARSET_ASCII, or unibyte. */
3058 face_id = face_at_buffer_position (it->w,
3059 CHARPOS (pos),
3060 it->region_beg_charpos,
3061 it->region_end_charpos,
3062 &next_check_charpos,
3063 limit, 0);
3064
3065 /* Correct the face for charsets different from ASCII. Do it
3066 for the multibyte case only. The face returned above is
3067 suitable for unibyte text if current_buffer is unibyte. */
3068 if (it->multibyte_p)
3069 {
3070 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3071 struct face *face = FACE_FROM_ID (it->f, face_id);
3072 face_id = FACE_FOR_CHAR (it->f, face, c);
3073 }
3074 }
3075
3076 return face_id;
3077 }
3078
3079
3080 \f
3081 /***********************************************************************
3082 Invisible text
3083 ***********************************************************************/
3084
3085 /* Set up iterator IT from invisible properties at its current
3086 position. Called from handle_stop. */
3087
3088 static enum prop_handled
3089 handle_invisible_prop (it)
3090 struct it *it;
3091 {
3092 enum prop_handled handled = HANDLED_NORMALLY;
3093
3094 if (STRINGP (it->string))
3095 {
3096 extern Lisp_Object Qinvisible;
3097 Lisp_Object prop, end_charpos, limit, charpos;
3098
3099 /* Get the value of the invisible text property at the
3100 current position. Value will be nil if there is no such
3101 property. */
3102 charpos = make_number (IT_STRING_CHARPOS (*it));
3103 prop = Fget_text_property (charpos, Qinvisible, it->string);
3104
3105 if (!NILP (prop)
3106 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3107 {
3108 handled = HANDLED_RECOMPUTE_PROPS;
3109
3110 /* Get the position at which the next change of the
3111 invisible text property can be found in IT->string.
3112 Value will be nil if the property value is the same for
3113 all the rest of IT->string. */
3114 XSETINT (limit, SCHARS (it->string));
3115 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3116 it->string, limit);
3117
3118 /* Text at current position is invisible. The next
3119 change in the property is at position end_charpos.
3120 Move IT's current position to that position. */
3121 if (INTEGERP (end_charpos)
3122 && XFASTINT (end_charpos) < XFASTINT (limit))
3123 {
3124 struct text_pos old;
3125 old = it->current.string_pos;
3126 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3127 compute_string_pos (&it->current.string_pos, old, it->string);
3128 }
3129 else
3130 {
3131 /* The rest of the string is invisible. If this is an
3132 overlay string, proceed with the next overlay string
3133 or whatever comes and return a character from there. */
3134 if (it->current.overlay_string_index >= 0)
3135 {
3136 next_overlay_string (it);
3137 /* Don't check for overlay strings when we just
3138 finished processing them. */
3139 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3140 }
3141 else
3142 {
3143 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3144 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3145 }
3146 }
3147 }
3148 }
3149 else
3150 {
3151 int invis_p, newpos, next_stop, start_charpos;
3152 Lisp_Object pos, prop, overlay;
3153
3154 /* First of all, is there invisible text at this position? */
3155 start_charpos = IT_CHARPOS (*it);
3156 pos = make_number (IT_CHARPOS (*it));
3157 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3158 &overlay);
3159 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3160
3161 /* If we are on invisible text, skip over it. */
3162 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3163 {
3164 /* Record whether we have to display an ellipsis for the
3165 invisible text. */
3166 int display_ellipsis_p = invis_p == 2;
3167
3168 handled = HANDLED_RECOMPUTE_PROPS;
3169
3170 /* Loop skipping over invisible text. The loop is left at
3171 ZV or with IT on the first char being visible again. */
3172 do
3173 {
3174 /* Try to skip some invisible text. Return value is the
3175 position reached which can be equal to IT's position
3176 if there is nothing invisible here. This skips both
3177 over invisible text properties and overlays with
3178 invisible property. */
3179 newpos = skip_invisible (IT_CHARPOS (*it),
3180 &next_stop, ZV, it->window);
3181
3182 /* If we skipped nothing at all we weren't at invisible
3183 text in the first place. If everything to the end of
3184 the buffer was skipped, end the loop. */
3185 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3186 invis_p = 0;
3187 else
3188 {
3189 /* We skipped some characters but not necessarily
3190 all there are. Check if we ended up on visible
3191 text. Fget_char_property returns the property of
3192 the char before the given position, i.e. if we
3193 get invis_p = 0, this means that the char at
3194 newpos is visible. */
3195 pos = make_number (newpos);
3196 prop = Fget_char_property (pos, Qinvisible, it->window);
3197 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3198 }
3199
3200 /* If we ended up on invisible text, proceed to
3201 skip starting with next_stop. */
3202 if (invis_p)
3203 IT_CHARPOS (*it) = next_stop;
3204 }
3205 while (invis_p);
3206
3207 /* The position newpos is now either ZV or on visible text. */
3208 IT_CHARPOS (*it) = newpos;
3209 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3210
3211 /* If there are before-strings at the start of invisible
3212 text, and the text is invisible because of a text
3213 property, arrange to show before-strings because 20.x did
3214 it that way. (If the text is invisible because of an
3215 overlay property instead of a text property, this is
3216 already handled in the overlay code.) */
3217 if (NILP (overlay)
3218 && get_overlay_strings (it, start_charpos))
3219 {
3220 handled = HANDLED_RECOMPUTE_PROPS;
3221 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3222 }
3223 else if (display_ellipsis_p)
3224 setup_for_ellipsis (it);
3225 }
3226 }
3227
3228 return handled;
3229 }
3230
3231
3232 /* Make iterator IT return `...' next. */
3233
3234 static void
3235 setup_for_ellipsis (it)
3236 struct it *it;
3237 {
3238 if (it->dp
3239 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3240 {
3241 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3242 it->dpvec = v->contents;
3243 it->dpend = v->contents + v->size;
3244 }
3245 else
3246 {
3247 /* Default `...'. */
3248 it->dpvec = default_invis_vector;
3249 it->dpend = default_invis_vector + 3;
3250 }
3251
3252 /* The ellipsis display does not replace the display of the
3253 character at the new position. Indicate this by setting
3254 IT->dpvec_char_len to zero. */
3255 it->dpvec_char_len = 0;
3256
3257 it->current.dpvec_index = 0;
3258 it->method = next_element_from_display_vector;
3259 }
3260
3261
3262 \f
3263 /***********************************************************************
3264 'display' property
3265 ***********************************************************************/
3266
3267 /* Set up iterator IT from `display' property at its current position.
3268 Called from handle_stop. */
3269
3270 static enum prop_handled
3271 handle_display_prop (it)
3272 struct it *it;
3273 {
3274 Lisp_Object prop, object;
3275 struct text_pos *position;
3276 int display_replaced_p = 0;
3277
3278 if (STRINGP (it->string))
3279 {
3280 object = it->string;
3281 position = &it->current.string_pos;
3282 }
3283 else
3284 {
3285 object = it->w->buffer;
3286 position = &it->current.pos;
3287 }
3288
3289 /* Reset those iterator values set from display property values. */
3290 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3291 it->space_width = Qnil;
3292 it->font_height = Qnil;
3293 it->voffset = 0;
3294
3295 /* We don't support recursive `display' properties, i.e. string
3296 values that have a string `display' property, that have a string
3297 `display' property etc. */
3298 if (!it->string_from_display_prop_p)
3299 it->area = TEXT_AREA;
3300
3301 prop = Fget_char_property (make_number (position->charpos),
3302 Qdisplay, object);
3303 if (NILP (prop))
3304 return HANDLED_NORMALLY;
3305
3306 if (CONSP (prop)
3307 /* Simple properties. */
3308 && !EQ (XCAR (prop), Qimage)
3309 && !EQ (XCAR (prop), Qspace)
3310 && !EQ (XCAR (prop), Qwhen)
3311 && !EQ (XCAR (prop), Qslice)
3312 && !EQ (XCAR (prop), Qspace_width)
3313 && !EQ (XCAR (prop), Qheight)
3314 && !EQ (XCAR (prop), Qraise)
3315 /* Marginal area specifications. */
3316 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3317 && !EQ (XCAR (prop), Qleft_fringe)
3318 && !EQ (XCAR (prop), Qright_fringe)
3319 && !NILP (XCAR (prop)))
3320 {
3321 for (; CONSP (prop); prop = XCDR (prop))
3322 {
3323 if (handle_single_display_prop (it, XCAR (prop), object,
3324 position, display_replaced_p))
3325 display_replaced_p = 1;
3326 }
3327 }
3328 else if (VECTORP (prop))
3329 {
3330 int i;
3331 for (i = 0; i < ASIZE (prop); ++i)
3332 if (handle_single_display_prop (it, AREF (prop, i), object,
3333 position, display_replaced_p))
3334 display_replaced_p = 1;
3335 }
3336 else
3337 {
3338 if (handle_single_display_prop (it, prop, object, position, 0))
3339 display_replaced_p = 1;
3340 }
3341
3342 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3343 }
3344
3345
3346 /* Value is the position of the end of the `display' property starting
3347 at START_POS in OBJECT. */
3348
3349 static struct text_pos
3350 display_prop_end (it, object, start_pos)
3351 struct it *it;
3352 Lisp_Object object;
3353 struct text_pos start_pos;
3354 {
3355 Lisp_Object end;
3356 struct text_pos end_pos;
3357
3358 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3359 Qdisplay, object, Qnil);
3360 CHARPOS (end_pos) = XFASTINT (end);
3361 if (STRINGP (object))
3362 compute_string_pos (&end_pos, start_pos, it->string);
3363 else
3364 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3365
3366 return end_pos;
3367 }
3368
3369
3370 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3371 is the object in which the `display' property was found. *POSITION
3372 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3373 means that we previously saw a display sub-property which already
3374 replaced text display with something else, for example an image;
3375 ignore such properties after the first one has been processed.
3376
3377 If PROP is a `space' or `image' sub-property, set *POSITION to the
3378 end position of the `display' property.
3379
3380 Value is non-zero if something was found which replaces the display
3381 of buffer or string text. */
3382
3383 static int
3384 handle_single_display_prop (it, prop, object, position,
3385 display_replaced_before_p)
3386 struct it *it;
3387 Lisp_Object prop;
3388 Lisp_Object object;
3389 struct text_pos *position;
3390 int display_replaced_before_p;
3391 {
3392 Lisp_Object value;
3393 int replaces_text_display_p = 0;
3394 Lisp_Object form;
3395
3396 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3397 evaluated. If the result is nil, VALUE is ignored. */
3398 form = Qt;
3399 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3400 {
3401 prop = XCDR (prop);
3402 if (!CONSP (prop))
3403 return 0;
3404 form = XCAR (prop);
3405 prop = XCDR (prop);
3406 }
3407
3408 if (!NILP (form) && !EQ (form, Qt))
3409 {
3410 int count = SPECPDL_INDEX ();
3411 struct gcpro gcpro1;
3412
3413 /* Bind `object' to the object having the `display' property, a
3414 buffer or string. Bind `position' to the position in the
3415 object where the property was found, and `buffer-position'
3416 to the current position in the buffer. */
3417 specbind (Qobject, object);
3418 specbind (Qposition, make_number (CHARPOS (*position)));
3419 specbind (Qbuffer_position,
3420 make_number (STRINGP (object)
3421 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3422 GCPRO1 (form);
3423 form = safe_eval (form);
3424 UNGCPRO;
3425 unbind_to (count, Qnil);
3426 }
3427
3428 if (NILP (form))
3429 return 0;
3430
3431 if (CONSP (prop)
3432 && EQ (XCAR (prop), Qheight)
3433 && CONSP (XCDR (prop)))
3434 {
3435 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3436 return 0;
3437
3438 /* `(height HEIGHT)'. */
3439 it->font_height = XCAR (XCDR (prop));
3440 if (!NILP (it->font_height))
3441 {
3442 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3443 int new_height = -1;
3444
3445 if (CONSP (it->font_height)
3446 && (EQ (XCAR (it->font_height), Qplus)
3447 || EQ (XCAR (it->font_height), Qminus))
3448 && CONSP (XCDR (it->font_height))
3449 && INTEGERP (XCAR (XCDR (it->font_height))))
3450 {
3451 /* `(+ N)' or `(- N)' where N is an integer. */
3452 int steps = XINT (XCAR (XCDR (it->font_height)));
3453 if (EQ (XCAR (it->font_height), Qplus))
3454 steps = - steps;
3455 it->face_id = smaller_face (it->f, it->face_id, steps);
3456 }
3457 else if (FUNCTIONP (it->font_height))
3458 {
3459 /* Call function with current height as argument.
3460 Value is the new height. */
3461 Lisp_Object height;
3462 height = safe_call1 (it->font_height,
3463 face->lface[LFACE_HEIGHT_INDEX]);
3464 if (NUMBERP (height))
3465 new_height = XFLOATINT (height);
3466 }
3467 else if (NUMBERP (it->font_height))
3468 {
3469 /* Value is a multiple of the canonical char height. */
3470 struct face *face;
3471
3472 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3473 new_height = (XFLOATINT (it->font_height)
3474 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3475 }
3476 else
3477 {
3478 /* Evaluate IT->font_height with `height' bound to the
3479 current specified height to get the new height. */
3480 Lisp_Object value;
3481 int count = SPECPDL_INDEX ();
3482
3483 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3484 value = safe_eval (it->font_height);
3485 unbind_to (count, Qnil);
3486
3487 if (NUMBERP (value))
3488 new_height = XFLOATINT (value);
3489 }
3490
3491 if (new_height > 0)
3492 it->face_id = face_with_height (it->f, it->face_id, new_height);
3493 }
3494 }
3495 else if (CONSP (prop)
3496 && EQ (XCAR (prop), Qspace_width)
3497 && CONSP (XCDR (prop)))
3498 {
3499 /* `(space_width WIDTH)'. */
3500 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3501 return 0;
3502
3503 value = XCAR (XCDR (prop));
3504 if (NUMBERP (value) && XFLOATINT (value) > 0)
3505 it->space_width = value;
3506 }
3507 else if (CONSP (prop)
3508 && EQ (XCAR (prop), Qslice))
3509 {
3510 /* `(slice X Y WIDTH HEIGHT)'. */
3511 Lisp_Object tem;
3512
3513 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3514 return 0;
3515
3516 if (tem = XCDR (prop), CONSP (tem))
3517 {
3518 it->slice.x = XCAR (tem);
3519 if (tem = XCDR (tem), CONSP (tem))
3520 {
3521 it->slice.y = XCAR (tem);
3522 if (tem = XCDR (tem), CONSP (tem))
3523 {
3524 it->slice.width = XCAR (tem);
3525 if (tem = XCDR (tem), CONSP (tem))
3526 it->slice.height = XCAR (tem);
3527 }
3528 }
3529 }
3530 }
3531 else if (CONSP (prop)
3532 && EQ (XCAR (prop), Qraise)
3533 && CONSP (XCDR (prop)))
3534 {
3535 /* `(raise FACTOR)'. */
3536 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3537 return 0;
3538
3539 #ifdef HAVE_WINDOW_SYSTEM
3540 value = XCAR (XCDR (prop));
3541 if (NUMBERP (value))
3542 {
3543 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3544 it->voffset = - (XFLOATINT (value)
3545 * (FONT_HEIGHT (face->font)));
3546 }
3547 #endif /* HAVE_WINDOW_SYSTEM */
3548 }
3549 else if (!it->string_from_display_prop_p)
3550 {
3551 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3552 VALUE) or `((margin nil) VALUE)' or VALUE. */
3553 Lisp_Object location, value;
3554 struct text_pos start_pos;
3555 int valid_p;
3556
3557 /* Characters having this form of property are not displayed, so
3558 we have to find the end of the property. */
3559 start_pos = *position;
3560 *position = display_prop_end (it, object, start_pos);
3561 value = Qnil;
3562
3563 /* Let's stop at the new position and assume that all
3564 text properties change there. */
3565 it->stop_charpos = position->charpos;
3566
3567 if (CONSP (prop)
3568 && (EQ (XCAR (prop), Qleft_fringe)
3569 || EQ (XCAR (prop), Qright_fringe))
3570 && CONSP (XCDR (prop)))
3571 {
3572 unsigned face_id = DEFAULT_FACE_ID;
3573 int fringe_bitmap;
3574
3575 /* Save current settings of IT so that we can restore them
3576 when we are finished with the glyph property value. */
3577
3578 /* `(left-fringe BITMAP FACE)'. */
3579 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3580 return 0;
3581
3582 #ifdef HAVE_WINDOW_SYSTEM
3583 value = XCAR (XCDR (prop));
3584 if (!SYMBOLP (value)
3585 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3586 return 0;
3587
3588 if (CONSP (XCDR (XCDR (prop))))
3589 {
3590 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3591
3592 face_id = lookup_named_face (it->f, face_name, 'A');
3593 if (face_id < 0)
3594 return 0;
3595 }
3596
3597 push_it (it);
3598
3599 it->area = TEXT_AREA;
3600 it->what = IT_IMAGE;
3601 it->image_id = -1; /* no image */
3602 it->position = start_pos;
3603 it->object = NILP (object) ? it->w->buffer : object;
3604 it->method = next_element_from_image;
3605 it->face_id = face_id;
3606
3607 /* Say that we haven't consumed the characters with
3608 `display' property yet. The call to pop_it in
3609 set_iterator_to_next will clean this up. */
3610 *position = start_pos;
3611
3612 if (EQ (XCAR (prop), Qleft_fringe))
3613 {
3614 it->left_user_fringe_bitmap = fringe_bitmap;
3615 it->left_user_fringe_face_id = face_id;
3616 }
3617 else
3618 {
3619 it->right_user_fringe_bitmap = fringe_bitmap;
3620 it->right_user_fringe_face_id = face_id;
3621 }
3622 #endif /* HAVE_WINDOW_SYSTEM */
3623 return 1;
3624 }
3625
3626 location = Qunbound;
3627 if (CONSP (prop) && CONSP (XCAR (prop)))
3628 {
3629 Lisp_Object tem;
3630
3631 value = XCDR (prop);
3632 if (CONSP (value))
3633 value = XCAR (value);
3634
3635 tem = XCAR (prop);
3636 if (EQ (XCAR (tem), Qmargin)
3637 && (tem = XCDR (tem),
3638 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3639 (NILP (tem)
3640 || EQ (tem, Qleft_margin)
3641 || EQ (tem, Qright_margin))))
3642 location = tem;
3643 }
3644
3645 if (EQ (location, Qunbound))
3646 {
3647 location = Qnil;
3648 value = prop;
3649 }
3650
3651 valid_p = (STRINGP (value)
3652 #ifdef HAVE_WINDOW_SYSTEM
3653 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3654 #endif /* not HAVE_WINDOW_SYSTEM */
3655 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3656
3657 if ((EQ (location, Qleft_margin)
3658 || EQ (location, Qright_margin)
3659 || NILP (location))
3660 && valid_p
3661 && !display_replaced_before_p)
3662 {
3663 replaces_text_display_p = 1;
3664
3665 /* Save current settings of IT so that we can restore them
3666 when we are finished with the glyph property value. */
3667 push_it (it);
3668
3669 if (NILP (location))
3670 it->area = TEXT_AREA;
3671 else if (EQ (location, Qleft_margin))
3672 it->area = LEFT_MARGIN_AREA;
3673 else
3674 it->area = RIGHT_MARGIN_AREA;
3675
3676 if (STRINGP (value))
3677 {
3678 it->string = value;
3679 it->multibyte_p = STRING_MULTIBYTE (it->string);
3680 it->current.overlay_string_index = -1;
3681 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3682 it->end_charpos = it->string_nchars = SCHARS (it->string);
3683 it->method = next_element_from_string;
3684 it->stop_charpos = 0;
3685 it->string_from_display_prop_p = 1;
3686 /* Say that we haven't consumed the characters with
3687 `display' property yet. The call to pop_it in
3688 set_iterator_to_next will clean this up. */
3689 *position = start_pos;
3690 }
3691 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3692 {
3693 it->method = next_element_from_stretch;
3694 it->object = value;
3695 it->current.pos = it->position = start_pos;
3696 }
3697 #ifdef HAVE_WINDOW_SYSTEM
3698 else
3699 {
3700 it->what = IT_IMAGE;
3701 it->image_id = lookup_image (it->f, value);
3702 it->position = start_pos;
3703 it->object = NILP (object) ? it->w->buffer : object;
3704 it->method = next_element_from_image;
3705
3706 /* Say that we haven't consumed the characters with
3707 `display' property yet. The call to pop_it in
3708 set_iterator_to_next will clean this up. */
3709 *position = start_pos;
3710 }
3711 #endif /* HAVE_WINDOW_SYSTEM */
3712 }
3713 else
3714 /* Invalid property or property not supported. Restore
3715 the position to what it was before. */
3716 *position = start_pos;
3717 }
3718
3719 return replaces_text_display_p;
3720 }
3721
3722
3723 /* Check if PROP is a display sub-property value whose text should be
3724 treated as intangible. */
3725
3726 static int
3727 single_display_prop_intangible_p (prop)
3728 Lisp_Object prop;
3729 {
3730 /* Skip over `when FORM'. */
3731 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3732 {
3733 prop = XCDR (prop);
3734 if (!CONSP (prop))
3735 return 0;
3736 prop = XCDR (prop);
3737 }
3738
3739 if (STRINGP (prop))
3740 return 1;
3741
3742 if (!CONSP (prop))
3743 return 0;
3744
3745 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3746 we don't need to treat text as intangible. */
3747 if (EQ (XCAR (prop), Qmargin))
3748 {
3749 prop = XCDR (prop);
3750 if (!CONSP (prop))
3751 return 0;
3752
3753 prop = XCDR (prop);
3754 if (!CONSP (prop)
3755 || EQ (XCAR (prop), Qleft_margin)
3756 || EQ (XCAR (prop), Qright_margin))
3757 return 0;
3758 }
3759
3760 return (CONSP (prop)
3761 && (EQ (XCAR (prop), Qimage)
3762 || EQ (XCAR (prop), Qspace)));
3763 }
3764
3765
3766 /* Check if PROP is a display property value whose text should be
3767 treated as intangible. */
3768
3769 int
3770 display_prop_intangible_p (prop)
3771 Lisp_Object prop;
3772 {
3773 if (CONSP (prop)
3774 && CONSP (XCAR (prop))
3775 && !EQ (Qmargin, XCAR (XCAR (prop))))
3776 {
3777 /* A list of sub-properties. */
3778 while (CONSP (prop))
3779 {
3780 if (single_display_prop_intangible_p (XCAR (prop)))
3781 return 1;
3782 prop = XCDR (prop);
3783 }
3784 }
3785 else if (VECTORP (prop))
3786 {
3787 /* A vector of sub-properties. */
3788 int i;
3789 for (i = 0; i < ASIZE (prop); ++i)
3790 if (single_display_prop_intangible_p (AREF (prop, i)))
3791 return 1;
3792 }
3793 else
3794 return single_display_prop_intangible_p (prop);
3795
3796 return 0;
3797 }
3798
3799
3800 /* Return 1 if PROP is a display sub-property value containing STRING. */
3801
3802 static int
3803 single_display_prop_string_p (prop, string)
3804 Lisp_Object prop, string;
3805 {
3806 if (EQ (string, prop))
3807 return 1;
3808
3809 /* Skip over `when FORM'. */
3810 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3811 {
3812 prop = XCDR (prop);
3813 if (!CONSP (prop))
3814 return 0;
3815 prop = XCDR (prop);
3816 }
3817
3818 if (CONSP (prop))
3819 /* Skip over `margin LOCATION'. */
3820 if (EQ (XCAR (prop), Qmargin))
3821 {
3822 prop = XCDR (prop);
3823 if (!CONSP (prop))
3824 return 0;
3825
3826 prop = XCDR (prop);
3827 if (!CONSP (prop))
3828 return 0;
3829 }
3830
3831 return CONSP (prop) && EQ (XCAR (prop), string);
3832 }
3833
3834
3835 /* Return 1 if STRING appears in the `display' property PROP. */
3836
3837 static int
3838 display_prop_string_p (prop, string)
3839 Lisp_Object prop, string;
3840 {
3841 if (CONSP (prop)
3842 && CONSP (XCAR (prop))
3843 && !EQ (Qmargin, XCAR (XCAR (prop))))
3844 {
3845 /* A list of sub-properties. */
3846 while (CONSP (prop))
3847 {
3848 if (single_display_prop_string_p (XCAR (prop), string))
3849 return 1;
3850 prop = XCDR (prop);
3851 }
3852 }
3853 else if (VECTORP (prop))
3854 {
3855 /* A vector of sub-properties. */
3856 int i;
3857 for (i = 0; i < ASIZE (prop); ++i)
3858 if (single_display_prop_string_p (AREF (prop, i), string))
3859 return 1;
3860 }
3861 else
3862 return single_display_prop_string_p (prop, string);
3863
3864 return 0;
3865 }
3866
3867
3868 /* Determine from which buffer position in W's buffer STRING comes
3869 from. AROUND_CHARPOS is an approximate position where it could
3870 be from. Value is the buffer position or 0 if it couldn't be
3871 determined.
3872
3873 W's buffer must be current.
3874
3875 This function is necessary because we don't record buffer positions
3876 in glyphs generated from strings (to keep struct glyph small).
3877 This function may only use code that doesn't eval because it is
3878 called asynchronously from note_mouse_highlight. */
3879
3880 int
3881 string_buffer_position (w, string, around_charpos)
3882 struct window *w;
3883 Lisp_Object string;
3884 int around_charpos;
3885 {
3886 Lisp_Object limit, prop, pos;
3887 const int MAX_DISTANCE = 1000;
3888 int found = 0;
3889
3890 pos = make_number (around_charpos);
3891 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3892 while (!found && !EQ (pos, limit))
3893 {
3894 prop = Fget_char_property (pos, Qdisplay, Qnil);
3895 if (!NILP (prop) && display_prop_string_p (prop, string))
3896 found = 1;
3897 else
3898 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3899 }
3900
3901 if (!found)
3902 {
3903 pos = make_number (around_charpos);
3904 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3905 while (!found && !EQ (pos, limit))
3906 {
3907 prop = Fget_char_property (pos, Qdisplay, Qnil);
3908 if (!NILP (prop) && display_prop_string_p (prop, string))
3909 found = 1;
3910 else
3911 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3912 limit);
3913 }
3914 }
3915
3916 return found ? XINT (pos) : 0;
3917 }
3918
3919
3920 \f
3921 /***********************************************************************
3922 `composition' property
3923 ***********************************************************************/
3924
3925 /* Set up iterator IT from `composition' property at its current
3926 position. Called from handle_stop. */
3927
3928 static enum prop_handled
3929 handle_composition_prop (it)
3930 struct it *it;
3931 {
3932 Lisp_Object prop, string;
3933 int pos, pos_byte, end;
3934 enum prop_handled handled = HANDLED_NORMALLY;
3935
3936 if (STRINGP (it->string))
3937 {
3938 pos = IT_STRING_CHARPOS (*it);
3939 pos_byte = IT_STRING_BYTEPOS (*it);
3940 string = it->string;
3941 }
3942 else
3943 {
3944 pos = IT_CHARPOS (*it);
3945 pos_byte = IT_BYTEPOS (*it);
3946 string = Qnil;
3947 }
3948
3949 /* If there's a valid composition and point is not inside of the
3950 composition (in the case that the composition is from the current
3951 buffer), draw a glyph composed from the composition components. */
3952 if (find_composition (pos, -1, &pos, &end, &prop, string)
3953 && COMPOSITION_VALID_P (pos, end, prop)
3954 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3955 {
3956 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3957
3958 if (id >= 0)
3959 {
3960 it->method = next_element_from_composition;
3961 it->cmp_id = id;
3962 it->cmp_len = COMPOSITION_LENGTH (prop);
3963 /* For a terminal, draw only the first character of the
3964 components. */
3965 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3966 it->len = (STRINGP (it->string)
3967 ? string_char_to_byte (it->string, end)
3968 : CHAR_TO_BYTE (end)) - pos_byte;
3969 it->stop_charpos = end;
3970 handled = HANDLED_RETURN;
3971 }
3972 }
3973
3974 return handled;
3975 }
3976
3977
3978 \f
3979 /***********************************************************************
3980 Overlay strings
3981 ***********************************************************************/
3982
3983 /* The following structure is used to record overlay strings for
3984 later sorting in load_overlay_strings. */
3985
3986 struct overlay_entry
3987 {
3988 Lisp_Object overlay;
3989 Lisp_Object string;
3990 int priority;
3991 int after_string_p;
3992 };
3993
3994
3995 /* Set up iterator IT from overlay strings at its current position.
3996 Called from handle_stop. */
3997
3998 static enum prop_handled
3999 handle_overlay_change (it)
4000 struct it *it;
4001 {
4002 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4003 return HANDLED_RECOMPUTE_PROPS;
4004 else
4005 return HANDLED_NORMALLY;
4006 }
4007
4008
4009 /* Set up the next overlay string for delivery by IT, if there is an
4010 overlay string to deliver. Called by set_iterator_to_next when the
4011 end of the current overlay string is reached. If there are more
4012 overlay strings to display, IT->string and
4013 IT->current.overlay_string_index are set appropriately here.
4014 Otherwise IT->string is set to nil. */
4015
4016 static void
4017 next_overlay_string (it)
4018 struct it *it;
4019 {
4020 ++it->current.overlay_string_index;
4021 if (it->current.overlay_string_index == it->n_overlay_strings)
4022 {
4023 /* No more overlay strings. Restore IT's settings to what
4024 they were before overlay strings were processed, and
4025 continue to deliver from current_buffer. */
4026 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4027
4028 pop_it (it);
4029 xassert (it->stop_charpos >= BEGV
4030 && it->stop_charpos <= it->end_charpos);
4031 it->string = Qnil;
4032 it->current.overlay_string_index = -1;
4033 SET_TEXT_POS (it->current.string_pos, -1, -1);
4034 it->n_overlay_strings = 0;
4035 it->method = next_element_from_buffer;
4036
4037 /* If we're at the end of the buffer, record that we have
4038 processed the overlay strings there already, so that
4039 next_element_from_buffer doesn't try it again. */
4040 if (IT_CHARPOS (*it) >= it->end_charpos)
4041 it->overlay_strings_at_end_processed_p = 1;
4042
4043 /* If we have to display `...' for invisible text, set
4044 the iterator up for that. */
4045 if (display_ellipsis_p)
4046 setup_for_ellipsis (it);
4047 }
4048 else
4049 {
4050 /* There are more overlay strings to process. If
4051 IT->current.overlay_string_index has advanced to a position
4052 where we must load IT->overlay_strings with more strings, do
4053 it. */
4054 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4055
4056 if (it->current.overlay_string_index && i == 0)
4057 load_overlay_strings (it, 0);
4058
4059 /* Initialize IT to deliver display elements from the overlay
4060 string. */
4061 it->string = it->overlay_strings[i];
4062 it->multibyte_p = STRING_MULTIBYTE (it->string);
4063 SET_TEXT_POS (it->current.string_pos, 0, 0);
4064 it->method = next_element_from_string;
4065 it->stop_charpos = 0;
4066 }
4067
4068 CHECK_IT (it);
4069 }
4070
4071
4072 /* Compare two overlay_entry structures E1 and E2. Used as a
4073 comparison function for qsort in load_overlay_strings. Overlay
4074 strings for the same position are sorted so that
4075
4076 1. All after-strings come in front of before-strings, except
4077 when they come from the same overlay.
4078
4079 2. Within after-strings, strings are sorted so that overlay strings
4080 from overlays with higher priorities come first.
4081
4082 2. Within before-strings, strings are sorted so that overlay
4083 strings from overlays with higher priorities come last.
4084
4085 Value is analogous to strcmp. */
4086
4087
4088 static int
4089 compare_overlay_entries (e1, e2)
4090 void *e1, *e2;
4091 {
4092 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4093 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4094 int result;
4095
4096 if (entry1->after_string_p != entry2->after_string_p)
4097 {
4098 /* Let after-strings appear in front of before-strings if
4099 they come from different overlays. */
4100 if (EQ (entry1->overlay, entry2->overlay))
4101 result = entry1->after_string_p ? 1 : -1;
4102 else
4103 result = entry1->after_string_p ? -1 : 1;
4104 }
4105 else if (entry1->after_string_p)
4106 /* After-strings sorted in order of decreasing priority. */
4107 result = entry2->priority - entry1->priority;
4108 else
4109 /* Before-strings sorted in order of increasing priority. */
4110 result = entry1->priority - entry2->priority;
4111
4112 return result;
4113 }
4114
4115
4116 /* Load the vector IT->overlay_strings with overlay strings from IT's
4117 current buffer position, or from CHARPOS if that is > 0. Set
4118 IT->n_overlays to the total number of overlay strings found.
4119
4120 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4121 a time. On entry into load_overlay_strings,
4122 IT->current.overlay_string_index gives the number of overlay
4123 strings that have already been loaded by previous calls to this
4124 function.
4125
4126 IT->add_overlay_start contains an additional overlay start
4127 position to consider for taking overlay strings from, if non-zero.
4128 This position comes into play when the overlay has an `invisible'
4129 property, and both before and after-strings. When we've skipped to
4130 the end of the overlay, because of its `invisible' property, we
4131 nevertheless want its before-string to appear.
4132 IT->add_overlay_start will contain the overlay start position
4133 in this case.
4134
4135 Overlay strings are sorted so that after-string strings come in
4136 front of before-string strings. Within before and after-strings,
4137 strings are sorted by overlay priority. See also function
4138 compare_overlay_entries. */
4139
4140 static void
4141 load_overlay_strings (it, charpos)
4142 struct it *it;
4143 int charpos;
4144 {
4145 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4146 Lisp_Object overlay, window, str, invisible;
4147 struct Lisp_Overlay *ov;
4148 int start, end;
4149 int size = 20;
4150 int n = 0, i, j, invis_p;
4151 struct overlay_entry *entries
4152 = (struct overlay_entry *) alloca (size * sizeof *entries);
4153
4154 if (charpos <= 0)
4155 charpos = IT_CHARPOS (*it);
4156
4157 /* Append the overlay string STRING of overlay OVERLAY to vector
4158 `entries' which has size `size' and currently contains `n'
4159 elements. AFTER_P non-zero means STRING is an after-string of
4160 OVERLAY. */
4161 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4162 do \
4163 { \
4164 Lisp_Object priority; \
4165 \
4166 if (n == size) \
4167 { \
4168 int new_size = 2 * size; \
4169 struct overlay_entry *old = entries; \
4170 entries = \
4171 (struct overlay_entry *) alloca (new_size \
4172 * sizeof *entries); \
4173 bcopy (old, entries, size * sizeof *entries); \
4174 size = new_size; \
4175 } \
4176 \
4177 entries[n].string = (STRING); \
4178 entries[n].overlay = (OVERLAY); \
4179 priority = Foverlay_get ((OVERLAY), Qpriority); \
4180 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4181 entries[n].after_string_p = (AFTER_P); \
4182 ++n; \
4183 } \
4184 while (0)
4185
4186 /* Process overlay before the overlay center. */
4187 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4188 {
4189 XSETMISC (overlay, ov);
4190 xassert (OVERLAYP (overlay));
4191 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4192 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4193
4194 if (end < charpos)
4195 break;
4196
4197 /* Skip this overlay if it doesn't start or end at IT's current
4198 position. */
4199 if (end != charpos && start != charpos)
4200 continue;
4201
4202 /* Skip this overlay if it doesn't apply to IT->w. */
4203 window = Foverlay_get (overlay, Qwindow);
4204 if (WINDOWP (window) && XWINDOW (window) != it->w)
4205 continue;
4206
4207 /* If the text ``under'' the overlay is invisible, both before-
4208 and after-strings from this overlay are visible; start and
4209 end position are indistinguishable. */
4210 invisible = Foverlay_get (overlay, Qinvisible);
4211 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4212
4213 /* If overlay has a non-empty before-string, record it. */
4214 if ((start == charpos || (end == charpos && invis_p))
4215 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4216 && SCHARS (str))
4217 RECORD_OVERLAY_STRING (overlay, str, 0);
4218
4219 /* If overlay has a non-empty after-string, record it. */
4220 if ((end == charpos || (start == charpos && invis_p))
4221 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4222 && SCHARS (str))
4223 RECORD_OVERLAY_STRING (overlay, str, 1);
4224 }
4225
4226 /* Process overlays after the overlay center. */
4227 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4228 {
4229 XSETMISC (overlay, ov);
4230 xassert (OVERLAYP (overlay));
4231 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4232 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4233
4234 if (start > charpos)
4235 break;
4236
4237 /* Skip this overlay if it doesn't start or end at IT's current
4238 position. */
4239 if (end != charpos && start != charpos)
4240 continue;
4241
4242 /* Skip this overlay if it doesn't apply to IT->w. */
4243 window = Foverlay_get (overlay, Qwindow);
4244 if (WINDOWP (window) && XWINDOW (window) != it->w)
4245 continue;
4246
4247 /* If the text ``under'' the overlay is invisible, it has a zero
4248 dimension, and both before- and after-strings apply. */
4249 invisible = Foverlay_get (overlay, Qinvisible);
4250 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4251
4252 /* If overlay has a non-empty before-string, record it. */
4253 if ((start == charpos || (end == charpos && invis_p))
4254 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4255 && SCHARS (str))
4256 RECORD_OVERLAY_STRING (overlay, str, 0);
4257
4258 /* If overlay has a non-empty after-string, record it. */
4259 if ((end == charpos || (start == charpos && invis_p))
4260 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4261 && SCHARS (str))
4262 RECORD_OVERLAY_STRING (overlay, str, 1);
4263 }
4264
4265 #undef RECORD_OVERLAY_STRING
4266
4267 /* Sort entries. */
4268 if (n > 1)
4269 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4270
4271 /* Record the total number of strings to process. */
4272 it->n_overlay_strings = n;
4273
4274 /* IT->current.overlay_string_index is the number of overlay strings
4275 that have already been consumed by IT. Copy some of the
4276 remaining overlay strings to IT->overlay_strings. */
4277 i = 0;
4278 j = it->current.overlay_string_index;
4279 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4280 it->overlay_strings[i++] = entries[j++].string;
4281
4282 CHECK_IT (it);
4283 }
4284
4285
4286 /* Get the first chunk of overlay strings at IT's current buffer
4287 position, or at CHARPOS if that is > 0. Value is non-zero if at
4288 least one overlay string was found. */
4289
4290 static int
4291 get_overlay_strings (it, charpos)
4292 struct it *it;
4293 int charpos;
4294 {
4295 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4296 process. This fills IT->overlay_strings with strings, and sets
4297 IT->n_overlay_strings to the total number of strings to process.
4298 IT->pos.overlay_string_index has to be set temporarily to zero
4299 because load_overlay_strings needs this; it must be set to -1
4300 when no overlay strings are found because a zero value would
4301 indicate a position in the first overlay string. */
4302 it->current.overlay_string_index = 0;
4303 load_overlay_strings (it, charpos);
4304
4305 /* If we found overlay strings, set up IT to deliver display
4306 elements from the first one. Otherwise set up IT to deliver
4307 from current_buffer. */
4308 if (it->n_overlay_strings)
4309 {
4310 /* Make sure we know settings in current_buffer, so that we can
4311 restore meaningful values when we're done with the overlay
4312 strings. */
4313 compute_stop_pos (it);
4314 xassert (it->face_id >= 0);
4315
4316 /* Save IT's settings. They are restored after all overlay
4317 strings have been processed. */
4318 xassert (it->sp == 0);
4319 push_it (it);
4320
4321 /* Set up IT to deliver display elements from the first overlay
4322 string. */
4323 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4324 it->string = it->overlay_strings[0];
4325 it->stop_charpos = 0;
4326 xassert (STRINGP (it->string));
4327 it->end_charpos = SCHARS (it->string);
4328 it->multibyte_p = STRING_MULTIBYTE (it->string);
4329 it->method = next_element_from_string;
4330 }
4331 else
4332 {
4333 it->string = Qnil;
4334 it->current.overlay_string_index = -1;
4335 it->method = next_element_from_buffer;
4336 }
4337
4338 CHECK_IT (it);
4339
4340 /* Value is non-zero if we found at least one overlay string. */
4341 return STRINGP (it->string);
4342 }
4343
4344
4345 \f
4346 /***********************************************************************
4347 Saving and restoring state
4348 ***********************************************************************/
4349
4350 /* Save current settings of IT on IT->stack. Called, for example,
4351 before setting up IT for an overlay string, to be able to restore
4352 IT's settings to what they were after the overlay string has been
4353 processed. */
4354
4355 static void
4356 push_it (it)
4357 struct it *it;
4358 {
4359 struct iterator_stack_entry *p;
4360
4361 xassert (it->sp < 2);
4362 p = it->stack + it->sp;
4363
4364 p->stop_charpos = it->stop_charpos;
4365 xassert (it->face_id >= 0);
4366 p->face_id = it->face_id;
4367 p->string = it->string;
4368 p->pos = it->current;
4369 p->end_charpos = it->end_charpos;
4370 p->string_nchars = it->string_nchars;
4371 p->area = it->area;
4372 p->multibyte_p = it->multibyte_p;
4373 p->slice = it->slice;
4374 p->space_width = it->space_width;
4375 p->font_height = it->font_height;
4376 p->voffset = it->voffset;
4377 p->string_from_display_prop_p = it->string_from_display_prop_p;
4378 p->display_ellipsis_p = 0;
4379 ++it->sp;
4380 }
4381
4382
4383 /* Restore IT's settings from IT->stack. Called, for example, when no
4384 more overlay strings must be processed, and we return to delivering
4385 display elements from a buffer, or when the end of a string from a
4386 `display' property is reached and we return to delivering display
4387 elements from an overlay string, or from a buffer. */
4388
4389 static void
4390 pop_it (it)
4391 struct it *it;
4392 {
4393 struct iterator_stack_entry *p;
4394
4395 xassert (it->sp > 0);
4396 --it->sp;
4397 p = it->stack + it->sp;
4398 it->stop_charpos = p->stop_charpos;
4399 it->face_id = p->face_id;
4400 it->string = p->string;
4401 it->current = p->pos;
4402 it->end_charpos = p->end_charpos;
4403 it->string_nchars = p->string_nchars;
4404 it->area = p->area;
4405 it->multibyte_p = p->multibyte_p;
4406 it->slice = p->slice;
4407 it->space_width = p->space_width;
4408 it->font_height = p->font_height;
4409 it->voffset = p->voffset;
4410 it->string_from_display_prop_p = p->string_from_display_prop_p;
4411 }
4412
4413
4414 \f
4415 /***********************************************************************
4416 Moving over lines
4417 ***********************************************************************/
4418
4419 /* Set IT's current position to the previous line start. */
4420
4421 static void
4422 back_to_previous_line_start (it)
4423 struct it *it;
4424 {
4425 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4426 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4427 }
4428
4429
4430 /* Move IT to the next line start.
4431
4432 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4433 we skipped over part of the text (as opposed to moving the iterator
4434 continuously over the text). Otherwise, don't change the value
4435 of *SKIPPED_P.
4436
4437 Newlines may come from buffer text, overlay strings, or strings
4438 displayed via the `display' property. That's the reason we can't
4439 simply use find_next_newline_no_quit.
4440
4441 Note that this function may not skip over invisible text that is so
4442 because of text properties and immediately follows a newline. If
4443 it would, function reseat_at_next_visible_line_start, when called
4444 from set_iterator_to_next, would effectively make invisible
4445 characters following a newline part of the wrong glyph row, which
4446 leads to wrong cursor motion. */
4447
4448 static int
4449 forward_to_next_line_start (it, skipped_p)
4450 struct it *it;
4451 int *skipped_p;
4452 {
4453 int old_selective, newline_found_p, n;
4454 const int MAX_NEWLINE_DISTANCE = 500;
4455
4456 /* If already on a newline, just consume it to avoid unintended
4457 skipping over invisible text below. */
4458 if (it->what == IT_CHARACTER
4459 && it->c == '\n'
4460 && CHARPOS (it->position) == IT_CHARPOS (*it))
4461 {
4462 set_iterator_to_next (it, 0);
4463 it->c = 0;
4464 return 1;
4465 }
4466
4467 /* Don't handle selective display in the following. It's (a)
4468 unnecessary because it's done by the caller, and (b) leads to an
4469 infinite recursion because next_element_from_ellipsis indirectly
4470 calls this function. */
4471 old_selective = it->selective;
4472 it->selective = 0;
4473
4474 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4475 from buffer text. */
4476 for (n = newline_found_p = 0;
4477 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4478 n += STRINGP (it->string) ? 0 : 1)
4479 {
4480 if (!get_next_display_element (it))
4481 return 0;
4482 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4483 set_iterator_to_next (it, 0);
4484 }
4485
4486 /* If we didn't find a newline near enough, see if we can use a
4487 short-cut. */
4488 if (!newline_found_p)
4489 {
4490 int start = IT_CHARPOS (*it);
4491 int limit = find_next_newline_no_quit (start, 1);
4492 Lisp_Object pos;
4493
4494 xassert (!STRINGP (it->string));
4495
4496 /* If there isn't any `display' property in sight, and no
4497 overlays, we can just use the position of the newline in
4498 buffer text. */
4499 if (it->stop_charpos >= limit
4500 || ((pos = Fnext_single_property_change (make_number (start),
4501 Qdisplay,
4502 Qnil, make_number (limit)),
4503 NILP (pos))
4504 && next_overlay_change (start) == ZV))
4505 {
4506 IT_CHARPOS (*it) = limit;
4507 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4508 *skipped_p = newline_found_p = 1;
4509 }
4510 else
4511 {
4512 while (get_next_display_element (it)
4513 && !newline_found_p)
4514 {
4515 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4516 set_iterator_to_next (it, 0);
4517 }
4518 }
4519 }
4520
4521 it->selective = old_selective;
4522 return newline_found_p;
4523 }
4524
4525
4526 /* Set IT's current position to the previous visible line start. Skip
4527 invisible text that is so either due to text properties or due to
4528 selective display. Caution: this does not change IT->current_x and
4529 IT->hpos. */
4530
4531 static void
4532 back_to_previous_visible_line_start (it)
4533 struct it *it;
4534 {
4535 int visible_p = 0;
4536
4537 /* Go back one newline if not on BEGV already. */
4538 if (IT_CHARPOS (*it) > BEGV)
4539 back_to_previous_line_start (it);
4540
4541 /* Move over lines that are invisible because of selective display
4542 or text properties. */
4543 while (IT_CHARPOS (*it) > BEGV
4544 && !visible_p)
4545 {
4546 visible_p = 1;
4547
4548 /* If selective > 0, then lines indented more than that values
4549 are invisible. */
4550 if (it->selective > 0
4551 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4552 (double) it->selective)) /* iftc */
4553 visible_p = 0;
4554 else
4555 {
4556 Lisp_Object prop;
4557
4558 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4559 Qinvisible, it->window);
4560 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4561 visible_p = 0;
4562 }
4563
4564 if (visible_p)
4565 {
4566 struct it it2 = *it;
4567
4568 if (handle_display_prop (&it2) == HANDLED_RETURN)
4569 visible_p = 0;
4570 }
4571
4572 /* Back one more newline if the current one is invisible. */
4573 if (!visible_p)
4574 back_to_previous_line_start (it);
4575 }
4576
4577 xassert (IT_CHARPOS (*it) >= BEGV);
4578 xassert (IT_CHARPOS (*it) == BEGV
4579 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4580 CHECK_IT (it);
4581 }
4582
4583
4584 /* Reseat iterator IT at the previous visible line start. Skip
4585 invisible text that is so either due to text properties or due to
4586 selective display. At the end, update IT's overlay information,
4587 face information etc. */
4588
4589 static void
4590 reseat_at_previous_visible_line_start (it)
4591 struct it *it;
4592 {
4593 back_to_previous_visible_line_start (it);
4594 reseat (it, it->current.pos, 1);
4595 CHECK_IT (it);
4596 }
4597
4598
4599 /* Reseat iterator IT on the next visible line start in the current
4600 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4601 preceding the line start. Skip over invisible text that is so
4602 because of selective display. Compute faces, overlays etc at the
4603 new position. Note that this function does not skip over text that
4604 is invisible because of text properties. */
4605
4606 static void
4607 reseat_at_next_visible_line_start (it, on_newline_p)
4608 struct it *it;
4609 int on_newline_p;
4610 {
4611 int newline_found_p, skipped_p = 0;
4612
4613 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4614
4615 /* Skip over lines that are invisible because they are indented
4616 more than the value of IT->selective. */
4617 if (it->selective > 0)
4618 while (IT_CHARPOS (*it) < ZV
4619 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4620 (double) it->selective)) /* iftc */
4621 {
4622 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4623 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4624 }
4625
4626 /* Position on the newline if that's what's requested. */
4627 if (on_newline_p && newline_found_p)
4628 {
4629 if (STRINGP (it->string))
4630 {
4631 if (IT_STRING_CHARPOS (*it) > 0)
4632 {
4633 --IT_STRING_CHARPOS (*it);
4634 --IT_STRING_BYTEPOS (*it);
4635 }
4636 }
4637 else if (IT_CHARPOS (*it) > BEGV)
4638 {
4639 --IT_CHARPOS (*it);
4640 --IT_BYTEPOS (*it);
4641 reseat (it, it->current.pos, 0);
4642 }
4643 }
4644 else if (skipped_p)
4645 reseat (it, it->current.pos, 0);
4646
4647 CHECK_IT (it);
4648 }
4649
4650
4651 \f
4652 /***********************************************************************
4653 Changing an iterator's position
4654 ***********************************************************************/
4655
4656 /* Change IT's current position to POS in current_buffer. If FORCE_P
4657 is non-zero, always check for text properties at the new position.
4658 Otherwise, text properties are only looked up if POS >=
4659 IT->check_charpos of a property. */
4660
4661 static void
4662 reseat (it, pos, force_p)
4663 struct it *it;
4664 struct text_pos pos;
4665 int force_p;
4666 {
4667 int original_pos = IT_CHARPOS (*it);
4668
4669 reseat_1 (it, pos, 0);
4670
4671 /* Determine where to check text properties. Avoid doing it
4672 where possible because text property lookup is very expensive. */
4673 if (force_p
4674 || CHARPOS (pos) > it->stop_charpos
4675 || CHARPOS (pos) < original_pos)
4676 handle_stop (it);
4677
4678 CHECK_IT (it);
4679 }
4680
4681
4682 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4683 IT->stop_pos to POS, also. */
4684
4685 static void
4686 reseat_1 (it, pos, set_stop_p)
4687 struct it *it;
4688 struct text_pos pos;
4689 int set_stop_p;
4690 {
4691 /* Don't call this function when scanning a C string. */
4692 xassert (it->s == NULL);
4693
4694 /* POS must be a reasonable value. */
4695 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4696
4697 it->current.pos = it->position = pos;
4698 XSETBUFFER (it->object, current_buffer);
4699 it->end_charpos = ZV;
4700 it->dpvec = NULL;
4701 it->current.dpvec_index = -1;
4702 it->current.overlay_string_index = -1;
4703 IT_STRING_CHARPOS (*it) = -1;
4704 IT_STRING_BYTEPOS (*it) = -1;
4705 it->string = Qnil;
4706 it->method = next_element_from_buffer;
4707 /* RMS: I added this to fix a bug in move_it_vertically_backward
4708 where it->area continued to relate to the starting point
4709 for the backward motion. Bug report from
4710 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4711 However, I am not sure whether reseat still does the right thing
4712 in general after this change. */
4713 it->area = TEXT_AREA;
4714 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4715 it->sp = 0;
4716 it->face_before_selective_p = 0;
4717
4718 if (set_stop_p)
4719 it->stop_charpos = CHARPOS (pos);
4720 }
4721
4722
4723 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4724 If S is non-null, it is a C string to iterate over. Otherwise,
4725 STRING gives a Lisp string to iterate over.
4726
4727 If PRECISION > 0, don't return more then PRECISION number of
4728 characters from the string.
4729
4730 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4731 characters have been returned. FIELD_WIDTH < 0 means an infinite
4732 field width.
4733
4734 MULTIBYTE = 0 means disable processing of multibyte characters,
4735 MULTIBYTE > 0 means enable it,
4736 MULTIBYTE < 0 means use IT->multibyte_p.
4737
4738 IT must be initialized via a prior call to init_iterator before
4739 calling this function. */
4740
4741 static void
4742 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4743 struct it *it;
4744 unsigned char *s;
4745 Lisp_Object string;
4746 int charpos;
4747 int precision, field_width, multibyte;
4748 {
4749 /* No region in strings. */
4750 it->region_beg_charpos = it->region_end_charpos = -1;
4751
4752 /* No text property checks performed by default, but see below. */
4753 it->stop_charpos = -1;
4754
4755 /* Set iterator position and end position. */
4756 bzero (&it->current, sizeof it->current);
4757 it->current.overlay_string_index = -1;
4758 it->current.dpvec_index = -1;
4759 xassert (charpos >= 0);
4760
4761 /* If STRING is specified, use its multibyteness, otherwise use the
4762 setting of MULTIBYTE, if specified. */
4763 if (multibyte >= 0)
4764 it->multibyte_p = multibyte > 0;
4765
4766 if (s == NULL)
4767 {
4768 xassert (STRINGP (string));
4769 it->string = string;
4770 it->s = NULL;
4771 it->end_charpos = it->string_nchars = SCHARS (string);
4772 it->method = next_element_from_string;
4773 it->current.string_pos = string_pos (charpos, string);
4774 }
4775 else
4776 {
4777 it->s = s;
4778 it->string = Qnil;
4779
4780 /* Note that we use IT->current.pos, not it->current.string_pos,
4781 for displaying C strings. */
4782 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4783 if (it->multibyte_p)
4784 {
4785 it->current.pos = c_string_pos (charpos, s, 1);
4786 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4787 }
4788 else
4789 {
4790 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4791 it->end_charpos = it->string_nchars = strlen (s);
4792 }
4793
4794 it->method = next_element_from_c_string;
4795 }
4796
4797 /* PRECISION > 0 means don't return more than PRECISION characters
4798 from the string. */
4799 if (precision > 0 && it->end_charpos - charpos > precision)
4800 it->end_charpos = it->string_nchars = charpos + precision;
4801
4802 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4803 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4804 FIELD_WIDTH < 0 means infinite field width. This is useful for
4805 padding with `-' at the end of a mode line. */
4806 if (field_width < 0)
4807 field_width = INFINITY;
4808 if (field_width > it->end_charpos - charpos)
4809 it->end_charpos = charpos + field_width;
4810
4811 /* Use the standard display table for displaying strings. */
4812 if (DISP_TABLE_P (Vstandard_display_table))
4813 it->dp = XCHAR_TABLE (Vstandard_display_table);
4814
4815 it->stop_charpos = charpos;
4816 CHECK_IT (it);
4817 }
4818
4819
4820 \f
4821 /***********************************************************************
4822 Iteration
4823 ***********************************************************************/
4824
4825 /* Load IT's display element fields with information about the next
4826 display element from the current position of IT. Value is zero if
4827 end of buffer (or C string) is reached. */
4828
4829 int
4830 get_next_display_element (it)
4831 struct it *it;
4832 {
4833 /* Non-zero means that we found a display element. Zero means that
4834 we hit the end of what we iterate over. Performance note: the
4835 function pointer `method' used here turns out to be faster than
4836 using a sequence of if-statements. */
4837 int success_p = (*it->method) (it);
4838
4839 if (it->what == IT_CHARACTER)
4840 {
4841 /* Map via display table or translate control characters.
4842 IT->c, IT->len etc. have been set to the next character by
4843 the function call above. If we have a display table, and it
4844 contains an entry for IT->c, translate it. Don't do this if
4845 IT->c itself comes from a display table, otherwise we could
4846 end up in an infinite recursion. (An alternative could be to
4847 count the recursion depth of this function and signal an
4848 error when a certain maximum depth is reached.) Is it worth
4849 it? */
4850 if (success_p && it->dpvec == NULL)
4851 {
4852 Lisp_Object dv;
4853
4854 if (it->dp
4855 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4856 VECTORP (dv)))
4857 {
4858 struct Lisp_Vector *v = XVECTOR (dv);
4859
4860 /* Return the first character from the display table
4861 entry, if not empty. If empty, don't display the
4862 current character. */
4863 if (v->size)
4864 {
4865 it->dpvec_char_len = it->len;
4866 it->dpvec = v->contents;
4867 it->dpend = v->contents + v->size;
4868 it->current.dpvec_index = 0;
4869 it->method = next_element_from_display_vector;
4870 success_p = get_next_display_element (it);
4871 }
4872 else
4873 {
4874 set_iterator_to_next (it, 0);
4875 success_p = get_next_display_element (it);
4876 }
4877 }
4878
4879 /* Translate control characters into `\003' or `^C' form.
4880 Control characters coming from a display table entry are
4881 currently not translated because we use IT->dpvec to hold
4882 the translation. This could easily be changed but I
4883 don't believe that it is worth doing.
4884
4885 If it->multibyte_p is nonzero, eight-bit characters and
4886 non-printable multibyte characters are also translated to
4887 octal form.
4888
4889 If it->multibyte_p is zero, eight-bit characters that
4890 don't have corresponding multibyte char code are also
4891 translated to octal form. */
4892 else if ((it->c < ' '
4893 && (it->area != TEXT_AREA
4894 || (it->c != '\n' && it->c != '\t')))
4895 || (it->multibyte_p
4896 ? ((it->c >= 127
4897 && it->len == 1)
4898 || !CHAR_PRINTABLE_P (it->c))
4899 : (it->c >= 127
4900 && (!unibyte_display_via_language_environment
4901 || it->c == unibyte_char_to_multibyte (it->c)))))
4902 {
4903 /* IT->c is a control character which must be displayed
4904 either as '\003' or as `^C' where the '\\' and '^'
4905 can be defined in the display table. Fill
4906 IT->ctl_chars with glyphs for what we have to
4907 display. Then, set IT->dpvec to these glyphs. */
4908 GLYPH g;
4909
4910 if (it->c < 128 && it->ctl_arrow_p)
4911 {
4912 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4913 if (it->dp
4914 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4915 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4916 g = XINT (DISP_CTRL_GLYPH (it->dp));
4917 else
4918 g = FAST_MAKE_GLYPH ('^', 0);
4919 XSETINT (it->ctl_chars[0], g);
4920
4921 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4922 XSETINT (it->ctl_chars[1], g);
4923
4924 /* Set up IT->dpvec and return first character from it. */
4925 it->dpvec_char_len = it->len;
4926 it->dpvec = it->ctl_chars;
4927 it->dpend = it->dpvec + 2;
4928 it->current.dpvec_index = 0;
4929 it->method = next_element_from_display_vector;
4930 get_next_display_element (it);
4931 }
4932 else
4933 {
4934 unsigned char str[MAX_MULTIBYTE_LENGTH];
4935 int len;
4936 int i;
4937 GLYPH escape_glyph;
4938
4939 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4940 if (it->dp
4941 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4942 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4943 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4944 else
4945 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4946
4947 if (SINGLE_BYTE_CHAR_P (it->c))
4948 str[0] = it->c, len = 1;
4949 else
4950 {
4951 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4952 if (len < 0)
4953 {
4954 /* It's an invalid character, which
4955 shouldn't happen actually, but due to
4956 bugs it may happen. Let's print the char
4957 as is, there's not much meaningful we can
4958 do with it. */
4959 str[0] = it->c;
4960 str[1] = it->c >> 8;
4961 str[2] = it->c >> 16;
4962 str[3] = it->c >> 24;
4963 len = 4;
4964 }
4965 }
4966
4967 for (i = 0; i < len; i++)
4968 {
4969 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4970 /* Insert three more glyphs into IT->ctl_chars for
4971 the octal display of the character. */
4972 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4973 XSETINT (it->ctl_chars[i * 4 + 1], g);
4974 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4975 XSETINT (it->ctl_chars[i * 4 + 2], g);
4976 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4977 XSETINT (it->ctl_chars[i * 4 + 3], g);
4978 }
4979
4980 /* Set up IT->dpvec and return the first character
4981 from it. */
4982 it->dpvec_char_len = it->len;
4983 it->dpvec = it->ctl_chars;
4984 it->dpend = it->dpvec + len * 4;
4985 it->current.dpvec_index = 0;
4986 it->method = next_element_from_display_vector;
4987 get_next_display_element (it);
4988 }
4989 }
4990 }
4991
4992 /* Adjust face id for a multibyte character. There are no
4993 multibyte character in unibyte text. */
4994 if (it->multibyte_p
4995 && success_p
4996 && FRAME_WINDOW_P (it->f))
4997 {
4998 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4999 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5000 }
5001 }
5002
5003 /* Is this character the last one of a run of characters with
5004 box? If yes, set IT->end_of_box_run_p to 1. */
5005 if (it->face_box_p
5006 && it->s == NULL)
5007 {
5008 int face_id;
5009 struct face *face;
5010
5011 it->end_of_box_run_p
5012 = ((face_id = face_after_it_pos (it),
5013 face_id != it->face_id)
5014 && (face = FACE_FROM_ID (it->f, face_id),
5015 face->box == FACE_NO_BOX));
5016 }
5017
5018 /* Value is 0 if end of buffer or string reached. */
5019 return success_p;
5020 }
5021
5022
5023 /* Move IT to the next display element.
5024
5025 RESEAT_P non-zero means if called on a newline in buffer text,
5026 skip to the next visible line start.
5027
5028 Functions get_next_display_element and set_iterator_to_next are
5029 separate because I find this arrangement easier to handle than a
5030 get_next_display_element function that also increments IT's
5031 position. The way it is we can first look at an iterator's current
5032 display element, decide whether it fits on a line, and if it does,
5033 increment the iterator position. The other way around we probably
5034 would either need a flag indicating whether the iterator has to be
5035 incremented the next time, or we would have to implement a
5036 decrement position function which would not be easy to write. */
5037
5038 void
5039 set_iterator_to_next (it, reseat_p)
5040 struct it *it;
5041 int reseat_p;
5042 {
5043 /* Reset flags indicating start and end of a sequence of characters
5044 with box. Reset them at the start of this function because
5045 moving the iterator to a new position might set them. */
5046 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5047
5048 if (it->method == next_element_from_buffer)
5049 {
5050 /* The current display element of IT is a character from
5051 current_buffer. Advance in the buffer, and maybe skip over
5052 invisible lines that are so because of selective display. */
5053 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5054 reseat_at_next_visible_line_start (it, 0);
5055 else
5056 {
5057 xassert (it->len != 0);
5058 IT_BYTEPOS (*it) += it->len;
5059 IT_CHARPOS (*it) += 1;
5060 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5061 }
5062 }
5063 else if (it->method == next_element_from_composition)
5064 {
5065 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5066 if (STRINGP (it->string))
5067 {
5068 IT_STRING_BYTEPOS (*it) += it->len;
5069 IT_STRING_CHARPOS (*it) += it->cmp_len;
5070 it->method = next_element_from_string;
5071 goto consider_string_end;
5072 }
5073 else
5074 {
5075 IT_BYTEPOS (*it) += it->len;
5076 IT_CHARPOS (*it) += it->cmp_len;
5077 it->method = next_element_from_buffer;
5078 }
5079 }
5080 else if (it->method == next_element_from_c_string)
5081 {
5082 /* Current display element of IT is from a C string. */
5083 IT_BYTEPOS (*it) += it->len;
5084 IT_CHARPOS (*it) += 1;
5085 }
5086 else if (it->method == next_element_from_display_vector)
5087 {
5088 /* Current display element of IT is from a display table entry.
5089 Advance in the display table definition. Reset it to null if
5090 end reached, and continue with characters from buffers/
5091 strings. */
5092 ++it->current.dpvec_index;
5093
5094 /* Restore face of the iterator to what they were before the
5095 display vector entry (these entries may contain faces). */
5096 it->face_id = it->saved_face_id;
5097
5098 if (it->dpvec + it->current.dpvec_index == it->dpend)
5099 {
5100 if (it->s)
5101 it->method = next_element_from_c_string;
5102 else if (STRINGP (it->string))
5103 it->method = next_element_from_string;
5104 else
5105 it->method = next_element_from_buffer;
5106
5107 it->dpvec = NULL;
5108 it->current.dpvec_index = -1;
5109
5110 /* Skip over characters which were displayed via IT->dpvec. */
5111 if (it->dpvec_char_len < 0)
5112 reseat_at_next_visible_line_start (it, 1);
5113 else if (it->dpvec_char_len > 0)
5114 {
5115 it->len = it->dpvec_char_len;
5116 set_iterator_to_next (it, reseat_p);
5117 }
5118 }
5119 }
5120 else if (it->method == next_element_from_string)
5121 {
5122 /* Current display element is a character from a Lisp string. */
5123 xassert (it->s == NULL && STRINGP (it->string));
5124 IT_STRING_BYTEPOS (*it) += it->len;
5125 IT_STRING_CHARPOS (*it) += 1;
5126
5127 consider_string_end:
5128
5129 if (it->current.overlay_string_index >= 0)
5130 {
5131 /* IT->string is an overlay string. Advance to the
5132 next, if there is one. */
5133 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5134 next_overlay_string (it);
5135 }
5136 else
5137 {
5138 /* IT->string is not an overlay string. If we reached
5139 its end, and there is something on IT->stack, proceed
5140 with what is on the stack. This can be either another
5141 string, this time an overlay string, or a buffer. */
5142 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5143 && it->sp > 0)
5144 {
5145 pop_it (it);
5146 if (!STRINGP (it->string))
5147 it->method = next_element_from_buffer;
5148 else
5149 goto consider_string_end;
5150 }
5151 }
5152 }
5153 else if (it->method == next_element_from_image
5154 || it->method == next_element_from_stretch)
5155 {
5156 /* The position etc with which we have to proceed are on
5157 the stack. The position may be at the end of a string,
5158 if the `display' property takes up the whole string. */
5159 pop_it (it);
5160 it->image_id = 0;
5161 if (STRINGP (it->string))
5162 {
5163 it->method = next_element_from_string;
5164 goto consider_string_end;
5165 }
5166 else
5167 it->method = next_element_from_buffer;
5168 }
5169 else
5170 /* There are no other methods defined, so this should be a bug. */
5171 abort ();
5172
5173 xassert (it->method != next_element_from_string
5174 || (STRINGP (it->string)
5175 && IT_STRING_CHARPOS (*it) >= 0));
5176 }
5177
5178
5179 /* Load IT's display element fields with information about the next
5180 display element which comes from a display table entry or from the
5181 result of translating a control character to one of the forms `^C'
5182 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5183
5184 static int
5185 next_element_from_display_vector (it)
5186 struct it *it;
5187 {
5188 /* Precondition. */
5189 xassert (it->dpvec && it->current.dpvec_index >= 0);
5190
5191 /* Remember the current face id in case glyphs specify faces.
5192 IT's face is restored in set_iterator_to_next. */
5193 it->saved_face_id = it->face_id;
5194
5195 if (INTEGERP (*it->dpvec)
5196 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5197 {
5198 int lface_id;
5199 GLYPH g;
5200
5201 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5202 it->c = FAST_GLYPH_CHAR (g);
5203 it->len = CHAR_BYTES (it->c);
5204
5205 /* The entry may contain a face id to use. Such a face id is
5206 the id of a Lisp face, not a realized face. A face id of
5207 zero means no face is specified. */
5208 lface_id = FAST_GLYPH_FACE (g);
5209 if (lface_id)
5210 {
5211 /* The function returns -1 if lface_id is invalid. */
5212 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5213 if (face_id >= 0)
5214 it->face_id = face_id;
5215 }
5216 }
5217 else
5218 /* Display table entry is invalid. Return a space. */
5219 it->c = ' ', it->len = 1;
5220
5221 /* Don't change position and object of the iterator here. They are
5222 still the values of the character that had this display table
5223 entry or was translated, and that's what we want. */
5224 it->what = IT_CHARACTER;
5225 return 1;
5226 }
5227
5228
5229 /* Load IT with the next display element from Lisp string IT->string.
5230 IT->current.string_pos is the current position within the string.
5231 If IT->current.overlay_string_index >= 0, the Lisp string is an
5232 overlay string. */
5233
5234 static int
5235 next_element_from_string (it)
5236 struct it *it;
5237 {
5238 struct text_pos position;
5239
5240 xassert (STRINGP (it->string));
5241 xassert (IT_STRING_CHARPOS (*it) >= 0);
5242 position = it->current.string_pos;
5243
5244 /* Time to check for invisible text? */
5245 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5246 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5247 {
5248 handle_stop (it);
5249
5250 /* Since a handler may have changed IT->method, we must
5251 recurse here. */
5252 return get_next_display_element (it);
5253 }
5254
5255 if (it->current.overlay_string_index >= 0)
5256 {
5257 /* Get the next character from an overlay string. In overlay
5258 strings, There is no field width or padding with spaces to
5259 do. */
5260 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5261 {
5262 it->what = IT_EOB;
5263 return 0;
5264 }
5265 else if (STRING_MULTIBYTE (it->string))
5266 {
5267 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5268 const unsigned char *s = (SDATA (it->string)
5269 + IT_STRING_BYTEPOS (*it));
5270 it->c = string_char_and_length (s, remaining, &it->len);
5271 }
5272 else
5273 {
5274 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5275 it->len = 1;
5276 }
5277 }
5278 else
5279 {
5280 /* Get the next character from a Lisp string that is not an
5281 overlay string. Such strings come from the mode line, for
5282 example. We may have to pad with spaces, or truncate the
5283 string. See also next_element_from_c_string. */
5284 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5285 {
5286 it->what = IT_EOB;
5287 return 0;
5288 }
5289 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5290 {
5291 /* Pad with spaces. */
5292 it->c = ' ', it->len = 1;
5293 CHARPOS (position) = BYTEPOS (position) = -1;
5294 }
5295 else if (STRING_MULTIBYTE (it->string))
5296 {
5297 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5298 const unsigned char *s = (SDATA (it->string)
5299 + IT_STRING_BYTEPOS (*it));
5300 it->c = string_char_and_length (s, maxlen, &it->len);
5301 }
5302 else
5303 {
5304 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5305 it->len = 1;
5306 }
5307 }
5308
5309 /* Record what we have and where it came from. Note that we store a
5310 buffer position in IT->position although it could arguably be a
5311 string position. */
5312 it->what = IT_CHARACTER;
5313 it->object = it->string;
5314 it->position = position;
5315 return 1;
5316 }
5317
5318
5319 /* Load IT with next display element from C string IT->s.
5320 IT->string_nchars is the maximum number of characters to return
5321 from the string. IT->end_charpos may be greater than
5322 IT->string_nchars when this function is called, in which case we
5323 may have to return padding spaces. Value is zero if end of string
5324 reached, including padding spaces. */
5325
5326 static int
5327 next_element_from_c_string (it)
5328 struct it *it;
5329 {
5330 int success_p = 1;
5331
5332 xassert (it->s);
5333 it->what = IT_CHARACTER;
5334 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5335 it->object = Qnil;
5336
5337 /* IT's position can be greater IT->string_nchars in case a field
5338 width or precision has been specified when the iterator was
5339 initialized. */
5340 if (IT_CHARPOS (*it) >= it->end_charpos)
5341 {
5342 /* End of the game. */
5343 it->what = IT_EOB;
5344 success_p = 0;
5345 }
5346 else if (IT_CHARPOS (*it) >= it->string_nchars)
5347 {
5348 /* Pad with spaces. */
5349 it->c = ' ', it->len = 1;
5350 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5351 }
5352 else if (it->multibyte_p)
5353 {
5354 /* Implementation note: The calls to strlen apparently aren't a
5355 performance problem because there is no noticeable performance
5356 difference between Emacs running in unibyte or multibyte mode. */
5357 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5358 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5359 maxlen, &it->len);
5360 }
5361 else
5362 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5363
5364 return success_p;
5365 }
5366
5367
5368 /* Set up IT to return characters from an ellipsis, if appropriate.
5369 The definition of the ellipsis glyphs may come from a display table
5370 entry. This function Fills IT with the first glyph from the
5371 ellipsis if an ellipsis is to be displayed. */
5372
5373 static int
5374 next_element_from_ellipsis (it)
5375 struct it *it;
5376 {
5377 if (it->selective_display_ellipsis_p)
5378 {
5379 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5380 {
5381 /* Use the display table definition for `...'. Invalid glyphs
5382 will be handled by the method returning elements from dpvec. */
5383 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5384 it->dpvec_char_len = it->len;
5385 it->dpvec = v->contents;
5386 it->dpend = v->contents + v->size;
5387 it->current.dpvec_index = 0;
5388 it->method = next_element_from_display_vector;
5389 }
5390 else
5391 {
5392 /* Use default `...' which is stored in default_invis_vector. */
5393 it->dpvec_char_len = it->len;
5394 it->dpvec = default_invis_vector;
5395 it->dpend = default_invis_vector + 3;
5396 it->current.dpvec_index = 0;
5397 it->method = next_element_from_display_vector;
5398 }
5399 }
5400 else
5401 {
5402 /* The face at the current position may be different from the
5403 face we find after the invisible text. Remember what it
5404 was in IT->saved_face_id, and signal that it's there by
5405 setting face_before_selective_p. */
5406 it->saved_face_id = it->face_id;
5407 it->method = next_element_from_buffer;
5408 reseat_at_next_visible_line_start (it, 1);
5409 it->face_before_selective_p = 1;
5410 }
5411
5412 return get_next_display_element (it);
5413 }
5414
5415
5416 /* Deliver an image display element. The iterator IT is already
5417 filled with image information (done in handle_display_prop). Value
5418 is always 1. */
5419
5420
5421 static int
5422 next_element_from_image (it)
5423 struct it *it;
5424 {
5425 it->what = IT_IMAGE;
5426 return 1;
5427 }
5428
5429
5430 /* Fill iterator IT with next display element from a stretch glyph
5431 property. IT->object is the value of the text property. Value is
5432 always 1. */
5433
5434 static int
5435 next_element_from_stretch (it)
5436 struct it *it;
5437 {
5438 it->what = IT_STRETCH;
5439 return 1;
5440 }
5441
5442
5443 /* Load IT with the next display element from current_buffer. Value
5444 is zero if end of buffer reached. IT->stop_charpos is the next
5445 position at which to stop and check for text properties or buffer
5446 end. */
5447
5448 static int
5449 next_element_from_buffer (it)
5450 struct it *it;
5451 {
5452 int success_p = 1;
5453
5454 /* Check this assumption, otherwise, we would never enter the
5455 if-statement, below. */
5456 xassert (IT_CHARPOS (*it) >= BEGV
5457 && IT_CHARPOS (*it) <= it->stop_charpos);
5458
5459 if (IT_CHARPOS (*it) >= it->stop_charpos)
5460 {
5461 if (IT_CHARPOS (*it) >= it->end_charpos)
5462 {
5463 int overlay_strings_follow_p;
5464
5465 /* End of the game, except when overlay strings follow that
5466 haven't been returned yet. */
5467 if (it->overlay_strings_at_end_processed_p)
5468 overlay_strings_follow_p = 0;
5469 else
5470 {
5471 it->overlay_strings_at_end_processed_p = 1;
5472 overlay_strings_follow_p = get_overlay_strings (it, 0);
5473 }
5474
5475 if (overlay_strings_follow_p)
5476 success_p = get_next_display_element (it);
5477 else
5478 {
5479 it->what = IT_EOB;
5480 it->position = it->current.pos;
5481 success_p = 0;
5482 }
5483 }
5484 else
5485 {
5486 handle_stop (it);
5487 return get_next_display_element (it);
5488 }
5489 }
5490 else
5491 {
5492 /* No face changes, overlays etc. in sight, so just return a
5493 character from current_buffer. */
5494 unsigned char *p;
5495
5496 /* Maybe run the redisplay end trigger hook. Performance note:
5497 This doesn't seem to cost measurable time. */
5498 if (it->redisplay_end_trigger_charpos
5499 && it->glyph_row
5500 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5501 run_redisplay_end_trigger_hook (it);
5502
5503 /* Get the next character, maybe multibyte. */
5504 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5505 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5506 {
5507 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5508 - IT_BYTEPOS (*it));
5509 it->c = string_char_and_length (p, maxlen, &it->len);
5510 }
5511 else
5512 it->c = *p, it->len = 1;
5513
5514 /* Record what we have and where it came from. */
5515 it->what = IT_CHARACTER;;
5516 it->object = it->w->buffer;
5517 it->position = it->current.pos;
5518
5519 /* Normally we return the character found above, except when we
5520 really want to return an ellipsis for selective display. */
5521 if (it->selective)
5522 {
5523 if (it->c == '\n')
5524 {
5525 /* A value of selective > 0 means hide lines indented more
5526 than that number of columns. */
5527 if (it->selective > 0
5528 && IT_CHARPOS (*it) + 1 < ZV
5529 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5530 IT_BYTEPOS (*it) + 1,
5531 (double) it->selective)) /* iftc */
5532 {
5533 success_p = next_element_from_ellipsis (it);
5534 it->dpvec_char_len = -1;
5535 }
5536 }
5537 else if (it->c == '\r' && it->selective == -1)
5538 {
5539 /* A value of selective == -1 means that everything from the
5540 CR to the end of the line is invisible, with maybe an
5541 ellipsis displayed for it. */
5542 success_p = next_element_from_ellipsis (it);
5543 it->dpvec_char_len = -1;
5544 }
5545 }
5546 }
5547
5548 /* Value is zero if end of buffer reached. */
5549 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5550 return success_p;
5551 }
5552
5553
5554 /* Run the redisplay end trigger hook for IT. */
5555
5556 static void
5557 run_redisplay_end_trigger_hook (it)
5558 struct it *it;
5559 {
5560 Lisp_Object args[3];
5561
5562 /* IT->glyph_row should be non-null, i.e. we should be actually
5563 displaying something, or otherwise we should not run the hook. */
5564 xassert (it->glyph_row);
5565
5566 /* Set up hook arguments. */
5567 args[0] = Qredisplay_end_trigger_functions;
5568 args[1] = it->window;
5569 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5570 it->redisplay_end_trigger_charpos = 0;
5571
5572 /* Since we are *trying* to run these functions, don't try to run
5573 them again, even if they get an error. */
5574 it->w->redisplay_end_trigger = Qnil;
5575 Frun_hook_with_args (3, args);
5576
5577 /* Notice if it changed the face of the character we are on. */
5578 handle_face_prop (it);
5579 }
5580
5581
5582 /* Deliver a composition display element. The iterator IT is already
5583 filled with composition information (done in
5584 handle_composition_prop). Value is always 1. */
5585
5586 static int
5587 next_element_from_composition (it)
5588 struct it *it;
5589 {
5590 it->what = IT_COMPOSITION;
5591 it->position = (STRINGP (it->string)
5592 ? it->current.string_pos
5593 : it->current.pos);
5594 return 1;
5595 }
5596
5597
5598 \f
5599 /***********************************************************************
5600 Moving an iterator without producing glyphs
5601 ***********************************************************************/
5602
5603 /* Move iterator IT to a specified buffer or X position within one
5604 line on the display without producing glyphs.
5605
5606 OP should be a bit mask including some or all of these bits:
5607 MOVE_TO_X: Stop on reaching x-position TO_X.
5608 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5609 Regardless of OP's value, stop in reaching the end of the display line.
5610
5611 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5612 This means, in particular, that TO_X includes window's horizontal
5613 scroll amount.
5614
5615 The return value has several possible values that
5616 say what condition caused the scan to stop:
5617
5618 MOVE_POS_MATCH_OR_ZV
5619 - when TO_POS or ZV was reached.
5620
5621 MOVE_X_REACHED
5622 -when TO_X was reached before TO_POS or ZV were reached.
5623
5624 MOVE_LINE_CONTINUED
5625 - when we reached the end of the display area and the line must
5626 be continued.
5627
5628 MOVE_LINE_TRUNCATED
5629 - when we reached the end of the display area and the line is
5630 truncated.
5631
5632 MOVE_NEWLINE_OR_CR
5633 - when we stopped at a line end, i.e. a newline or a CR and selective
5634 display is on. */
5635
5636 static enum move_it_result
5637 move_it_in_display_line_to (it, to_charpos, to_x, op)
5638 struct it *it;
5639 int to_charpos, to_x, op;
5640 {
5641 enum move_it_result result = MOVE_UNDEFINED;
5642 struct glyph_row *saved_glyph_row;
5643
5644 /* Don't produce glyphs in produce_glyphs. */
5645 saved_glyph_row = it->glyph_row;
5646 it->glyph_row = NULL;
5647
5648 #define BUFFER_POS_REACHED_P() \
5649 ((op & MOVE_TO_POS) != 0 \
5650 && BUFFERP (it->object) \
5651 && IT_CHARPOS (*it) >= to_charpos)
5652
5653 while (1)
5654 {
5655 int x, i, ascent = 0, descent = 0;
5656
5657 /* Stop when ZV reached.
5658 We used to stop here when TO_CHARPOS reached as well, but that is
5659 too soon if this glyph does not fit on this line. So we handle it
5660 explicitly below. */
5661 if (!get_next_display_element (it)
5662 || (it->truncate_lines_p
5663 && BUFFER_POS_REACHED_P ()))
5664 {
5665 result = MOVE_POS_MATCH_OR_ZV;
5666 break;
5667 }
5668
5669 /* The call to produce_glyphs will get the metrics of the
5670 display element IT is loaded with. We record in x the
5671 x-position before this display element in case it does not
5672 fit on the line. */
5673 x = it->current_x;
5674
5675 /* Remember the line height so far in case the next element doesn't
5676 fit on the line. */
5677 if (!it->truncate_lines_p)
5678 {
5679 ascent = it->max_ascent;
5680 descent = it->max_descent;
5681 }
5682
5683 PRODUCE_GLYPHS (it);
5684
5685 if (it->area != TEXT_AREA)
5686 {
5687 set_iterator_to_next (it, 1);
5688 continue;
5689 }
5690
5691 /* The number of glyphs we get back in IT->nglyphs will normally
5692 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5693 character on a terminal frame, or (iii) a line end. For the
5694 second case, IT->nglyphs - 1 padding glyphs will be present
5695 (on X frames, there is only one glyph produced for a
5696 composite character.
5697
5698 The behavior implemented below means, for continuation lines,
5699 that as many spaces of a TAB as fit on the current line are
5700 displayed there. For terminal frames, as many glyphs of a
5701 multi-glyph character are displayed in the current line, too.
5702 This is what the old redisplay code did, and we keep it that
5703 way. Under X, the whole shape of a complex character must
5704 fit on the line or it will be completely displayed in the
5705 next line.
5706
5707 Note that both for tabs and padding glyphs, all glyphs have
5708 the same width. */
5709 if (it->nglyphs)
5710 {
5711 /* More than one glyph or glyph doesn't fit on line. All
5712 glyphs have the same width. */
5713 int single_glyph_width = it->pixel_width / it->nglyphs;
5714 int new_x;
5715
5716 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5717 {
5718 new_x = x + single_glyph_width;
5719
5720 /* We want to leave anything reaching TO_X to the caller. */
5721 if ((op & MOVE_TO_X) && new_x > to_x)
5722 {
5723 if (BUFFER_POS_REACHED_P ())
5724 goto buffer_pos_reached;
5725 it->current_x = x;
5726 result = MOVE_X_REACHED;
5727 break;
5728 }
5729 else if (/* Lines are continued. */
5730 !it->truncate_lines_p
5731 && (/* And glyph doesn't fit on the line. */
5732 new_x > it->last_visible_x
5733 /* Or it fits exactly and we're on a window
5734 system frame. */
5735 || (new_x == it->last_visible_x
5736 && FRAME_WINDOW_P (it->f))))
5737 {
5738 if (/* IT->hpos == 0 means the very first glyph
5739 doesn't fit on the line, e.g. a wide image. */
5740 it->hpos == 0
5741 || (new_x == it->last_visible_x
5742 && FRAME_WINDOW_P (it->f)))
5743 {
5744 ++it->hpos;
5745 it->current_x = new_x;
5746 if (i == it->nglyphs - 1)
5747 {
5748 set_iterator_to_next (it, 1);
5749 #ifdef HAVE_WINDOW_SYSTEM
5750 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5751 {
5752 if (!get_next_display_element (it))
5753 {
5754 result = MOVE_POS_MATCH_OR_ZV;
5755 break;
5756 }
5757 if (BUFFER_POS_REACHED_P ())
5758 {
5759 if (ITERATOR_AT_END_OF_LINE_P (it))
5760 result = MOVE_POS_MATCH_OR_ZV;
5761 else
5762 result = MOVE_LINE_CONTINUED;
5763 break;
5764 }
5765 if (ITERATOR_AT_END_OF_LINE_P (it))
5766 {
5767 result = MOVE_NEWLINE_OR_CR;
5768 break;
5769 }
5770 }
5771 #endif /* HAVE_WINDOW_SYSTEM */
5772 }
5773 }
5774 else
5775 {
5776 it->current_x = x;
5777 it->max_ascent = ascent;
5778 it->max_descent = descent;
5779 }
5780
5781 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5782 IT_CHARPOS (*it)));
5783 result = MOVE_LINE_CONTINUED;
5784 break;
5785 }
5786 else if (BUFFER_POS_REACHED_P ())
5787 goto buffer_pos_reached;
5788 else if (new_x > it->first_visible_x)
5789 {
5790 /* Glyph is visible. Increment number of glyphs that
5791 would be displayed. */
5792 ++it->hpos;
5793 }
5794 else
5795 {
5796 /* Glyph is completely off the left margin of the display
5797 area. Nothing to do. */
5798 }
5799 }
5800
5801 if (result != MOVE_UNDEFINED)
5802 break;
5803 }
5804 else if (BUFFER_POS_REACHED_P ())
5805 {
5806 buffer_pos_reached:
5807 it->current_x = x;
5808 it->max_ascent = ascent;
5809 it->max_descent = descent;
5810 result = MOVE_POS_MATCH_OR_ZV;
5811 break;
5812 }
5813 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5814 {
5815 /* Stop when TO_X specified and reached. This check is
5816 necessary here because of lines consisting of a line end,
5817 only. The line end will not produce any glyphs and we
5818 would never get MOVE_X_REACHED. */
5819 xassert (it->nglyphs == 0);
5820 result = MOVE_X_REACHED;
5821 break;
5822 }
5823
5824 /* Is this a line end? If yes, we're done. */
5825 if (ITERATOR_AT_END_OF_LINE_P (it))
5826 {
5827 result = MOVE_NEWLINE_OR_CR;
5828 break;
5829 }
5830
5831 /* The current display element has been consumed. Advance
5832 to the next. */
5833 set_iterator_to_next (it, 1);
5834
5835 /* Stop if lines are truncated and IT's current x-position is
5836 past the right edge of the window now. */
5837 if (it->truncate_lines_p
5838 && it->current_x >= it->last_visible_x)
5839 {
5840 #ifdef HAVE_WINDOW_SYSTEM
5841 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5842 {
5843 if (!get_next_display_element (it)
5844 || BUFFER_POS_REACHED_P ())
5845 {
5846 result = MOVE_POS_MATCH_OR_ZV;
5847 break;
5848 }
5849 if (ITERATOR_AT_END_OF_LINE_P (it))
5850 {
5851 result = MOVE_NEWLINE_OR_CR;
5852 break;
5853 }
5854 }
5855 #endif /* HAVE_WINDOW_SYSTEM */
5856 result = MOVE_LINE_TRUNCATED;
5857 break;
5858 }
5859 }
5860
5861 #undef BUFFER_POS_REACHED_P
5862
5863 /* Restore the iterator settings altered at the beginning of this
5864 function. */
5865 it->glyph_row = saved_glyph_row;
5866 return result;
5867 }
5868
5869
5870 /* Move IT forward until it satisfies one or more of the criteria in
5871 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5872
5873 OP is a bit-mask that specifies where to stop, and in particular,
5874 which of those four position arguments makes a difference. See the
5875 description of enum move_operation_enum.
5876
5877 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5878 screen line, this function will set IT to the next position >
5879 TO_CHARPOS. */
5880
5881 void
5882 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5883 struct it *it;
5884 int to_charpos, to_x, to_y, to_vpos;
5885 int op;
5886 {
5887 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5888 int line_height;
5889 int reached = 0;
5890
5891 for (;;)
5892 {
5893 if (op & MOVE_TO_VPOS)
5894 {
5895 /* If no TO_CHARPOS and no TO_X specified, stop at the
5896 start of the line TO_VPOS. */
5897 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5898 {
5899 if (it->vpos == to_vpos)
5900 {
5901 reached = 1;
5902 break;
5903 }
5904 else
5905 skip = move_it_in_display_line_to (it, -1, -1, 0);
5906 }
5907 else
5908 {
5909 /* TO_VPOS >= 0 means stop at TO_X in the line at
5910 TO_VPOS, or at TO_POS, whichever comes first. */
5911 if (it->vpos == to_vpos)
5912 {
5913 reached = 2;
5914 break;
5915 }
5916
5917 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5918
5919 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5920 {
5921 reached = 3;
5922 break;
5923 }
5924 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5925 {
5926 /* We have reached TO_X but not in the line we want. */
5927 skip = move_it_in_display_line_to (it, to_charpos,
5928 -1, MOVE_TO_POS);
5929 if (skip == MOVE_POS_MATCH_OR_ZV)
5930 {
5931 reached = 4;
5932 break;
5933 }
5934 }
5935 }
5936 }
5937 else if (op & MOVE_TO_Y)
5938 {
5939 struct it it_backup;
5940
5941 /* TO_Y specified means stop at TO_X in the line containing
5942 TO_Y---or at TO_CHARPOS if this is reached first. The
5943 problem is that we can't really tell whether the line
5944 contains TO_Y before we have completely scanned it, and
5945 this may skip past TO_X. What we do is to first scan to
5946 TO_X.
5947
5948 If TO_X is not specified, use a TO_X of zero. The reason
5949 is to make the outcome of this function more predictable.
5950 If we didn't use TO_X == 0, we would stop at the end of
5951 the line which is probably not what a caller would expect
5952 to happen. */
5953 skip = move_it_in_display_line_to (it, to_charpos,
5954 ((op & MOVE_TO_X)
5955 ? to_x : 0),
5956 (MOVE_TO_X
5957 | (op & MOVE_TO_POS)));
5958
5959 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5960 if (skip == MOVE_POS_MATCH_OR_ZV)
5961 {
5962 reached = 5;
5963 break;
5964 }
5965
5966 /* If TO_X was reached, we would like to know whether TO_Y
5967 is in the line. This can only be said if we know the
5968 total line height which requires us to scan the rest of
5969 the line. */
5970 if (skip == MOVE_X_REACHED)
5971 {
5972 it_backup = *it;
5973 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5974 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5975 op & MOVE_TO_POS);
5976 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5977 }
5978
5979 /* Now, decide whether TO_Y is in this line. */
5980 line_height = it->max_ascent + it->max_descent;
5981 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5982
5983 if (to_y >= it->current_y
5984 && to_y < it->current_y + line_height)
5985 {
5986 if (skip == MOVE_X_REACHED)
5987 /* If TO_Y is in this line and TO_X was reached above,
5988 we scanned too far. We have to restore IT's settings
5989 to the ones before skipping. */
5990 *it = it_backup;
5991 reached = 6;
5992 }
5993 else if (skip == MOVE_X_REACHED)
5994 {
5995 skip = skip2;
5996 if (skip == MOVE_POS_MATCH_OR_ZV)
5997 reached = 7;
5998 }
5999
6000 if (reached)
6001 break;
6002 }
6003 else
6004 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6005
6006 switch (skip)
6007 {
6008 case MOVE_POS_MATCH_OR_ZV:
6009 reached = 8;
6010 goto out;
6011
6012 case MOVE_NEWLINE_OR_CR:
6013 set_iterator_to_next (it, 1);
6014 it->continuation_lines_width = 0;
6015 break;
6016
6017 case MOVE_LINE_TRUNCATED:
6018 it->continuation_lines_width = 0;
6019 reseat_at_next_visible_line_start (it, 0);
6020 if ((op & MOVE_TO_POS) != 0
6021 && IT_CHARPOS (*it) > to_charpos)
6022 {
6023 reached = 9;
6024 goto out;
6025 }
6026 break;
6027
6028 case MOVE_LINE_CONTINUED:
6029 it->continuation_lines_width += it->current_x;
6030 break;
6031
6032 default:
6033 abort ();
6034 }
6035
6036 /* Reset/increment for the next run. */
6037 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6038 it->current_x = it->hpos = 0;
6039 it->current_y += it->max_ascent + it->max_descent;
6040 ++it->vpos;
6041 last_height = it->max_ascent + it->max_descent;
6042 last_max_ascent = it->max_ascent;
6043 it->max_ascent = it->max_descent = 0;
6044 }
6045
6046 out:
6047
6048 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6049 }
6050
6051
6052 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6053
6054 If DY > 0, move IT backward at least that many pixels. DY = 0
6055 means move IT backward to the preceding line start or BEGV. This
6056 function may move over more than DY pixels if IT->current_y - DY
6057 ends up in the middle of a line; in this case IT->current_y will be
6058 set to the top of the line moved to. */
6059
6060 void
6061 move_it_vertically_backward (it, dy)
6062 struct it *it;
6063 int dy;
6064 {
6065 int nlines, h;
6066 struct it it2, it3;
6067 int start_pos = IT_CHARPOS (*it);
6068
6069 xassert (dy >= 0);
6070
6071 /* Estimate how many newlines we must move back. */
6072 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6073
6074 /* Set the iterator's position that many lines back. */
6075 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6076 back_to_previous_visible_line_start (it);
6077
6078 /* Reseat the iterator here. When moving backward, we don't want
6079 reseat to skip forward over invisible text, set up the iterator
6080 to deliver from overlay strings at the new position etc. So,
6081 use reseat_1 here. */
6082 reseat_1 (it, it->current.pos, 1);
6083
6084 /* We are now surely at a line start. */
6085 it->current_x = it->hpos = 0;
6086 it->continuation_lines_width = 0;
6087
6088 /* Move forward and see what y-distance we moved. First move to the
6089 start of the next line so that we get its height. We need this
6090 height to be able to tell whether we reached the specified
6091 y-distance. */
6092 it2 = *it;
6093 it2.max_ascent = it2.max_descent = 0;
6094 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6095 MOVE_TO_POS | MOVE_TO_VPOS);
6096 xassert (IT_CHARPOS (*it) >= BEGV);
6097 it3 = it2;
6098
6099 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6100 xassert (IT_CHARPOS (*it) >= BEGV);
6101 /* H is the actual vertical distance from the position in *IT
6102 and the starting position. */
6103 h = it2.current_y - it->current_y;
6104 /* NLINES is the distance in number of lines. */
6105 nlines = it2.vpos - it->vpos;
6106
6107 /* Correct IT's y and vpos position
6108 so that they are relative to the starting point. */
6109 it->vpos -= nlines;
6110 it->current_y -= h;
6111
6112 if (dy == 0)
6113 {
6114 /* DY == 0 means move to the start of the screen line. The
6115 value of nlines is > 0 if continuation lines were involved. */
6116 if (nlines > 0)
6117 move_it_by_lines (it, nlines, 1);
6118 xassert (IT_CHARPOS (*it) <= start_pos);
6119 }
6120 else
6121 {
6122 /* The y-position we try to reach, relative to *IT.
6123 Note that H has been subtracted in front of the if-statement. */
6124 int target_y = it->current_y + h - dy;
6125 int y0 = it3.current_y;
6126 int y1 = line_bottom_y (&it3);
6127 int line_height = y1 - y0;
6128
6129 /* If we did not reach target_y, try to move further backward if
6130 we can. If we moved too far backward, try to move forward. */
6131 if (target_y < it->current_y
6132 /* This is heuristic. In a window that's 3 lines high, with
6133 a line height of 13 pixels each, recentering with point
6134 on the bottom line will try to move -39/2 = 19 pixels
6135 backward. Try to avoid moving into the first line. */
6136 && it->current_y - target_y > line_height / 3 * 2
6137 && IT_CHARPOS (*it) > BEGV)
6138 {
6139 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6140 target_y - it->current_y));
6141 move_it_vertically (it, target_y - it->current_y);
6142 xassert (IT_CHARPOS (*it) >= BEGV);
6143 }
6144 else if (target_y >= it->current_y + line_height
6145 && IT_CHARPOS (*it) < ZV)
6146 {
6147 /* Should move forward by at least one line, maybe more.
6148
6149 Note: Calling move_it_by_lines can be expensive on
6150 terminal frames, where compute_motion is used (via
6151 vmotion) to do the job, when there are very long lines
6152 and truncate-lines is nil. That's the reason for
6153 treating terminal frames specially here. */
6154
6155 if (!FRAME_WINDOW_P (it->f))
6156 move_it_vertically (it, target_y - (it->current_y + line_height));
6157 else
6158 {
6159 do
6160 {
6161 move_it_by_lines (it, 1, 1);
6162 }
6163 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6164 }
6165
6166 xassert (IT_CHARPOS (*it) >= BEGV);
6167 }
6168 }
6169 }
6170
6171
6172 /* Move IT by a specified amount of pixel lines DY. DY negative means
6173 move backwards. DY = 0 means move to start of screen line. At the
6174 end, IT will be on the start of a screen line. */
6175
6176 void
6177 move_it_vertically (it, dy)
6178 struct it *it;
6179 int dy;
6180 {
6181 if (dy <= 0)
6182 move_it_vertically_backward (it, -dy);
6183 else if (dy > 0)
6184 {
6185 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6186 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6187 MOVE_TO_POS | MOVE_TO_Y);
6188 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6189
6190 /* If buffer ends in ZV without a newline, move to the start of
6191 the line to satisfy the post-condition. */
6192 if (IT_CHARPOS (*it) == ZV
6193 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6194 move_it_by_lines (it, 0, 0);
6195 }
6196 }
6197
6198
6199 /* Move iterator IT past the end of the text line it is in. */
6200
6201 void
6202 move_it_past_eol (it)
6203 struct it *it;
6204 {
6205 enum move_it_result rc;
6206
6207 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6208 if (rc == MOVE_NEWLINE_OR_CR)
6209 set_iterator_to_next (it, 0);
6210 }
6211
6212
6213 #if 0 /* Currently not used. */
6214
6215 /* Return non-zero if some text between buffer positions START_CHARPOS
6216 and END_CHARPOS is invisible. IT->window is the window for text
6217 property lookup. */
6218
6219 static int
6220 invisible_text_between_p (it, start_charpos, end_charpos)
6221 struct it *it;
6222 int start_charpos, end_charpos;
6223 {
6224 Lisp_Object prop, limit;
6225 int invisible_found_p;
6226
6227 xassert (it != NULL && start_charpos <= end_charpos);
6228
6229 /* Is text at START invisible? */
6230 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6231 it->window);
6232 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6233 invisible_found_p = 1;
6234 else
6235 {
6236 limit = Fnext_single_char_property_change (make_number (start_charpos),
6237 Qinvisible, Qnil,
6238 make_number (end_charpos));
6239 invisible_found_p = XFASTINT (limit) < end_charpos;
6240 }
6241
6242 return invisible_found_p;
6243 }
6244
6245 #endif /* 0 */
6246
6247
6248 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6249 negative means move up. DVPOS == 0 means move to the start of the
6250 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6251 NEED_Y_P is zero, IT->current_y will be left unchanged.
6252
6253 Further optimization ideas: If we would know that IT->f doesn't use
6254 a face with proportional font, we could be faster for
6255 truncate-lines nil. */
6256
6257 void
6258 move_it_by_lines (it, dvpos, need_y_p)
6259 struct it *it;
6260 int dvpos, need_y_p;
6261 {
6262 struct position pos;
6263
6264 if (!FRAME_WINDOW_P (it->f))
6265 {
6266 struct text_pos textpos;
6267
6268 /* We can use vmotion on frames without proportional fonts. */
6269 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6270 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6271 reseat (it, textpos, 1);
6272 it->vpos += pos.vpos;
6273 it->current_y += pos.vpos;
6274 }
6275 else if (dvpos == 0)
6276 {
6277 /* DVPOS == 0 means move to the start of the screen line. */
6278 move_it_vertically_backward (it, 0);
6279 xassert (it->current_x == 0 && it->hpos == 0);
6280 }
6281 else if (dvpos > 0)
6282 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6283 else
6284 {
6285 struct it it2;
6286 int start_charpos, i;
6287
6288 /* Start at the beginning of the screen line containing IT's
6289 position. */
6290 move_it_vertically_backward (it, 0);
6291
6292 /* Go back -DVPOS visible lines and reseat the iterator there. */
6293 start_charpos = IT_CHARPOS (*it);
6294 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6295 back_to_previous_visible_line_start (it);
6296 reseat (it, it->current.pos, 1);
6297 it->current_x = it->hpos = 0;
6298
6299 /* Above call may have moved too far if continuation lines
6300 are involved. Scan forward and see if it did. */
6301 it2 = *it;
6302 it2.vpos = it2.current_y = 0;
6303 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6304 it->vpos -= it2.vpos;
6305 it->current_y -= it2.current_y;
6306 it->current_x = it->hpos = 0;
6307
6308 /* If we moved too far, move IT some lines forward. */
6309 if (it2.vpos > -dvpos)
6310 {
6311 int delta = it2.vpos + dvpos;
6312 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6313 }
6314 }
6315 }
6316
6317 /* Return 1 if IT points into the middle of a display vector. */
6318
6319 int
6320 in_display_vector_p (it)
6321 struct it *it;
6322 {
6323 return (it->method == next_element_from_display_vector
6324 && it->current.dpvec_index > 0
6325 && it->dpvec + it->current.dpvec_index != it->dpend);
6326 }
6327
6328 \f
6329 /***********************************************************************
6330 Messages
6331 ***********************************************************************/
6332
6333
6334 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6335 to *Messages*. */
6336
6337 void
6338 add_to_log (format, arg1, arg2)
6339 char *format;
6340 Lisp_Object arg1, arg2;
6341 {
6342 Lisp_Object args[3];
6343 Lisp_Object msg, fmt;
6344 char *buffer;
6345 int len;
6346 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6347 USE_SAFE_ALLOCA;
6348
6349 /* Do nothing if called asynchronously. Inserting text into
6350 a buffer may call after-change-functions and alike and
6351 that would means running Lisp asynchronously. */
6352 if (handling_signal)
6353 return;
6354
6355 fmt = msg = Qnil;
6356 GCPRO4 (fmt, msg, arg1, arg2);
6357
6358 args[0] = fmt = build_string (format);
6359 args[1] = arg1;
6360 args[2] = arg2;
6361 msg = Fformat (3, args);
6362
6363 len = SBYTES (msg) + 1;
6364 SAFE_ALLOCA (buffer, char *, len);
6365 bcopy (SDATA (msg), buffer, len);
6366
6367 message_dolog (buffer, len - 1, 1, 0);
6368 SAFE_FREE (len);
6369
6370 UNGCPRO;
6371 }
6372
6373
6374 /* Output a newline in the *Messages* buffer if "needs" one. */
6375
6376 void
6377 message_log_maybe_newline ()
6378 {
6379 if (message_log_need_newline)
6380 message_dolog ("", 0, 1, 0);
6381 }
6382
6383
6384 /* Add a string M of length NBYTES to the message log, optionally
6385 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6386 nonzero, means interpret the contents of M as multibyte. This
6387 function calls low-level routines in order to bypass text property
6388 hooks, etc. which might not be safe to run. */
6389
6390 void
6391 message_dolog (m, nbytes, nlflag, multibyte)
6392 const char *m;
6393 int nbytes, nlflag, multibyte;
6394 {
6395 if (!NILP (Vmemory_full))
6396 return;
6397
6398 if (!NILP (Vmessage_log_max))
6399 {
6400 struct buffer *oldbuf;
6401 Lisp_Object oldpoint, oldbegv, oldzv;
6402 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6403 int point_at_end = 0;
6404 int zv_at_end = 0;
6405 Lisp_Object old_deactivate_mark, tem;
6406 struct gcpro gcpro1;
6407
6408 old_deactivate_mark = Vdeactivate_mark;
6409 oldbuf = current_buffer;
6410 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6411 current_buffer->undo_list = Qt;
6412
6413 oldpoint = message_dolog_marker1;
6414 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6415 oldbegv = message_dolog_marker2;
6416 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6417 oldzv = message_dolog_marker3;
6418 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6419 GCPRO1 (old_deactivate_mark);
6420
6421 if (PT == Z)
6422 point_at_end = 1;
6423 if (ZV == Z)
6424 zv_at_end = 1;
6425
6426 BEGV = BEG;
6427 BEGV_BYTE = BEG_BYTE;
6428 ZV = Z;
6429 ZV_BYTE = Z_BYTE;
6430 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6431
6432 /* Insert the string--maybe converting multibyte to single byte
6433 or vice versa, so that all the text fits the buffer. */
6434 if (multibyte
6435 && NILP (current_buffer->enable_multibyte_characters))
6436 {
6437 int i, c, char_bytes;
6438 unsigned char work[1];
6439
6440 /* Convert a multibyte string to single-byte
6441 for the *Message* buffer. */
6442 for (i = 0; i < nbytes; i += char_bytes)
6443 {
6444 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6445 work[0] = (SINGLE_BYTE_CHAR_P (c)
6446 ? c
6447 : multibyte_char_to_unibyte (c, Qnil));
6448 insert_1_both (work, 1, 1, 1, 0, 0);
6449 }
6450 }
6451 else if (! multibyte
6452 && ! NILP (current_buffer->enable_multibyte_characters))
6453 {
6454 int i, c, char_bytes;
6455 unsigned char *msg = (unsigned char *) m;
6456 unsigned char str[MAX_MULTIBYTE_LENGTH];
6457 /* Convert a single-byte string to multibyte
6458 for the *Message* buffer. */
6459 for (i = 0; i < nbytes; i++)
6460 {
6461 c = unibyte_char_to_multibyte (msg[i]);
6462 char_bytes = CHAR_STRING (c, str);
6463 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6464 }
6465 }
6466 else if (nbytes)
6467 insert_1 (m, nbytes, 1, 0, 0);
6468
6469 if (nlflag)
6470 {
6471 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6472 insert_1 ("\n", 1, 1, 0, 0);
6473
6474 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6475 this_bol = PT;
6476 this_bol_byte = PT_BYTE;
6477
6478 /* See if this line duplicates the previous one.
6479 If so, combine duplicates. */
6480 if (this_bol > BEG)
6481 {
6482 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6483 prev_bol = PT;
6484 prev_bol_byte = PT_BYTE;
6485
6486 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6487 this_bol, this_bol_byte);
6488 if (dup)
6489 {
6490 del_range_both (prev_bol, prev_bol_byte,
6491 this_bol, this_bol_byte, 0);
6492 if (dup > 1)
6493 {
6494 char dupstr[40];
6495 int duplen;
6496
6497 /* If you change this format, don't forget to also
6498 change message_log_check_duplicate. */
6499 sprintf (dupstr, " [%d times]", dup);
6500 duplen = strlen (dupstr);
6501 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6502 insert_1 (dupstr, duplen, 1, 0, 1);
6503 }
6504 }
6505 }
6506
6507 /* If we have more than the desired maximum number of lines
6508 in the *Messages* buffer now, delete the oldest ones.
6509 This is safe because we don't have undo in this buffer. */
6510
6511 if (NATNUMP (Vmessage_log_max))
6512 {
6513 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6514 -XFASTINT (Vmessage_log_max) - 1, 0);
6515 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6516 }
6517 }
6518 BEGV = XMARKER (oldbegv)->charpos;
6519 BEGV_BYTE = marker_byte_position (oldbegv);
6520
6521 if (zv_at_end)
6522 {
6523 ZV = Z;
6524 ZV_BYTE = Z_BYTE;
6525 }
6526 else
6527 {
6528 ZV = XMARKER (oldzv)->charpos;
6529 ZV_BYTE = marker_byte_position (oldzv);
6530 }
6531
6532 if (point_at_end)
6533 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6534 else
6535 /* We can't do Fgoto_char (oldpoint) because it will run some
6536 Lisp code. */
6537 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6538 XMARKER (oldpoint)->bytepos);
6539
6540 UNGCPRO;
6541 unchain_marker (XMARKER (oldpoint));
6542 unchain_marker (XMARKER (oldbegv));
6543 unchain_marker (XMARKER (oldzv));
6544
6545 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6546 set_buffer_internal (oldbuf);
6547 if (NILP (tem))
6548 windows_or_buffers_changed = old_windows_or_buffers_changed;
6549 message_log_need_newline = !nlflag;
6550 Vdeactivate_mark = old_deactivate_mark;
6551 }
6552 }
6553
6554
6555 /* We are at the end of the buffer after just having inserted a newline.
6556 (Note: We depend on the fact we won't be crossing the gap.)
6557 Check to see if the most recent message looks a lot like the previous one.
6558 Return 0 if different, 1 if the new one should just replace it, or a
6559 value N > 1 if we should also append " [N times]". */
6560
6561 static int
6562 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6563 int prev_bol, this_bol;
6564 int prev_bol_byte, this_bol_byte;
6565 {
6566 int i;
6567 int len = Z_BYTE - 1 - this_bol_byte;
6568 int seen_dots = 0;
6569 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6570 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6571
6572 for (i = 0; i < len; i++)
6573 {
6574 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6575 seen_dots = 1;
6576 if (p1[i] != p2[i])
6577 return seen_dots;
6578 }
6579 p1 += len;
6580 if (*p1 == '\n')
6581 return 2;
6582 if (*p1++ == ' ' && *p1++ == '[')
6583 {
6584 int n = 0;
6585 while (*p1 >= '0' && *p1 <= '9')
6586 n = n * 10 + *p1++ - '0';
6587 if (strncmp (p1, " times]\n", 8) == 0)
6588 return n+1;
6589 }
6590 return 0;
6591 }
6592
6593
6594 /* Display an echo area message M with a specified length of NBYTES
6595 bytes. The string may include null characters. If M is 0, clear
6596 out any existing message, and let the mini-buffer text show
6597 through.
6598
6599 The buffer M must continue to exist until after the echo area gets
6600 cleared or some other message gets displayed there. This means do
6601 not pass text that is stored in a Lisp string; do not pass text in
6602 a buffer that was alloca'd. */
6603
6604 void
6605 message2 (m, nbytes, multibyte)
6606 const char *m;
6607 int nbytes;
6608 int multibyte;
6609 {
6610 /* First flush out any partial line written with print. */
6611 message_log_maybe_newline ();
6612 if (m)
6613 message_dolog (m, nbytes, 1, multibyte);
6614 message2_nolog (m, nbytes, multibyte);
6615 }
6616
6617
6618 /* The non-logging counterpart of message2. */
6619
6620 void
6621 message2_nolog (m, nbytes, multibyte)
6622 const char *m;
6623 int nbytes, multibyte;
6624 {
6625 struct frame *sf = SELECTED_FRAME ();
6626 message_enable_multibyte = multibyte;
6627
6628 if (noninteractive)
6629 {
6630 if (noninteractive_need_newline)
6631 putc ('\n', stderr);
6632 noninteractive_need_newline = 0;
6633 if (m)
6634 fwrite (m, nbytes, 1, stderr);
6635 if (cursor_in_echo_area == 0)
6636 fprintf (stderr, "\n");
6637 fflush (stderr);
6638 }
6639 /* A null message buffer means that the frame hasn't really been
6640 initialized yet. Error messages get reported properly by
6641 cmd_error, so this must be just an informative message; toss it. */
6642 else if (INTERACTIVE
6643 && sf->glyphs_initialized_p
6644 && FRAME_MESSAGE_BUF (sf))
6645 {
6646 Lisp_Object mini_window;
6647 struct frame *f;
6648
6649 /* Get the frame containing the mini-buffer
6650 that the selected frame is using. */
6651 mini_window = FRAME_MINIBUF_WINDOW (sf);
6652 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6653
6654 FRAME_SAMPLE_VISIBILITY (f);
6655 if (FRAME_VISIBLE_P (sf)
6656 && ! FRAME_VISIBLE_P (f))
6657 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6658
6659 if (m)
6660 {
6661 set_message (m, Qnil, nbytes, multibyte);
6662 if (minibuffer_auto_raise)
6663 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6664 }
6665 else
6666 clear_message (1, 1);
6667
6668 do_pending_window_change (0);
6669 echo_area_display (1);
6670 do_pending_window_change (0);
6671 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6672 (*frame_up_to_date_hook) (f);
6673 }
6674 }
6675
6676
6677 /* Display an echo area message M with a specified length of NBYTES
6678 bytes. The string may include null characters. If M is not a
6679 string, clear out any existing message, and let the mini-buffer
6680 text show through. */
6681
6682 void
6683 message3 (m, nbytes, multibyte)
6684 Lisp_Object m;
6685 int nbytes;
6686 int multibyte;
6687 {
6688 struct gcpro gcpro1;
6689
6690 GCPRO1 (m);
6691
6692 /* First flush out any partial line written with print. */
6693 message_log_maybe_newline ();
6694 if (STRINGP (m))
6695 message_dolog (SDATA (m), nbytes, 1, multibyte);
6696 message3_nolog (m, nbytes, multibyte);
6697
6698 UNGCPRO;
6699 }
6700
6701
6702 /* The non-logging version of message3. */
6703
6704 void
6705 message3_nolog (m, nbytes, multibyte)
6706 Lisp_Object m;
6707 int nbytes, multibyte;
6708 {
6709 struct frame *sf = SELECTED_FRAME ();
6710 message_enable_multibyte = multibyte;
6711
6712 if (noninteractive)
6713 {
6714 if (noninteractive_need_newline)
6715 putc ('\n', stderr);
6716 noninteractive_need_newline = 0;
6717 if (STRINGP (m))
6718 fwrite (SDATA (m), nbytes, 1, stderr);
6719 if (cursor_in_echo_area == 0)
6720 fprintf (stderr, "\n");
6721 fflush (stderr);
6722 }
6723 /* A null message buffer means that the frame hasn't really been
6724 initialized yet. Error messages get reported properly by
6725 cmd_error, so this must be just an informative message; toss it. */
6726 else if (INTERACTIVE
6727 && sf->glyphs_initialized_p
6728 && FRAME_MESSAGE_BUF (sf))
6729 {
6730 Lisp_Object mini_window;
6731 Lisp_Object frame;
6732 struct frame *f;
6733
6734 /* Get the frame containing the mini-buffer
6735 that the selected frame is using. */
6736 mini_window = FRAME_MINIBUF_WINDOW (sf);
6737 frame = XWINDOW (mini_window)->frame;
6738 f = XFRAME (frame);
6739
6740 FRAME_SAMPLE_VISIBILITY (f);
6741 if (FRAME_VISIBLE_P (sf)
6742 && !FRAME_VISIBLE_P (f))
6743 Fmake_frame_visible (frame);
6744
6745 if (STRINGP (m) && SCHARS (m) > 0)
6746 {
6747 set_message (NULL, m, nbytes, multibyte);
6748 if (minibuffer_auto_raise)
6749 Fraise_frame (frame);
6750 }
6751 else
6752 clear_message (1, 1);
6753
6754 do_pending_window_change (0);
6755 echo_area_display (1);
6756 do_pending_window_change (0);
6757 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6758 (*frame_up_to_date_hook) (f);
6759 }
6760 }
6761
6762
6763 /* Display a null-terminated echo area message M. If M is 0, clear
6764 out any existing message, and let the mini-buffer text show through.
6765
6766 The buffer M must continue to exist until after the echo area gets
6767 cleared or some other message gets displayed there. Do not pass
6768 text that is stored in a Lisp string. Do not pass text in a buffer
6769 that was alloca'd. */
6770
6771 void
6772 message1 (m)
6773 char *m;
6774 {
6775 message2 (m, (m ? strlen (m) : 0), 0);
6776 }
6777
6778
6779 /* The non-logging counterpart of message1. */
6780
6781 void
6782 message1_nolog (m)
6783 char *m;
6784 {
6785 message2_nolog (m, (m ? strlen (m) : 0), 0);
6786 }
6787
6788 /* Display a message M which contains a single %s
6789 which gets replaced with STRING. */
6790
6791 void
6792 message_with_string (m, string, log)
6793 char *m;
6794 Lisp_Object string;
6795 int log;
6796 {
6797 CHECK_STRING (string);
6798
6799 if (noninteractive)
6800 {
6801 if (m)
6802 {
6803 if (noninteractive_need_newline)
6804 putc ('\n', stderr);
6805 noninteractive_need_newline = 0;
6806 fprintf (stderr, m, SDATA (string));
6807 if (cursor_in_echo_area == 0)
6808 fprintf (stderr, "\n");
6809 fflush (stderr);
6810 }
6811 }
6812 else if (INTERACTIVE)
6813 {
6814 /* The frame whose minibuffer we're going to display the message on.
6815 It may be larger than the selected frame, so we need
6816 to use its buffer, not the selected frame's buffer. */
6817 Lisp_Object mini_window;
6818 struct frame *f, *sf = SELECTED_FRAME ();
6819
6820 /* Get the frame containing the minibuffer
6821 that the selected frame is using. */
6822 mini_window = FRAME_MINIBUF_WINDOW (sf);
6823 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6824
6825 /* A null message buffer means that the frame hasn't really been
6826 initialized yet. Error messages get reported properly by
6827 cmd_error, so this must be just an informative message; toss it. */
6828 if (FRAME_MESSAGE_BUF (f))
6829 {
6830 Lisp_Object args[2], message;
6831 struct gcpro gcpro1, gcpro2;
6832
6833 args[0] = build_string (m);
6834 args[1] = message = string;
6835 GCPRO2 (args[0], message);
6836 gcpro1.nvars = 2;
6837
6838 message = Fformat (2, args);
6839
6840 if (log)
6841 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6842 else
6843 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6844
6845 UNGCPRO;
6846
6847 /* Print should start at the beginning of the message
6848 buffer next time. */
6849 message_buf_print = 0;
6850 }
6851 }
6852 }
6853
6854
6855 /* Dump an informative message to the minibuf. If M is 0, clear out
6856 any existing message, and let the mini-buffer text show through. */
6857
6858 /* VARARGS 1 */
6859 void
6860 message (m, a1, a2, a3)
6861 char *m;
6862 EMACS_INT a1, a2, a3;
6863 {
6864 if (noninteractive)
6865 {
6866 if (m)
6867 {
6868 if (noninteractive_need_newline)
6869 putc ('\n', stderr);
6870 noninteractive_need_newline = 0;
6871 fprintf (stderr, m, a1, a2, a3);
6872 if (cursor_in_echo_area == 0)
6873 fprintf (stderr, "\n");
6874 fflush (stderr);
6875 }
6876 }
6877 else if (INTERACTIVE)
6878 {
6879 /* The frame whose mini-buffer we're going to display the message
6880 on. It may be larger than the selected frame, so we need to
6881 use its buffer, not the selected frame's buffer. */
6882 Lisp_Object mini_window;
6883 struct frame *f, *sf = SELECTED_FRAME ();
6884
6885 /* Get the frame containing the mini-buffer
6886 that the selected frame is using. */
6887 mini_window = FRAME_MINIBUF_WINDOW (sf);
6888 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6889
6890 /* A null message buffer means that the frame hasn't really been
6891 initialized yet. Error messages get reported properly by
6892 cmd_error, so this must be just an informative message; toss
6893 it. */
6894 if (FRAME_MESSAGE_BUF (f))
6895 {
6896 if (m)
6897 {
6898 int len;
6899 #ifdef NO_ARG_ARRAY
6900 char *a[3];
6901 a[0] = (char *) a1;
6902 a[1] = (char *) a2;
6903 a[2] = (char *) a3;
6904
6905 len = doprnt (FRAME_MESSAGE_BUF (f),
6906 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6907 #else
6908 len = doprnt (FRAME_MESSAGE_BUF (f),
6909 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6910 (char **) &a1);
6911 #endif /* NO_ARG_ARRAY */
6912
6913 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6914 }
6915 else
6916 message1 (0);
6917
6918 /* Print should start at the beginning of the message
6919 buffer next time. */
6920 message_buf_print = 0;
6921 }
6922 }
6923 }
6924
6925
6926 /* The non-logging version of message. */
6927
6928 void
6929 message_nolog (m, a1, a2, a3)
6930 char *m;
6931 EMACS_INT a1, a2, a3;
6932 {
6933 Lisp_Object old_log_max;
6934 old_log_max = Vmessage_log_max;
6935 Vmessage_log_max = Qnil;
6936 message (m, a1, a2, a3);
6937 Vmessage_log_max = old_log_max;
6938 }
6939
6940
6941 /* Display the current message in the current mini-buffer. This is
6942 only called from error handlers in process.c, and is not time
6943 critical. */
6944
6945 void
6946 update_echo_area ()
6947 {
6948 if (!NILP (echo_area_buffer[0]))
6949 {
6950 Lisp_Object string;
6951 string = Fcurrent_message ();
6952 message3 (string, SBYTES (string),
6953 !NILP (current_buffer->enable_multibyte_characters));
6954 }
6955 }
6956
6957
6958 /* Make sure echo area buffers in `echo_buffers' are live.
6959 If they aren't, make new ones. */
6960
6961 static void
6962 ensure_echo_area_buffers ()
6963 {
6964 int i;
6965
6966 for (i = 0; i < 2; ++i)
6967 if (!BUFFERP (echo_buffer[i])
6968 || NILP (XBUFFER (echo_buffer[i])->name))
6969 {
6970 char name[30];
6971 Lisp_Object old_buffer;
6972 int j;
6973
6974 old_buffer = echo_buffer[i];
6975 sprintf (name, " *Echo Area %d*", i);
6976 echo_buffer[i] = Fget_buffer_create (build_string (name));
6977 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6978
6979 for (j = 0; j < 2; ++j)
6980 if (EQ (old_buffer, echo_area_buffer[j]))
6981 echo_area_buffer[j] = echo_buffer[i];
6982 }
6983 }
6984
6985
6986 /* Call FN with args A1..A4 with either the current or last displayed
6987 echo_area_buffer as current buffer.
6988
6989 WHICH zero means use the current message buffer
6990 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6991 from echo_buffer[] and clear it.
6992
6993 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6994 suitable buffer from echo_buffer[] and clear it.
6995
6996 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6997 that the current message becomes the last displayed one, make
6998 choose a suitable buffer for echo_area_buffer[0], and clear it.
6999
7000 Value is what FN returns. */
7001
7002 static int
7003 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7004 struct window *w;
7005 int which;
7006 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7007 EMACS_INT a1;
7008 Lisp_Object a2;
7009 EMACS_INT a3, a4;
7010 {
7011 Lisp_Object buffer;
7012 int this_one, the_other, clear_buffer_p, rc;
7013 int count = SPECPDL_INDEX ();
7014
7015 /* If buffers aren't live, make new ones. */
7016 ensure_echo_area_buffers ();
7017
7018 clear_buffer_p = 0;
7019
7020 if (which == 0)
7021 this_one = 0, the_other = 1;
7022 else if (which > 0)
7023 this_one = 1, the_other = 0;
7024 else
7025 {
7026 this_one = 0, the_other = 1;
7027 clear_buffer_p = 1;
7028
7029 /* We need a fresh one in case the current echo buffer equals
7030 the one containing the last displayed echo area message. */
7031 if (!NILP (echo_area_buffer[this_one])
7032 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7033 echo_area_buffer[this_one] = Qnil;
7034 }
7035
7036 /* Choose a suitable buffer from echo_buffer[] is we don't
7037 have one. */
7038 if (NILP (echo_area_buffer[this_one]))
7039 {
7040 echo_area_buffer[this_one]
7041 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7042 ? echo_buffer[the_other]
7043 : echo_buffer[this_one]);
7044 clear_buffer_p = 1;
7045 }
7046
7047 buffer = echo_area_buffer[this_one];
7048
7049 /* Don't get confused by reusing the buffer used for echoing
7050 for a different purpose. */
7051 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7052 cancel_echoing ();
7053
7054 record_unwind_protect (unwind_with_echo_area_buffer,
7055 with_echo_area_buffer_unwind_data (w));
7056
7057 /* Make the echo area buffer current. Note that for display
7058 purposes, it is not necessary that the displayed window's buffer
7059 == current_buffer, except for text property lookup. So, let's
7060 only set that buffer temporarily here without doing a full
7061 Fset_window_buffer. We must also change w->pointm, though,
7062 because otherwise an assertions in unshow_buffer fails, and Emacs
7063 aborts. */
7064 set_buffer_internal_1 (XBUFFER (buffer));
7065 if (w)
7066 {
7067 w->buffer = buffer;
7068 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7069 }
7070
7071 current_buffer->undo_list = Qt;
7072 current_buffer->read_only = Qnil;
7073 specbind (Qinhibit_read_only, Qt);
7074 specbind (Qinhibit_modification_hooks, Qt);
7075
7076 if (clear_buffer_p && Z > BEG)
7077 del_range (BEG, Z);
7078
7079 xassert (BEGV >= BEG);
7080 xassert (ZV <= Z && ZV >= BEGV);
7081
7082 rc = fn (a1, a2, a3, a4);
7083
7084 xassert (BEGV >= BEG);
7085 xassert (ZV <= Z && ZV >= BEGV);
7086
7087 unbind_to (count, Qnil);
7088 return rc;
7089 }
7090
7091
7092 /* Save state that should be preserved around the call to the function
7093 FN called in with_echo_area_buffer. */
7094
7095 static Lisp_Object
7096 with_echo_area_buffer_unwind_data (w)
7097 struct window *w;
7098 {
7099 int i = 0;
7100 Lisp_Object vector;
7101
7102 /* Reduce consing by keeping one vector in
7103 Vwith_echo_area_save_vector. */
7104 vector = Vwith_echo_area_save_vector;
7105 Vwith_echo_area_save_vector = Qnil;
7106
7107 if (NILP (vector))
7108 vector = Fmake_vector (make_number (7), Qnil);
7109
7110 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7111 AREF (vector, i) = Vdeactivate_mark, ++i;
7112 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7113
7114 if (w)
7115 {
7116 XSETWINDOW (AREF (vector, i), w); ++i;
7117 AREF (vector, i) = w->buffer; ++i;
7118 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7119 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7120 }
7121 else
7122 {
7123 int end = i + 4;
7124 for (; i < end; ++i)
7125 AREF (vector, i) = Qnil;
7126 }
7127
7128 xassert (i == ASIZE (vector));
7129 return vector;
7130 }
7131
7132
7133 /* Restore global state from VECTOR which was created by
7134 with_echo_area_buffer_unwind_data. */
7135
7136 static Lisp_Object
7137 unwind_with_echo_area_buffer (vector)
7138 Lisp_Object vector;
7139 {
7140 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7141 Vdeactivate_mark = AREF (vector, 1);
7142 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7143
7144 if (WINDOWP (AREF (vector, 3)))
7145 {
7146 struct window *w;
7147 Lisp_Object buffer, charpos, bytepos;
7148
7149 w = XWINDOW (AREF (vector, 3));
7150 buffer = AREF (vector, 4);
7151 charpos = AREF (vector, 5);
7152 bytepos = AREF (vector, 6);
7153
7154 w->buffer = buffer;
7155 set_marker_both (w->pointm, buffer,
7156 XFASTINT (charpos), XFASTINT (bytepos));
7157 }
7158
7159 Vwith_echo_area_save_vector = vector;
7160 return Qnil;
7161 }
7162
7163
7164 /* Set up the echo area for use by print functions. MULTIBYTE_P
7165 non-zero means we will print multibyte. */
7166
7167 void
7168 setup_echo_area_for_printing (multibyte_p)
7169 int multibyte_p;
7170 {
7171 /* If we can't find an echo area any more, exit. */
7172 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7173 Fkill_emacs (Qnil);
7174
7175 ensure_echo_area_buffers ();
7176
7177 if (!message_buf_print)
7178 {
7179 /* A message has been output since the last time we printed.
7180 Choose a fresh echo area buffer. */
7181 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7182 echo_area_buffer[0] = echo_buffer[1];
7183 else
7184 echo_area_buffer[0] = echo_buffer[0];
7185
7186 /* Switch to that buffer and clear it. */
7187 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7188 current_buffer->truncate_lines = Qnil;
7189
7190 if (Z > BEG)
7191 {
7192 int count = SPECPDL_INDEX ();
7193 specbind (Qinhibit_read_only, Qt);
7194 /* Note that undo recording is always disabled. */
7195 del_range (BEG, Z);
7196 unbind_to (count, Qnil);
7197 }
7198 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7199
7200 /* Set up the buffer for the multibyteness we need. */
7201 if (multibyte_p
7202 != !NILP (current_buffer->enable_multibyte_characters))
7203 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7204
7205 /* Raise the frame containing the echo area. */
7206 if (minibuffer_auto_raise)
7207 {
7208 struct frame *sf = SELECTED_FRAME ();
7209 Lisp_Object mini_window;
7210 mini_window = FRAME_MINIBUF_WINDOW (sf);
7211 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7212 }
7213
7214 message_log_maybe_newline ();
7215 message_buf_print = 1;
7216 }
7217 else
7218 {
7219 if (NILP (echo_area_buffer[0]))
7220 {
7221 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7222 echo_area_buffer[0] = echo_buffer[1];
7223 else
7224 echo_area_buffer[0] = echo_buffer[0];
7225 }
7226
7227 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7228 {
7229 /* Someone switched buffers between print requests. */
7230 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7231 current_buffer->truncate_lines = Qnil;
7232 }
7233 }
7234 }
7235
7236
7237 /* Display an echo area message in window W. Value is non-zero if W's
7238 height is changed. If display_last_displayed_message_p is
7239 non-zero, display the message that was last displayed, otherwise
7240 display the current message. */
7241
7242 static int
7243 display_echo_area (w)
7244 struct window *w;
7245 {
7246 int i, no_message_p, window_height_changed_p, count;
7247
7248 /* Temporarily disable garbage collections while displaying the echo
7249 area. This is done because a GC can print a message itself.
7250 That message would modify the echo area buffer's contents while a
7251 redisplay of the buffer is going on, and seriously confuse
7252 redisplay. */
7253 count = inhibit_garbage_collection ();
7254
7255 /* If there is no message, we must call display_echo_area_1
7256 nevertheless because it resizes the window. But we will have to
7257 reset the echo_area_buffer in question to nil at the end because
7258 with_echo_area_buffer will sets it to an empty buffer. */
7259 i = display_last_displayed_message_p ? 1 : 0;
7260 no_message_p = NILP (echo_area_buffer[i]);
7261
7262 window_height_changed_p
7263 = with_echo_area_buffer (w, display_last_displayed_message_p,
7264 display_echo_area_1,
7265 (EMACS_INT) w, Qnil, 0, 0);
7266
7267 if (no_message_p)
7268 echo_area_buffer[i] = Qnil;
7269
7270 unbind_to (count, Qnil);
7271 return window_height_changed_p;
7272 }
7273
7274
7275 /* Helper for display_echo_area. Display the current buffer which
7276 contains the current echo area message in window W, a mini-window,
7277 a pointer to which is passed in A1. A2..A4 are currently not used.
7278 Change the height of W so that all of the message is displayed.
7279 Value is non-zero if height of W was changed. */
7280
7281 static int
7282 display_echo_area_1 (a1, a2, a3, a4)
7283 EMACS_INT a1;
7284 Lisp_Object a2;
7285 EMACS_INT a3, a4;
7286 {
7287 struct window *w = (struct window *) a1;
7288 Lisp_Object window;
7289 struct text_pos start;
7290 int window_height_changed_p = 0;
7291
7292 /* Do this before displaying, so that we have a large enough glyph
7293 matrix for the display. */
7294 window_height_changed_p = resize_mini_window (w, 0);
7295
7296 /* Display. */
7297 clear_glyph_matrix (w->desired_matrix);
7298 XSETWINDOW (window, w);
7299 SET_TEXT_POS (start, BEG, BEG_BYTE);
7300 try_window (window, start);
7301
7302 return window_height_changed_p;
7303 }
7304
7305
7306 /* Resize the echo area window to exactly the size needed for the
7307 currently displayed message, if there is one. If a mini-buffer
7308 is active, don't shrink it. */
7309
7310 void
7311 resize_echo_area_exactly ()
7312 {
7313 if (BUFFERP (echo_area_buffer[0])
7314 && WINDOWP (echo_area_window))
7315 {
7316 struct window *w = XWINDOW (echo_area_window);
7317 int resized_p;
7318 Lisp_Object resize_exactly;
7319
7320 if (minibuf_level == 0)
7321 resize_exactly = Qt;
7322 else
7323 resize_exactly = Qnil;
7324
7325 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7326 (EMACS_INT) w, resize_exactly, 0, 0);
7327 if (resized_p)
7328 {
7329 ++windows_or_buffers_changed;
7330 ++update_mode_lines;
7331 redisplay_internal (0);
7332 }
7333 }
7334 }
7335
7336
7337 /* Callback function for with_echo_area_buffer, when used from
7338 resize_echo_area_exactly. A1 contains a pointer to the window to
7339 resize, EXACTLY non-nil means resize the mini-window exactly to the
7340 size of the text displayed. A3 and A4 are not used. Value is what
7341 resize_mini_window returns. */
7342
7343 static int
7344 resize_mini_window_1 (a1, exactly, a3, a4)
7345 EMACS_INT a1;
7346 Lisp_Object exactly;
7347 EMACS_INT a3, a4;
7348 {
7349 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7350 }
7351
7352
7353 /* Resize mini-window W to fit the size of its contents. EXACT:P
7354 means size the window exactly to the size needed. Otherwise, it's
7355 only enlarged until W's buffer is empty. Value is non-zero if
7356 the window height has been changed. */
7357
7358 int
7359 resize_mini_window (w, exact_p)
7360 struct window *w;
7361 int exact_p;
7362 {
7363 struct frame *f = XFRAME (w->frame);
7364 int window_height_changed_p = 0;
7365
7366 xassert (MINI_WINDOW_P (w));
7367
7368 /* Don't resize windows while redisplaying a window; it would
7369 confuse redisplay functions when the size of the window they are
7370 displaying changes from under them. Such a resizing can happen,
7371 for instance, when which-func prints a long message while
7372 we are running fontification-functions. We're running these
7373 functions with safe_call which binds inhibit-redisplay to t. */
7374 if (!NILP (Vinhibit_redisplay))
7375 return 0;
7376
7377 /* Nil means don't try to resize. */
7378 if (NILP (Vresize_mini_windows)
7379 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7380 return 0;
7381
7382 if (!FRAME_MINIBUF_ONLY_P (f))
7383 {
7384 struct it it;
7385 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7386 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7387 int height, max_height;
7388 int unit = FRAME_LINE_HEIGHT (f);
7389 struct text_pos start;
7390 struct buffer *old_current_buffer = NULL;
7391
7392 if (current_buffer != XBUFFER (w->buffer))
7393 {
7394 old_current_buffer = current_buffer;
7395 set_buffer_internal (XBUFFER (w->buffer));
7396 }
7397
7398 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7399
7400 /* Compute the max. number of lines specified by the user. */
7401 if (FLOATP (Vmax_mini_window_height))
7402 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7403 else if (INTEGERP (Vmax_mini_window_height))
7404 max_height = XINT (Vmax_mini_window_height);
7405 else
7406 max_height = total_height / 4;
7407
7408 /* Correct that max. height if it's bogus. */
7409 max_height = max (1, max_height);
7410 max_height = min (total_height, max_height);
7411
7412 /* Find out the height of the text in the window. */
7413 if (it.truncate_lines_p)
7414 height = 1;
7415 else
7416 {
7417 last_height = 0;
7418 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7419 if (it.max_ascent == 0 && it.max_descent == 0)
7420 height = it.current_y + last_height;
7421 else
7422 height = it.current_y + it.max_ascent + it.max_descent;
7423 height -= it.extra_line_spacing;
7424 height = (height + unit - 1) / unit;
7425 }
7426
7427 /* Compute a suitable window start. */
7428 if (height > max_height)
7429 {
7430 height = max_height;
7431 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7432 move_it_vertically_backward (&it, (height - 1) * unit);
7433 start = it.current.pos;
7434 }
7435 else
7436 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7437 SET_MARKER_FROM_TEXT_POS (w->start, start);
7438
7439 if (EQ (Vresize_mini_windows, Qgrow_only))
7440 {
7441 /* Let it grow only, until we display an empty message, in which
7442 case the window shrinks again. */
7443 if (height > WINDOW_TOTAL_LINES (w))
7444 {
7445 int old_height = WINDOW_TOTAL_LINES (w);
7446 freeze_window_starts (f, 1);
7447 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7448 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7449 }
7450 else if (height < WINDOW_TOTAL_LINES (w)
7451 && (exact_p || BEGV == ZV))
7452 {
7453 int old_height = WINDOW_TOTAL_LINES (w);
7454 freeze_window_starts (f, 0);
7455 shrink_mini_window (w);
7456 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7457 }
7458 }
7459 else
7460 {
7461 /* Always resize to exact size needed. */
7462 if (height > WINDOW_TOTAL_LINES (w))
7463 {
7464 int old_height = WINDOW_TOTAL_LINES (w);
7465 freeze_window_starts (f, 1);
7466 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7467 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7468 }
7469 else if (height < WINDOW_TOTAL_LINES (w))
7470 {
7471 int old_height = WINDOW_TOTAL_LINES (w);
7472 freeze_window_starts (f, 0);
7473 shrink_mini_window (w);
7474
7475 if (height)
7476 {
7477 freeze_window_starts (f, 1);
7478 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7479 }
7480
7481 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7482 }
7483 }
7484
7485 if (old_current_buffer)
7486 set_buffer_internal (old_current_buffer);
7487 }
7488
7489 return window_height_changed_p;
7490 }
7491
7492
7493 /* Value is the current message, a string, or nil if there is no
7494 current message. */
7495
7496 Lisp_Object
7497 current_message ()
7498 {
7499 Lisp_Object msg;
7500
7501 if (NILP (echo_area_buffer[0]))
7502 msg = Qnil;
7503 else
7504 {
7505 with_echo_area_buffer (0, 0, current_message_1,
7506 (EMACS_INT) &msg, Qnil, 0, 0);
7507 if (NILP (msg))
7508 echo_area_buffer[0] = Qnil;
7509 }
7510
7511 return msg;
7512 }
7513
7514
7515 static int
7516 current_message_1 (a1, a2, a3, a4)
7517 EMACS_INT a1;
7518 Lisp_Object a2;
7519 EMACS_INT a3, a4;
7520 {
7521 Lisp_Object *msg = (Lisp_Object *) a1;
7522
7523 if (Z > BEG)
7524 *msg = make_buffer_string (BEG, Z, 1);
7525 else
7526 *msg = Qnil;
7527 return 0;
7528 }
7529
7530
7531 /* Push the current message on Vmessage_stack for later restauration
7532 by restore_message. Value is non-zero if the current message isn't
7533 empty. This is a relatively infrequent operation, so it's not
7534 worth optimizing. */
7535
7536 int
7537 push_message ()
7538 {
7539 Lisp_Object msg;
7540 msg = current_message ();
7541 Vmessage_stack = Fcons (msg, Vmessage_stack);
7542 return STRINGP (msg);
7543 }
7544
7545
7546 /* Restore message display from the top of Vmessage_stack. */
7547
7548 void
7549 restore_message ()
7550 {
7551 Lisp_Object msg;
7552
7553 xassert (CONSP (Vmessage_stack));
7554 msg = XCAR (Vmessage_stack);
7555 if (STRINGP (msg))
7556 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7557 else
7558 message3_nolog (msg, 0, 0);
7559 }
7560
7561
7562 /* Handler for record_unwind_protect calling pop_message. */
7563
7564 Lisp_Object
7565 pop_message_unwind (dummy)
7566 Lisp_Object dummy;
7567 {
7568 pop_message ();
7569 return Qnil;
7570 }
7571
7572 /* Pop the top-most entry off Vmessage_stack. */
7573
7574 void
7575 pop_message ()
7576 {
7577 xassert (CONSP (Vmessage_stack));
7578 Vmessage_stack = XCDR (Vmessage_stack);
7579 }
7580
7581
7582 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7583 exits. If the stack is not empty, we have a missing pop_message
7584 somewhere. */
7585
7586 void
7587 check_message_stack ()
7588 {
7589 if (!NILP (Vmessage_stack))
7590 abort ();
7591 }
7592
7593
7594 /* Truncate to NCHARS what will be displayed in the echo area the next
7595 time we display it---but don't redisplay it now. */
7596
7597 void
7598 truncate_echo_area (nchars)
7599 int nchars;
7600 {
7601 if (nchars == 0)
7602 echo_area_buffer[0] = Qnil;
7603 /* A null message buffer means that the frame hasn't really been
7604 initialized yet. Error messages get reported properly by
7605 cmd_error, so this must be just an informative message; toss it. */
7606 else if (!noninteractive
7607 && INTERACTIVE
7608 && !NILP (echo_area_buffer[0]))
7609 {
7610 struct frame *sf = SELECTED_FRAME ();
7611 if (FRAME_MESSAGE_BUF (sf))
7612 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7613 }
7614 }
7615
7616
7617 /* Helper function for truncate_echo_area. Truncate the current
7618 message to at most NCHARS characters. */
7619
7620 static int
7621 truncate_message_1 (nchars, a2, a3, a4)
7622 EMACS_INT nchars;
7623 Lisp_Object a2;
7624 EMACS_INT a3, a4;
7625 {
7626 if (BEG + nchars < Z)
7627 del_range (BEG + nchars, Z);
7628 if (Z == BEG)
7629 echo_area_buffer[0] = Qnil;
7630 return 0;
7631 }
7632
7633
7634 /* Set the current message to a substring of S or STRING.
7635
7636 If STRING is a Lisp string, set the message to the first NBYTES
7637 bytes from STRING. NBYTES zero means use the whole string. If
7638 STRING is multibyte, the message will be displayed multibyte.
7639
7640 If S is not null, set the message to the first LEN bytes of S. LEN
7641 zero means use the whole string. MULTIBYTE_P non-zero means S is
7642 multibyte. Display the message multibyte in that case. */
7643
7644 void
7645 set_message (s, string, nbytes, multibyte_p)
7646 const char *s;
7647 Lisp_Object string;
7648 int nbytes, multibyte_p;
7649 {
7650 message_enable_multibyte
7651 = ((s && multibyte_p)
7652 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7653
7654 with_echo_area_buffer (0, -1, set_message_1,
7655 (EMACS_INT) s, string, nbytes, multibyte_p);
7656 message_buf_print = 0;
7657 help_echo_showing_p = 0;
7658 }
7659
7660
7661 /* Helper function for set_message. Arguments have the same meaning
7662 as there, with A1 corresponding to S and A2 corresponding to STRING
7663 This function is called with the echo area buffer being
7664 current. */
7665
7666 static int
7667 set_message_1 (a1, a2, nbytes, multibyte_p)
7668 EMACS_INT a1;
7669 Lisp_Object a2;
7670 EMACS_INT nbytes, multibyte_p;
7671 {
7672 const char *s = (const char *) a1;
7673 Lisp_Object string = a2;
7674
7675 xassert (BEG == Z);
7676
7677 /* Change multibyteness of the echo buffer appropriately. */
7678 if (message_enable_multibyte
7679 != !NILP (current_buffer->enable_multibyte_characters))
7680 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7681
7682 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7683
7684 /* Insert new message at BEG. */
7685 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7686
7687 if (STRINGP (string))
7688 {
7689 int nchars;
7690
7691 if (nbytes == 0)
7692 nbytes = SBYTES (string);
7693 nchars = string_byte_to_char (string, nbytes);
7694
7695 /* This function takes care of single/multibyte conversion. We
7696 just have to ensure that the echo area buffer has the right
7697 setting of enable_multibyte_characters. */
7698 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7699 }
7700 else if (s)
7701 {
7702 if (nbytes == 0)
7703 nbytes = strlen (s);
7704
7705 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7706 {
7707 /* Convert from multi-byte to single-byte. */
7708 int i, c, n;
7709 unsigned char work[1];
7710
7711 /* Convert a multibyte string to single-byte. */
7712 for (i = 0; i < nbytes; i += n)
7713 {
7714 c = string_char_and_length (s + i, nbytes - i, &n);
7715 work[0] = (SINGLE_BYTE_CHAR_P (c)
7716 ? c
7717 : multibyte_char_to_unibyte (c, Qnil));
7718 insert_1_both (work, 1, 1, 1, 0, 0);
7719 }
7720 }
7721 else if (!multibyte_p
7722 && !NILP (current_buffer->enable_multibyte_characters))
7723 {
7724 /* Convert from single-byte to multi-byte. */
7725 int i, c, n;
7726 const unsigned char *msg = (const unsigned char *) s;
7727 unsigned char str[MAX_MULTIBYTE_LENGTH];
7728
7729 /* Convert a single-byte string to multibyte. */
7730 for (i = 0; i < nbytes; i++)
7731 {
7732 c = unibyte_char_to_multibyte (msg[i]);
7733 n = CHAR_STRING (c, str);
7734 insert_1_both (str, 1, n, 1, 0, 0);
7735 }
7736 }
7737 else
7738 insert_1 (s, nbytes, 1, 0, 0);
7739 }
7740
7741 return 0;
7742 }
7743
7744
7745 /* Clear messages. CURRENT_P non-zero means clear the current
7746 message. LAST_DISPLAYED_P non-zero means clear the message
7747 last displayed. */
7748
7749 void
7750 clear_message (current_p, last_displayed_p)
7751 int current_p, last_displayed_p;
7752 {
7753 if (current_p)
7754 {
7755 echo_area_buffer[0] = Qnil;
7756 message_cleared_p = 1;
7757 }
7758
7759 if (last_displayed_p)
7760 echo_area_buffer[1] = Qnil;
7761
7762 message_buf_print = 0;
7763 }
7764
7765 /* Clear garbaged frames.
7766
7767 This function is used where the old redisplay called
7768 redraw_garbaged_frames which in turn called redraw_frame which in
7769 turn called clear_frame. The call to clear_frame was a source of
7770 flickering. I believe a clear_frame is not necessary. It should
7771 suffice in the new redisplay to invalidate all current matrices,
7772 and ensure a complete redisplay of all windows. */
7773
7774 static void
7775 clear_garbaged_frames ()
7776 {
7777 if (frame_garbaged)
7778 {
7779 Lisp_Object tail, frame;
7780 int changed_count = 0;
7781
7782 FOR_EACH_FRAME (tail, frame)
7783 {
7784 struct frame *f = XFRAME (frame);
7785
7786 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7787 {
7788 if (f->resized_p)
7789 {
7790 Fredraw_frame (frame);
7791 f->force_flush_display_p = 1;
7792 }
7793 clear_current_matrices (f);
7794 changed_count++;
7795 f->garbaged = 0;
7796 f->resized_p = 0;
7797 }
7798 }
7799
7800 frame_garbaged = 0;
7801 if (changed_count)
7802 ++windows_or_buffers_changed;
7803 }
7804 }
7805
7806
7807 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7808 is non-zero update selected_frame. Value is non-zero if the
7809 mini-windows height has been changed. */
7810
7811 static int
7812 echo_area_display (update_frame_p)
7813 int update_frame_p;
7814 {
7815 Lisp_Object mini_window;
7816 struct window *w;
7817 struct frame *f;
7818 int window_height_changed_p = 0;
7819 struct frame *sf = SELECTED_FRAME ();
7820
7821 mini_window = FRAME_MINIBUF_WINDOW (sf);
7822 w = XWINDOW (mini_window);
7823 f = XFRAME (WINDOW_FRAME (w));
7824
7825 /* Don't display if frame is invisible or not yet initialized. */
7826 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7827 return 0;
7828
7829 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7830 #ifndef MAC_OS8
7831 #ifdef HAVE_WINDOW_SYSTEM
7832 /* When Emacs starts, selected_frame may be a visible terminal
7833 frame, even if we run under a window system. If we let this
7834 through, a message would be displayed on the terminal. */
7835 if (EQ (selected_frame, Vterminal_frame)
7836 && !NILP (Vwindow_system))
7837 return 0;
7838 #endif /* HAVE_WINDOW_SYSTEM */
7839 #endif
7840
7841 /* Redraw garbaged frames. */
7842 if (frame_garbaged)
7843 clear_garbaged_frames ();
7844
7845 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7846 {
7847 echo_area_window = mini_window;
7848 window_height_changed_p = display_echo_area (w);
7849 w->must_be_updated_p = 1;
7850
7851 /* Update the display, unless called from redisplay_internal.
7852 Also don't update the screen during redisplay itself. The
7853 update will happen at the end of redisplay, and an update
7854 here could cause confusion. */
7855 if (update_frame_p && !redisplaying_p)
7856 {
7857 int n = 0;
7858
7859 /* If the display update has been interrupted by pending
7860 input, update mode lines in the frame. Due to the
7861 pending input, it might have been that redisplay hasn't
7862 been called, so that mode lines above the echo area are
7863 garbaged. This looks odd, so we prevent it here. */
7864 if (!display_completed)
7865 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7866
7867 if (window_height_changed_p
7868 /* Don't do this if Emacs is shutting down. Redisplay
7869 needs to run hooks. */
7870 && !NILP (Vrun_hooks))
7871 {
7872 /* Must update other windows. Likewise as in other
7873 cases, don't let this update be interrupted by
7874 pending input. */
7875 int count = SPECPDL_INDEX ();
7876 specbind (Qredisplay_dont_pause, Qt);
7877 windows_or_buffers_changed = 1;
7878 redisplay_internal (0);
7879 unbind_to (count, Qnil);
7880 }
7881 else if (FRAME_WINDOW_P (f) && n == 0)
7882 {
7883 /* Window configuration is the same as before.
7884 Can do with a display update of the echo area,
7885 unless we displayed some mode lines. */
7886 update_single_window (w, 1);
7887 rif->flush_display (f);
7888 }
7889 else
7890 update_frame (f, 1, 1);
7891
7892 /* If cursor is in the echo area, make sure that the next
7893 redisplay displays the minibuffer, so that the cursor will
7894 be replaced with what the minibuffer wants. */
7895 if (cursor_in_echo_area)
7896 ++windows_or_buffers_changed;
7897 }
7898 }
7899 else if (!EQ (mini_window, selected_window))
7900 windows_or_buffers_changed++;
7901
7902 /* Last displayed message is now the current message. */
7903 echo_area_buffer[1] = echo_area_buffer[0];
7904
7905 /* Prevent redisplay optimization in redisplay_internal by resetting
7906 this_line_start_pos. This is done because the mini-buffer now
7907 displays the message instead of its buffer text. */
7908 if (EQ (mini_window, selected_window))
7909 CHARPOS (this_line_start_pos) = 0;
7910
7911 return window_height_changed_p;
7912 }
7913
7914
7915 \f
7916 /***********************************************************************
7917 Frame Titles
7918 ***********************************************************************/
7919
7920
7921 /* The frame title buffering code is also used by Fformat_mode_line.
7922 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7923
7924 /* A buffer for constructing frame titles in it; allocated from the
7925 heap in init_xdisp and resized as needed in store_frame_title_char. */
7926
7927 static char *frame_title_buf;
7928
7929 /* The buffer's end, and a current output position in it. */
7930
7931 static char *frame_title_buf_end;
7932 static char *frame_title_ptr;
7933
7934
7935 /* Store a single character C for the frame title in frame_title_buf.
7936 Re-allocate frame_title_buf if necessary. */
7937
7938 static void
7939 #ifdef PROTOTYPES
7940 store_frame_title_char (char c)
7941 #else
7942 store_frame_title_char (c)
7943 char c;
7944 #endif
7945 {
7946 /* If output position has reached the end of the allocated buffer,
7947 double the buffer's size. */
7948 if (frame_title_ptr == frame_title_buf_end)
7949 {
7950 int len = frame_title_ptr - frame_title_buf;
7951 int new_size = 2 * len * sizeof *frame_title_buf;
7952 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7953 frame_title_buf_end = frame_title_buf + new_size;
7954 frame_title_ptr = frame_title_buf + len;
7955 }
7956
7957 *frame_title_ptr++ = c;
7958 }
7959
7960
7961 /* Store part of a frame title in frame_title_buf, beginning at
7962 frame_title_ptr. STR is the string to store. Do not copy
7963 characters that yield more columns than PRECISION; PRECISION <= 0
7964 means copy the whole string. Pad with spaces until FIELD_WIDTH
7965 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7966 pad. Called from display_mode_element when it is used to build a
7967 frame title. */
7968
7969 static int
7970 store_frame_title (str, field_width, precision)
7971 const unsigned char *str;
7972 int field_width, precision;
7973 {
7974 int n = 0;
7975 int dummy, nbytes;
7976
7977 /* Copy at most PRECISION chars from STR. */
7978 nbytes = strlen (str);
7979 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7980 while (nbytes--)
7981 store_frame_title_char (*str++);
7982
7983 /* Fill up with spaces until FIELD_WIDTH reached. */
7984 while (field_width > 0
7985 && n < field_width)
7986 {
7987 store_frame_title_char (' ');
7988 ++n;
7989 }
7990
7991 return n;
7992 }
7993
7994 #ifdef HAVE_WINDOW_SYSTEM
7995
7996 /* Set the title of FRAME, if it has changed. The title format is
7997 Vicon_title_format if FRAME is iconified, otherwise it is
7998 frame_title_format. */
7999
8000 static void
8001 x_consider_frame_title (frame)
8002 Lisp_Object frame;
8003 {
8004 struct frame *f = XFRAME (frame);
8005
8006 if (FRAME_WINDOW_P (f)
8007 || FRAME_MINIBUF_ONLY_P (f)
8008 || f->explicit_name)
8009 {
8010 /* Do we have more than one visible frame on this X display? */
8011 Lisp_Object tail;
8012 Lisp_Object fmt;
8013 struct buffer *obuf;
8014 int len;
8015 struct it it;
8016
8017 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8018 {
8019 Lisp_Object other_frame = XCAR (tail);
8020 struct frame *tf = XFRAME (other_frame);
8021
8022 if (tf != f
8023 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8024 && !FRAME_MINIBUF_ONLY_P (tf)
8025 && !EQ (other_frame, tip_frame)
8026 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8027 break;
8028 }
8029
8030 /* Set global variable indicating that multiple frames exist. */
8031 multiple_frames = CONSP (tail);
8032
8033 /* Switch to the buffer of selected window of the frame. Set up
8034 frame_title_ptr so that display_mode_element will output into it;
8035 then display the title. */
8036 obuf = current_buffer;
8037 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8038 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8039 frame_title_ptr = frame_title_buf;
8040 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8041 NULL, DEFAULT_FACE_ID);
8042 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8043 len = frame_title_ptr - frame_title_buf;
8044 frame_title_ptr = NULL;
8045 set_buffer_internal_1 (obuf);
8046
8047 /* Set the title only if it's changed. This avoids consing in
8048 the common case where it hasn't. (If it turns out that we've
8049 already wasted too much time by walking through the list with
8050 display_mode_element, then we might need to optimize at a
8051 higher level than this.) */
8052 if (! STRINGP (f->name)
8053 || SBYTES (f->name) != len
8054 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8055 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8056 }
8057 }
8058
8059 #endif /* not HAVE_WINDOW_SYSTEM */
8060
8061
8062
8063 \f
8064 /***********************************************************************
8065 Menu Bars
8066 ***********************************************************************/
8067
8068
8069 /* Prepare for redisplay by updating menu-bar item lists when
8070 appropriate. This can call eval. */
8071
8072 void
8073 prepare_menu_bars ()
8074 {
8075 int all_windows;
8076 struct gcpro gcpro1, gcpro2;
8077 struct frame *f;
8078 Lisp_Object tooltip_frame;
8079
8080 #ifdef HAVE_WINDOW_SYSTEM
8081 tooltip_frame = tip_frame;
8082 #else
8083 tooltip_frame = Qnil;
8084 #endif
8085
8086 /* Update all frame titles based on their buffer names, etc. We do
8087 this before the menu bars so that the buffer-menu will show the
8088 up-to-date frame titles. */
8089 #ifdef HAVE_WINDOW_SYSTEM
8090 if (windows_or_buffers_changed || update_mode_lines)
8091 {
8092 Lisp_Object tail, frame;
8093
8094 FOR_EACH_FRAME (tail, frame)
8095 {
8096 f = XFRAME (frame);
8097 if (!EQ (frame, tooltip_frame)
8098 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8099 x_consider_frame_title (frame);
8100 }
8101 }
8102 #endif /* HAVE_WINDOW_SYSTEM */
8103
8104 /* Update the menu bar item lists, if appropriate. This has to be
8105 done before any actual redisplay or generation of display lines. */
8106 all_windows = (update_mode_lines
8107 || buffer_shared > 1
8108 || windows_or_buffers_changed);
8109 if (all_windows)
8110 {
8111 Lisp_Object tail, frame;
8112 int count = SPECPDL_INDEX ();
8113
8114 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8115
8116 FOR_EACH_FRAME (tail, frame)
8117 {
8118 f = XFRAME (frame);
8119
8120 /* Ignore tooltip frame. */
8121 if (EQ (frame, tooltip_frame))
8122 continue;
8123
8124 /* If a window on this frame changed size, report that to
8125 the user and clear the size-change flag. */
8126 if (FRAME_WINDOW_SIZES_CHANGED (f))
8127 {
8128 Lisp_Object functions;
8129
8130 /* Clear flag first in case we get an error below. */
8131 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8132 functions = Vwindow_size_change_functions;
8133 GCPRO2 (tail, functions);
8134
8135 while (CONSP (functions))
8136 {
8137 call1 (XCAR (functions), frame);
8138 functions = XCDR (functions);
8139 }
8140 UNGCPRO;
8141 }
8142
8143 GCPRO1 (tail);
8144 update_menu_bar (f, 0);
8145 #ifdef HAVE_WINDOW_SYSTEM
8146 update_tool_bar (f, 0);
8147 #endif
8148 UNGCPRO;
8149 }
8150
8151 unbind_to (count, Qnil);
8152 }
8153 else
8154 {
8155 struct frame *sf = SELECTED_FRAME ();
8156 update_menu_bar (sf, 1);
8157 #ifdef HAVE_WINDOW_SYSTEM
8158 update_tool_bar (sf, 1);
8159 #endif
8160 }
8161
8162 /* Motif needs this. See comment in xmenu.c. Turn it off when
8163 pending_menu_activation is not defined. */
8164 #ifdef USE_X_TOOLKIT
8165 pending_menu_activation = 0;
8166 #endif
8167 }
8168
8169
8170 /* Update the menu bar item list for frame F. This has to be done
8171 before we start to fill in any display lines, because it can call
8172 eval.
8173
8174 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8175
8176 static void
8177 update_menu_bar (f, save_match_data)
8178 struct frame *f;
8179 int save_match_data;
8180 {
8181 Lisp_Object window;
8182 register struct window *w;
8183
8184 /* If called recursively during a menu update, do nothing. This can
8185 happen when, for instance, an activate-menubar-hook causes a
8186 redisplay. */
8187 if (inhibit_menubar_update)
8188 return;
8189
8190 window = FRAME_SELECTED_WINDOW (f);
8191 w = XWINDOW (window);
8192
8193 #if 0 /* The if statement below this if statement used to include the
8194 condition !NILP (w->update_mode_line), rather than using
8195 update_mode_lines directly, and this if statement may have
8196 been added to make that condition work. Now the if
8197 statement below matches its comment, this isn't needed. */
8198 if (update_mode_lines)
8199 w->update_mode_line = Qt;
8200 #endif
8201
8202 if (FRAME_WINDOW_P (f)
8203 ?
8204 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8205 || defined (USE_GTK)
8206 FRAME_EXTERNAL_MENU_BAR (f)
8207 #else
8208 FRAME_MENU_BAR_LINES (f) > 0
8209 #endif
8210 : FRAME_MENU_BAR_LINES (f) > 0)
8211 {
8212 /* If the user has switched buffers or windows, we need to
8213 recompute to reflect the new bindings. But we'll
8214 recompute when update_mode_lines is set too; that means
8215 that people can use force-mode-line-update to request
8216 that the menu bar be recomputed. The adverse effect on
8217 the rest of the redisplay algorithm is about the same as
8218 windows_or_buffers_changed anyway. */
8219 if (windows_or_buffers_changed
8220 /* This used to test w->update_mode_line, but we believe
8221 there is no need to recompute the menu in that case. */
8222 || update_mode_lines
8223 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8224 < BUF_MODIFF (XBUFFER (w->buffer)))
8225 != !NILP (w->last_had_star))
8226 || ((!NILP (Vtransient_mark_mode)
8227 && !NILP (XBUFFER (w->buffer)->mark_active))
8228 != !NILP (w->region_showing)))
8229 {
8230 struct buffer *prev = current_buffer;
8231 int count = SPECPDL_INDEX ();
8232
8233 specbind (Qinhibit_menubar_update, Qt);
8234
8235 set_buffer_internal_1 (XBUFFER (w->buffer));
8236 if (save_match_data)
8237 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8238 if (NILP (Voverriding_local_map_menu_flag))
8239 {
8240 specbind (Qoverriding_terminal_local_map, Qnil);
8241 specbind (Qoverriding_local_map, Qnil);
8242 }
8243
8244 /* Run the Lucid hook. */
8245 safe_run_hooks (Qactivate_menubar_hook);
8246
8247 /* If it has changed current-menubar from previous value,
8248 really recompute the menu-bar from the value. */
8249 if (! NILP (Vlucid_menu_bar_dirty_flag))
8250 call0 (Qrecompute_lucid_menubar);
8251
8252 safe_run_hooks (Qmenu_bar_update_hook);
8253 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8254
8255 /* Redisplay the menu bar in case we changed it. */
8256 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8257 || defined (USE_GTK)
8258 if (FRAME_WINDOW_P (f)
8259 #if defined (MAC_OS)
8260 /* All frames on Mac OS share the same menubar. So only the
8261 selected frame should be allowed to set it. */
8262 && f == SELECTED_FRAME ()
8263 #endif
8264 )
8265 set_frame_menubar (f, 0, 0);
8266 else
8267 /* On a terminal screen, the menu bar is an ordinary screen
8268 line, and this makes it get updated. */
8269 w->update_mode_line = Qt;
8270 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8271 /* In the non-toolkit version, the menu bar is an ordinary screen
8272 line, and this makes it get updated. */
8273 w->update_mode_line = Qt;
8274 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8275
8276 unbind_to (count, Qnil);
8277 set_buffer_internal_1 (prev);
8278 }
8279 }
8280 }
8281
8282
8283 \f
8284 /***********************************************************************
8285 Output Cursor
8286 ***********************************************************************/
8287
8288 #ifdef HAVE_WINDOW_SYSTEM
8289
8290 /* EXPORT:
8291 Nominal cursor position -- where to draw output.
8292 HPOS and VPOS are window relative glyph matrix coordinates.
8293 X and Y are window relative pixel coordinates. */
8294
8295 struct cursor_pos output_cursor;
8296
8297
8298 /* EXPORT:
8299 Set the global variable output_cursor to CURSOR. All cursor
8300 positions are relative to updated_window. */
8301
8302 void
8303 set_output_cursor (cursor)
8304 struct cursor_pos *cursor;
8305 {
8306 output_cursor.hpos = cursor->hpos;
8307 output_cursor.vpos = cursor->vpos;
8308 output_cursor.x = cursor->x;
8309 output_cursor.y = cursor->y;
8310 }
8311
8312
8313 /* EXPORT for RIF:
8314 Set a nominal cursor position.
8315
8316 HPOS and VPOS are column/row positions in a window glyph matrix. X
8317 and Y are window text area relative pixel positions.
8318
8319 If this is done during an update, updated_window will contain the
8320 window that is being updated and the position is the future output
8321 cursor position for that window. If updated_window is null, use
8322 selected_window and display the cursor at the given position. */
8323
8324 void
8325 x_cursor_to (vpos, hpos, y, x)
8326 int vpos, hpos, y, x;
8327 {
8328 struct window *w;
8329
8330 /* If updated_window is not set, work on selected_window. */
8331 if (updated_window)
8332 w = updated_window;
8333 else
8334 w = XWINDOW (selected_window);
8335
8336 /* Set the output cursor. */
8337 output_cursor.hpos = hpos;
8338 output_cursor.vpos = vpos;
8339 output_cursor.x = x;
8340 output_cursor.y = y;
8341
8342 /* If not called as part of an update, really display the cursor.
8343 This will also set the cursor position of W. */
8344 if (updated_window == NULL)
8345 {
8346 BLOCK_INPUT;
8347 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8348 if (rif->flush_display_optional)
8349 rif->flush_display_optional (SELECTED_FRAME ());
8350 UNBLOCK_INPUT;
8351 }
8352 }
8353
8354 #endif /* HAVE_WINDOW_SYSTEM */
8355
8356 \f
8357 /***********************************************************************
8358 Tool-bars
8359 ***********************************************************************/
8360
8361 #ifdef HAVE_WINDOW_SYSTEM
8362
8363 /* Where the mouse was last time we reported a mouse event. */
8364
8365 FRAME_PTR last_mouse_frame;
8366
8367 /* Tool-bar item index of the item on which a mouse button was pressed
8368 or -1. */
8369
8370 int last_tool_bar_item;
8371
8372
8373 /* Update the tool-bar item list for frame F. This has to be done
8374 before we start to fill in any display lines. Called from
8375 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8376 and restore it here. */
8377
8378 static void
8379 update_tool_bar (f, save_match_data)
8380 struct frame *f;
8381 int save_match_data;
8382 {
8383 #ifdef USE_GTK
8384 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8385 #else
8386 int do_update = WINDOWP (f->tool_bar_window)
8387 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8388 #endif
8389
8390 if (do_update)
8391 {
8392 Lisp_Object window;
8393 struct window *w;
8394
8395 window = FRAME_SELECTED_WINDOW (f);
8396 w = XWINDOW (window);
8397
8398 /* If the user has switched buffers or windows, we need to
8399 recompute to reflect the new bindings. But we'll
8400 recompute when update_mode_lines is set too; that means
8401 that people can use force-mode-line-update to request
8402 that the menu bar be recomputed. The adverse effect on
8403 the rest of the redisplay algorithm is about the same as
8404 windows_or_buffers_changed anyway. */
8405 if (windows_or_buffers_changed
8406 || !NILP (w->update_mode_line)
8407 || update_mode_lines
8408 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8409 < BUF_MODIFF (XBUFFER (w->buffer)))
8410 != !NILP (w->last_had_star))
8411 || ((!NILP (Vtransient_mark_mode)
8412 && !NILP (XBUFFER (w->buffer)->mark_active))
8413 != !NILP (w->region_showing)))
8414 {
8415 struct buffer *prev = current_buffer;
8416 int count = SPECPDL_INDEX ();
8417 Lisp_Object old_tool_bar;
8418 struct gcpro gcpro1;
8419
8420 /* Set current_buffer to the buffer of the selected
8421 window of the frame, so that we get the right local
8422 keymaps. */
8423 set_buffer_internal_1 (XBUFFER (w->buffer));
8424
8425 /* Save match data, if we must. */
8426 if (save_match_data)
8427 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8428
8429 /* Make sure that we don't accidentally use bogus keymaps. */
8430 if (NILP (Voverriding_local_map_menu_flag))
8431 {
8432 specbind (Qoverriding_terminal_local_map, Qnil);
8433 specbind (Qoverriding_local_map, Qnil);
8434 }
8435
8436 old_tool_bar = f->tool_bar_items;
8437 GCPRO1 (old_tool_bar);
8438
8439 /* Build desired tool-bar items from keymaps. */
8440 BLOCK_INPUT;
8441 f->tool_bar_items
8442 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8443 UNBLOCK_INPUT;
8444
8445 /* Redisplay the tool-bar if we changed it. */
8446 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8447 w->update_mode_line = Qt;
8448
8449 UNGCPRO;
8450
8451 unbind_to (count, Qnil);
8452 set_buffer_internal_1 (prev);
8453 }
8454 }
8455 }
8456
8457
8458 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8459 F's desired tool-bar contents. F->tool_bar_items must have
8460 been set up previously by calling prepare_menu_bars. */
8461
8462 static void
8463 build_desired_tool_bar_string (f)
8464 struct frame *f;
8465 {
8466 int i, size, size_needed;
8467 struct gcpro gcpro1, gcpro2, gcpro3;
8468 Lisp_Object image, plist, props;
8469
8470 image = plist = props = Qnil;
8471 GCPRO3 (image, plist, props);
8472
8473 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8474 Otherwise, make a new string. */
8475
8476 /* The size of the string we might be able to reuse. */
8477 size = (STRINGP (f->desired_tool_bar_string)
8478 ? SCHARS (f->desired_tool_bar_string)
8479 : 0);
8480
8481 /* We need one space in the string for each image. */
8482 size_needed = f->n_tool_bar_items;
8483
8484 /* Reuse f->desired_tool_bar_string, if possible. */
8485 if (size < size_needed || NILP (f->desired_tool_bar_string))
8486 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8487 make_number (' '));
8488 else
8489 {
8490 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8491 Fremove_text_properties (make_number (0), make_number (size),
8492 props, f->desired_tool_bar_string);
8493 }
8494
8495 /* Put a `display' property on the string for the images to display,
8496 put a `menu_item' property on tool-bar items with a value that
8497 is the index of the item in F's tool-bar item vector. */
8498 for (i = 0; i < f->n_tool_bar_items; ++i)
8499 {
8500 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8501
8502 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8503 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8504 int hmargin, vmargin, relief, idx, end;
8505 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8506
8507 /* If image is a vector, choose the image according to the
8508 button state. */
8509 image = PROP (TOOL_BAR_ITEM_IMAGES);
8510 if (VECTORP (image))
8511 {
8512 if (enabled_p)
8513 idx = (selected_p
8514 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8515 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8516 else
8517 idx = (selected_p
8518 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8519 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8520
8521 xassert (ASIZE (image) >= idx);
8522 image = AREF (image, idx);
8523 }
8524 else
8525 idx = -1;
8526
8527 /* Ignore invalid image specifications. */
8528 if (!valid_image_p (image))
8529 continue;
8530
8531 /* Display the tool-bar button pressed, or depressed. */
8532 plist = Fcopy_sequence (XCDR (image));
8533
8534 /* Compute margin and relief to draw. */
8535 relief = (tool_bar_button_relief >= 0
8536 ? tool_bar_button_relief
8537 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8538 hmargin = vmargin = relief;
8539
8540 if (INTEGERP (Vtool_bar_button_margin)
8541 && XINT (Vtool_bar_button_margin) > 0)
8542 {
8543 hmargin += XFASTINT (Vtool_bar_button_margin);
8544 vmargin += XFASTINT (Vtool_bar_button_margin);
8545 }
8546 else if (CONSP (Vtool_bar_button_margin))
8547 {
8548 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8549 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8550 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8551
8552 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8553 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8554 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8555 }
8556
8557 if (auto_raise_tool_bar_buttons_p)
8558 {
8559 /* Add a `:relief' property to the image spec if the item is
8560 selected. */
8561 if (selected_p)
8562 {
8563 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8564 hmargin -= relief;
8565 vmargin -= relief;
8566 }
8567 }
8568 else
8569 {
8570 /* If image is selected, display it pressed, i.e. with a
8571 negative relief. If it's not selected, display it with a
8572 raised relief. */
8573 plist = Fplist_put (plist, QCrelief,
8574 (selected_p
8575 ? make_number (-relief)
8576 : make_number (relief)));
8577 hmargin -= relief;
8578 vmargin -= relief;
8579 }
8580
8581 /* Put a margin around the image. */
8582 if (hmargin || vmargin)
8583 {
8584 if (hmargin == vmargin)
8585 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8586 else
8587 plist = Fplist_put (plist, QCmargin,
8588 Fcons (make_number (hmargin),
8589 make_number (vmargin)));
8590 }
8591
8592 /* If button is not enabled, and we don't have special images
8593 for the disabled state, make the image appear disabled by
8594 applying an appropriate algorithm to it. */
8595 if (!enabled_p && idx < 0)
8596 plist = Fplist_put (plist, QCconversion, Qdisabled);
8597
8598 /* Put a `display' text property on the string for the image to
8599 display. Put a `menu-item' property on the string that gives
8600 the start of this item's properties in the tool-bar items
8601 vector. */
8602 image = Fcons (Qimage, plist);
8603 props = list4 (Qdisplay, image,
8604 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8605
8606 /* Let the last image hide all remaining spaces in the tool bar
8607 string. The string can be longer than needed when we reuse a
8608 previous string. */
8609 if (i + 1 == f->n_tool_bar_items)
8610 end = SCHARS (f->desired_tool_bar_string);
8611 else
8612 end = i + 1;
8613 Fadd_text_properties (make_number (i), make_number (end),
8614 props, f->desired_tool_bar_string);
8615 #undef PROP
8616 }
8617
8618 UNGCPRO;
8619 }
8620
8621
8622 /* Display one line of the tool-bar of frame IT->f. */
8623
8624 static void
8625 display_tool_bar_line (it)
8626 struct it *it;
8627 {
8628 struct glyph_row *row = it->glyph_row;
8629 int max_x = it->last_visible_x;
8630 struct glyph *last;
8631
8632 prepare_desired_row (row);
8633 row->y = it->current_y;
8634
8635 /* Note that this isn't made use of if the face hasn't a box,
8636 so there's no need to check the face here. */
8637 it->start_of_box_run_p = 1;
8638
8639 while (it->current_x < max_x)
8640 {
8641 int x_before, x, n_glyphs_before, i, nglyphs;
8642
8643 /* Get the next display element. */
8644 if (!get_next_display_element (it))
8645 break;
8646
8647 /* Produce glyphs. */
8648 x_before = it->current_x;
8649 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8650 PRODUCE_GLYPHS (it);
8651
8652 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8653 i = 0;
8654 x = x_before;
8655 while (i < nglyphs)
8656 {
8657 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8658
8659 if (x + glyph->pixel_width > max_x)
8660 {
8661 /* Glyph doesn't fit on line. */
8662 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8663 it->current_x = x;
8664 goto out;
8665 }
8666
8667 ++it->hpos;
8668 x += glyph->pixel_width;
8669 ++i;
8670 }
8671
8672 /* Stop at line ends. */
8673 if (ITERATOR_AT_END_OF_LINE_P (it))
8674 break;
8675
8676 set_iterator_to_next (it, 1);
8677 }
8678
8679 out:;
8680
8681 row->displays_text_p = row->used[TEXT_AREA] != 0;
8682 extend_face_to_end_of_line (it);
8683 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8684 last->right_box_line_p = 1;
8685 if (last == row->glyphs[TEXT_AREA])
8686 last->left_box_line_p = 1;
8687 compute_line_metrics (it);
8688
8689 /* If line is empty, make it occupy the rest of the tool-bar. */
8690 if (!row->displays_text_p)
8691 {
8692 row->height = row->phys_height = it->last_visible_y - row->y;
8693 row->ascent = row->phys_ascent = 0;
8694 }
8695
8696 row->full_width_p = 1;
8697 row->continued_p = 0;
8698 row->truncated_on_left_p = 0;
8699 row->truncated_on_right_p = 0;
8700
8701 it->current_x = it->hpos = 0;
8702 it->current_y += row->height;
8703 ++it->vpos;
8704 ++it->glyph_row;
8705 }
8706
8707
8708 /* Value is the number of screen lines needed to make all tool-bar
8709 items of frame F visible. */
8710
8711 static int
8712 tool_bar_lines_needed (f)
8713 struct frame *f;
8714 {
8715 struct window *w = XWINDOW (f->tool_bar_window);
8716 struct it it;
8717
8718 /* Initialize an iterator for iteration over
8719 F->desired_tool_bar_string in the tool-bar window of frame F. */
8720 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8721 it.first_visible_x = 0;
8722 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8723 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8724
8725 while (!ITERATOR_AT_END_P (&it))
8726 {
8727 it.glyph_row = w->desired_matrix->rows;
8728 clear_glyph_row (it.glyph_row);
8729 display_tool_bar_line (&it);
8730 }
8731
8732 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8733 }
8734
8735
8736 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8737 0, 1, 0,
8738 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8739 (frame)
8740 Lisp_Object frame;
8741 {
8742 struct frame *f;
8743 struct window *w;
8744 int nlines = 0;
8745
8746 if (NILP (frame))
8747 frame = selected_frame;
8748 else
8749 CHECK_FRAME (frame);
8750 f = XFRAME (frame);
8751
8752 if (WINDOWP (f->tool_bar_window)
8753 || (w = XWINDOW (f->tool_bar_window),
8754 WINDOW_TOTAL_LINES (w) > 0))
8755 {
8756 update_tool_bar (f, 1);
8757 if (f->n_tool_bar_items)
8758 {
8759 build_desired_tool_bar_string (f);
8760 nlines = tool_bar_lines_needed (f);
8761 }
8762 }
8763
8764 return make_number (nlines);
8765 }
8766
8767
8768 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8769 height should be changed. */
8770
8771 static int
8772 redisplay_tool_bar (f)
8773 struct frame *f;
8774 {
8775 struct window *w;
8776 struct it it;
8777 struct glyph_row *row;
8778 int change_height_p = 0;
8779
8780 #ifdef USE_GTK
8781 if (FRAME_EXTERNAL_TOOL_BAR (f))
8782 update_frame_tool_bar (f);
8783 return 0;
8784 #endif
8785
8786 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8787 do anything. This means you must start with tool-bar-lines
8788 non-zero to get the auto-sizing effect. Or in other words, you
8789 can turn off tool-bars by specifying tool-bar-lines zero. */
8790 if (!WINDOWP (f->tool_bar_window)
8791 || (w = XWINDOW (f->tool_bar_window),
8792 WINDOW_TOTAL_LINES (w) == 0))
8793 return 0;
8794
8795 /* Set up an iterator for the tool-bar window. */
8796 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8797 it.first_visible_x = 0;
8798 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8799 row = it.glyph_row;
8800
8801 /* Build a string that represents the contents of the tool-bar. */
8802 build_desired_tool_bar_string (f);
8803 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8804
8805 /* Display as many lines as needed to display all tool-bar items. */
8806 while (it.current_y < it.last_visible_y)
8807 display_tool_bar_line (&it);
8808
8809 /* It doesn't make much sense to try scrolling in the tool-bar
8810 window, so don't do it. */
8811 w->desired_matrix->no_scrolling_p = 1;
8812 w->must_be_updated_p = 1;
8813
8814 if (auto_resize_tool_bars_p)
8815 {
8816 int nlines;
8817
8818 /* If we couldn't display everything, change the tool-bar's
8819 height. */
8820 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8821 change_height_p = 1;
8822
8823 /* If there are blank lines at the end, except for a partially
8824 visible blank line at the end that is smaller than
8825 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8826 row = it.glyph_row - 1;
8827 if (!row->displays_text_p
8828 && row->height >= FRAME_LINE_HEIGHT (f))
8829 change_height_p = 1;
8830
8831 /* If row displays tool-bar items, but is partially visible,
8832 change the tool-bar's height. */
8833 if (row->displays_text_p
8834 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8835 change_height_p = 1;
8836
8837 /* Resize windows as needed by changing the `tool-bar-lines'
8838 frame parameter. */
8839 if (change_height_p
8840 && (nlines = tool_bar_lines_needed (f),
8841 nlines != WINDOW_TOTAL_LINES (w)))
8842 {
8843 extern Lisp_Object Qtool_bar_lines;
8844 Lisp_Object frame;
8845 int old_height = WINDOW_TOTAL_LINES (w);
8846
8847 XSETFRAME (frame, f);
8848 clear_glyph_matrix (w->desired_matrix);
8849 Fmodify_frame_parameters (frame,
8850 Fcons (Fcons (Qtool_bar_lines,
8851 make_number (nlines)),
8852 Qnil));
8853 if (WINDOW_TOTAL_LINES (w) != old_height)
8854 fonts_changed_p = 1;
8855 }
8856 }
8857
8858 return change_height_p;
8859 }
8860
8861
8862 /* Get information about the tool-bar item which is displayed in GLYPH
8863 on frame F. Return in *PROP_IDX the index where tool-bar item
8864 properties start in F->tool_bar_items. Value is zero if
8865 GLYPH doesn't display a tool-bar item. */
8866
8867 static int
8868 tool_bar_item_info (f, glyph, prop_idx)
8869 struct frame *f;
8870 struct glyph *glyph;
8871 int *prop_idx;
8872 {
8873 Lisp_Object prop;
8874 int success_p;
8875 int charpos;
8876
8877 /* This function can be called asynchronously, which means we must
8878 exclude any possibility that Fget_text_property signals an
8879 error. */
8880 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8881 charpos = max (0, charpos);
8882
8883 /* Get the text property `menu-item' at pos. The value of that
8884 property is the start index of this item's properties in
8885 F->tool_bar_items. */
8886 prop = Fget_text_property (make_number (charpos),
8887 Qmenu_item, f->current_tool_bar_string);
8888 if (INTEGERP (prop))
8889 {
8890 *prop_idx = XINT (prop);
8891 success_p = 1;
8892 }
8893 else
8894 success_p = 0;
8895
8896 return success_p;
8897 }
8898
8899 \f
8900 /* Get information about the tool-bar item at position X/Y on frame F.
8901 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8902 the current matrix of the tool-bar window of F, or NULL if not
8903 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8904 item in F->tool_bar_items. Value is
8905
8906 -1 if X/Y is not on a tool-bar item
8907 0 if X/Y is on the same item that was highlighted before.
8908 1 otherwise. */
8909
8910 static int
8911 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8912 struct frame *f;
8913 int x, y;
8914 struct glyph **glyph;
8915 int *hpos, *vpos, *prop_idx;
8916 {
8917 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8918 struct window *w = XWINDOW (f->tool_bar_window);
8919 int area;
8920
8921 /* Find the glyph under X/Y. */
8922 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8923 if (*glyph == NULL)
8924 return -1;
8925
8926 /* Get the start of this tool-bar item's properties in
8927 f->tool_bar_items. */
8928 if (!tool_bar_item_info (f, *glyph, prop_idx))
8929 return -1;
8930
8931 /* Is mouse on the highlighted item? */
8932 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8933 && *vpos >= dpyinfo->mouse_face_beg_row
8934 && *vpos <= dpyinfo->mouse_face_end_row
8935 && (*vpos > dpyinfo->mouse_face_beg_row
8936 || *hpos >= dpyinfo->mouse_face_beg_col)
8937 && (*vpos < dpyinfo->mouse_face_end_row
8938 || *hpos < dpyinfo->mouse_face_end_col
8939 || dpyinfo->mouse_face_past_end))
8940 return 0;
8941
8942 return 1;
8943 }
8944
8945
8946 /* EXPORT:
8947 Handle mouse button event on the tool-bar of frame F, at
8948 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8949 0 for button release. MODIFIERS is event modifiers for button
8950 release. */
8951
8952 void
8953 handle_tool_bar_click (f, x, y, down_p, modifiers)
8954 struct frame *f;
8955 int x, y, down_p;
8956 unsigned int modifiers;
8957 {
8958 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8959 struct window *w = XWINDOW (f->tool_bar_window);
8960 int hpos, vpos, prop_idx;
8961 struct glyph *glyph;
8962 Lisp_Object enabled_p;
8963
8964 /* If not on the highlighted tool-bar item, return. */
8965 frame_to_window_pixel_xy (w, &x, &y);
8966 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8967 return;
8968
8969 /* If item is disabled, do nothing. */
8970 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8971 if (NILP (enabled_p))
8972 return;
8973
8974 if (down_p)
8975 {
8976 /* Show item in pressed state. */
8977 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8978 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8979 last_tool_bar_item = prop_idx;
8980 }
8981 else
8982 {
8983 Lisp_Object key, frame;
8984 struct input_event event;
8985 EVENT_INIT (event);
8986
8987 /* Show item in released state. */
8988 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8989 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8990
8991 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8992
8993 XSETFRAME (frame, f);
8994 event.kind = TOOL_BAR_EVENT;
8995 event.frame_or_window = frame;
8996 event.arg = frame;
8997 kbd_buffer_store_event (&event);
8998
8999 event.kind = TOOL_BAR_EVENT;
9000 event.frame_or_window = frame;
9001 event.arg = key;
9002 event.modifiers = modifiers;
9003 kbd_buffer_store_event (&event);
9004 last_tool_bar_item = -1;
9005 }
9006 }
9007
9008
9009 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9010 tool-bar window-relative coordinates X/Y. Called from
9011 note_mouse_highlight. */
9012
9013 static void
9014 note_tool_bar_highlight (f, x, y)
9015 struct frame *f;
9016 int x, y;
9017 {
9018 Lisp_Object window = f->tool_bar_window;
9019 struct window *w = XWINDOW (window);
9020 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9021 int hpos, vpos;
9022 struct glyph *glyph;
9023 struct glyph_row *row;
9024 int i;
9025 Lisp_Object enabled_p;
9026 int prop_idx;
9027 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9028 int mouse_down_p, rc;
9029
9030 /* Function note_mouse_highlight is called with negative x(y
9031 values when mouse moves outside of the frame. */
9032 if (x <= 0 || y <= 0)
9033 {
9034 clear_mouse_face (dpyinfo);
9035 return;
9036 }
9037
9038 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9039 if (rc < 0)
9040 {
9041 /* Not on tool-bar item. */
9042 clear_mouse_face (dpyinfo);
9043 return;
9044 }
9045 else if (rc == 0)
9046 /* On same tool-bar item as before. */
9047 goto set_help_echo;
9048
9049 clear_mouse_face (dpyinfo);
9050
9051 /* Mouse is down, but on different tool-bar item? */
9052 mouse_down_p = (dpyinfo->grabbed
9053 && f == last_mouse_frame
9054 && FRAME_LIVE_P (f));
9055 if (mouse_down_p
9056 && last_tool_bar_item != prop_idx)
9057 return;
9058
9059 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9060 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9061
9062 /* If tool-bar item is not enabled, don't highlight it. */
9063 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9064 if (!NILP (enabled_p))
9065 {
9066 /* Compute the x-position of the glyph. In front and past the
9067 image is a space. We include this in the highlighted area. */
9068 row = MATRIX_ROW (w->current_matrix, vpos);
9069 for (i = x = 0; i < hpos; ++i)
9070 x += row->glyphs[TEXT_AREA][i].pixel_width;
9071
9072 /* Record this as the current active region. */
9073 dpyinfo->mouse_face_beg_col = hpos;
9074 dpyinfo->mouse_face_beg_row = vpos;
9075 dpyinfo->mouse_face_beg_x = x;
9076 dpyinfo->mouse_face_beg_y = row->y;
9077 dpyinfo->mouse_face_past_end = 0;
9078
9079 dpyinfo->mouse_face_end_col = hpos + 1;
9080 dpyinfo->mouse_face_end_row = vpos;
9081 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9082 dpyinfo->mouse_face_end_y = row->y;
9083 dpyinfo->mouse_face_window = window;
9084 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9085
9086 /* Display it as active. */
9087 show_mouse_face (dpyinfo, draw);
9088 dpyinfo->mouse_face_image_state = draw;
9089 }
9090
9091 set_help_echo:
9092
9093 /* Set help_echo_string to a help string to display for this tool-bar item.
9094 XTread_socket does the rest. */
9095 help_echo_object = help_echo_window = Qnil;
9096 help_echo_pos = -1;
9097 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9098 if (NILP (help_echo_string))
9099 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9100 }
9101
9102 #endif /* HAVE_WINDOW_SYSTEM */
9103
9104
9105 \f
9106 /************************************************************************
9107 Horizontal scrolling
9108 ************************************************************************/
9109
9110 static int hscroll_window_tree P_ ((Lisp_Object));
9111 static int hscroll_windows P_ ((Lisp_Object));
9112
9113 /* For all leaf windows in the window tree rooted at WINDOW, set their
9114 hscroll value so that PT is (i) visible in the window, and (ii) so
9115 that it is not within a certain margin at the window's left and
9116 right border. Value is non-zero if any window's hscroll has been
9117 changed. */
9118
9119 static int
9120 hscroll_window_tree (window)
9121 Lisp_Object window;
9122 {
9123 int hscrolled_p = 0;
9124 int hscroll_relative_p = FLOATP (Vhscroll_step);
9125 int hscroll_step_abs = 0;
9126 double hscroll_step_rel = 0;
9127
9128 if (hscroll_relative_p)
9129 {
9130 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9131 if (hscroll_step_rel < 0)
9132 {
9133 hscroll_relative_p = 0;
9134 hscroll_step_abs = 0;
9135 }
9136 }
9137 else if (INTEGERP (Vhscroll_step))
9138 {
9139 hscroll_step_abs = XINT (Vhscroll_step);
9140 if (hscroll_step_abs < 0)
9141 hscroll_step_abs = 0;
9142 }
9143 else
9144 hscroll_step_abs = 0;
9145
9146 while (WINDOWP (window))
9147 {
9148 struct window *w = XWINDOW (window);
9149
9150 if (WINDOWP (w->hchild))
9151 hscrolled_p |= hscroll_window_tree (w->hchild);
9152 else if (WINDOWP (w->vchild))
9153 hscrolled_p |= hscroll_window_tree (w->vchild);
9154 else if (w->cursor.vpos >= 0)
9155 {
9156 int h_margin;
9157 int text_area_width;
9158 struct glyph_row *current_cursor_row
9159 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9160 struct glyph_row *desired_cursor_row
9161 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9162 struct glyph_row *cursor_row
9163 = (desired_cursor_row->enabled_p
9164 ? desired_cursor_row
9165 : current_cursor_row);
9166
9167 text_area_width = window_box_width (w, TEXT_AREA);
9168
9169 /* Scroll when cursor is inside this scroll margin. */
9170 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9171
9172 if ((XFASTINT (w->hscroll)
9173 && w->cursor.x <= h_margin)
9174 || (cursor_row->enabled_p
9175 && cursor_row->truncated_on_right_p
9176 && (w->cursor.x >= text_area_width - h_margin)))
9177 {
9178 struct it it;
9179 int hscroll;
9180 struct buffer *saved_current_buffer;
9181 int pt;
9182 int wanted_x;
9183
9184 /* Find point in a display of infinite width. */
9185 saved_current_buffer = current_buffer;
9186 current_buffer = XBUFFER (w->buffer);
9187
9188 if (w == XWINDOW (selected_window))
9189 pt = BUF_PT (current_buffer);
9190 else
9191 {
9192 pt = marker_position (w->pointm);
9193 pt = max (BEGV, pt);
9194 pt = min (ZV, pt);
9195 }
9196
9197 /* Move iterator to pt starting at cursor_row->start in
9198 a line with infinite width. */
9199 init_to_row_start (&it, w, cursor_row);
9200 it.last_visible_x = INFINITY;
9201 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9202 current_buffer = saved_current_buffer;
9203
9204 /* Position cursor in window. */
9205 if (!hscroll_relative_p && hscroll_step_abs == 0)
9206 hscroll = max (0, (it.current_x
9207 - (ITERATOR_AT_END_OF_LINE_P (&it)
9208 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9209 : (text_area_width / 2))))
9210 / FRAME_COLUMN_WIDTH (it.f);
9211 else if (w->cursor.x >= text_area_width - h_margin)
9212 {
9213 if (hscroll_relative_p)
9214 wanted_x = text_area_width * (1 - hscroll_step_rel)
9215 - h_margin;
9216 else
9217 wanted_x = text_area_width
9218 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9219 - h_margin;
9220 hscroll
9221 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9222 }
9223 else
9224 {
9225 if (hscroll_relative_p)
9226 wanted_x = text_area_width * hscroll_step_rel
9227 + h_margin;
9228 else
9229 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9230 + h_margin;
9231 hscroll
9232 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9233 }
9234 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9235
9236 /* Don't call Fset_window_hscroll if value hasn't
9237 changed because it will prevent redisplay
9238 optimizations. */
9239 if (XFASTINT (w->hscroll) != hscroll)
9240 {
9241 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9242 w->hscroll = make_number (hscroll);
9243 hscrolled_p = 1;
9244 }
9245 }
9246 }
9247
9248 window = w->next;
9249 }
9250
9251 /* Value is non-zero if hscroll of any leaf window has been changed. */
9252 return hscrolled_p;
9253 }
9254
9255
9256 /* Set hscroll so that cursor is visible and not inside horizontal
9257 scroll margins for all windows in the tree rooted at WINDOW. See
9258 also hscroll_window_tree above. Value is non-zero if any window's
9259 hscroll has been changed. If it has, desired matrices on the frame
9260 of WINDOW are cleared. */
9261
9262 static int
9263 hscroll_windows (window)
9264 Lisp_Object window;
9265 {
9266 int hscrolled_p;
9267
9268 if (automatic_hscrolling_p)
9269 {
9270 hscrolled_p = hscroll_window_tree (window);
9271 if (hscrolled_p)
9272 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9273 }
9274 else
9275 hscrolled_p = 0;
9276 return hscrolled_p;
9277 }
9278
9279
9280 \f
9281 /************************************************************************
9282 Redisplay
9283 ************************************************************************/
9284
9285 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9286 to a non-zero value. This is sometimes handy to have in a debugger
9287 session. */
9288
9289 #if GLYPH_DEBUG
9290
9291 /* First and last unchanged row for try_window_id. */
9292
9293 int debug_first_unchanged_at_end_vpos;
9294 int debug_last_unchanged_at_beg_vpos;
9295
9296 /* Delta vpos and y. */
9297
9298 int debug_dvpos, debug_dy;
9299
9300 /* Delta in characters and bytes for try_window_id. */
9301
9302 int debug_delta, debug_delta_bytes;
9303
9304 /* Values of window_end_pos and window_end_vpos at the end of
9305 try_window_id. */
9306
9307 EMACS_INT debug_end_pos, debug_end_vpos;
9308
9309 /* Append a string to W->desired_matrix->method. FMT is a printf
9310 format string. A1...A9 are a supplement for a variable-length
9311 argument list. If trace_redisplay_p is non-zero also printf the
9312 resulting string to stderr. */
9313
9314 static void
9315 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9316 struct window *w;
9317 char *fmt;
9318 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9319 {
9320 char buffer[512];
9321 char *method = w->desired_matrix->method;
9322 int len = strlen (method);
9323 int size = sizeof w->desired_matrix->method;
9324 int remaining = size - len - 1;
9325
9326 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9327 if (len && remaining)
9328 {
9329 method[len] = '|';
9330 --remaining, ++len;
9331 }
9332
9333 strncpy (method + len, buffer, remaining);
9334
9335 if (trace_redisplay_p)
9336 fprintf (stderr, "%p (%s): %s\n",
9337 w,
9338 ((BUFFERP (w->buffer)
9339 && STRINGP (XBUFFER (w->buffer)->name))
9340 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9341 : "no buffer"),
9342 buffer);
9343 }
9344
9345 #endif /* GLYPH_DEBUG */
9346
9347
9348 /* Value is non-zero if all changes in window W, which displays
9349 current_buffer, are in the text between START and END. START is a
9350 buffer position, END is given as a distance from Z. Used in
9351 redisplay_internal for display optimization. */
9352
9353 static INLINE int
9354 text_outside_line_unchanged_p (w, start, end)
9355 struct window *w;
9356 int start, end;
9357 {
9358 int unchanged_p = 1;
9359
9360 /* If text or overlays have changed, see where. */
9361 if (XFASTINT (w->last_modified) < MODIFF
9362 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9363 {
9364 /* Gap in the line? */
9365 if (GPT < start || Z - GPT < end)
9366 unchanged_p = 0;
9367
9368 /* Changes start in front of the line, or end after it? */
9369 if (unchanged_p
9370 && (BEG_UNCHANGED < start - 1
9371 || END_UNCHANGED < end))
9372 unchanged_p = 0;
9373
9374 /* If selective display, can't optimize if changes start at the
9375 beginning of the line. */
9376 if (unchanged_p
9377 && INTEGERP (current_buffer->selective_display)
9378 && XINT (current_buffer->selective_display) > 0
9379 && (BEG_UNCHANGED < start || GPT <= start))
9380 unchanged_p = 0;
9381
9382 /* If there are overlays at the start or end of the line, these
9383 may have overlay strings with newlines in them. A change at
9384 START, for instance, may actually concern the display of such
9385 overlay strings as well, and they are displayed on different
9386 lines. So, quickly rule out this case. (For the future, it
9387 might be desirable to implement something more telling than
9388 just BEG/END_UNCHANGED.) */
9389 if (unchanged_p)
9390 {
9391 if (BEG + BEG_UNCHANGED == start
9392 && overlay_touches_p (start))
9393 unchanged_p = 0;
9394 if (END_UNCHANGED == end
9395 && overlay_touches_p (Z - end))
9396 unchanged_p = 0;
9397 }
9398 }
9399
9400 return unchanged_p;
9401 }
9402
9403
9404 /* Do a frame update, taking possible shortcuts into account. This is
9405 the main external entry point for redisplay.
9406
9407 If the last redisplay displayed an echo area message and that message
9408 is no longer requested, we clear the echo area or bring back the
9409 mini-buffer if that is in use. */
9410
9411 void
9412 redisplay ()
9413 {
9414 redisplay_internal (0);
9415 }
9416
9417
9418 static Lisp_Object
9419 overlay_arrow_string_or_property (var, pbitmap)
9420 Lisp_Object var;
9421 int *pbitmap;
9422 {
9423 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9424 Lisp_Object bitmap;
9425
9426 if (pbitmap)
9427 {
9428 *pbitmap = 0;
9429 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9430 *pbitmap = XINT (bitmap);
9431 }
9432
9433 if (!NILP (pstr))
9434 return pstr;
9435 return Voverlay_arrow_string;
9436 }
9437
9438 /* Return 1 if there are any overlay-arrows in current_buffer. */
9439 static int
9440 overlay_arrow_in_current_buffer_p ()
9441 {
9442 Lisp_Object vlist;
9443
9444 for (vlist = Voverlay_arrow_variable_list;
9445 CONSP (vlist);
9446 vlist = XCDR (vlist))
9447 {
9448 Lisp_Object var = XCAR (vlist);
9449 Lisp_Object val;
9450
9451 if (!SYMBOLP (var))
9452 continue;
9453 val = find_symbol_value (var);
9454 if (MARKERP (val)
9455 && current_buffer == XMARKER (val)->buffer)
9456 return 1;
9457 }
9458 return 0;
9459 }
9460
9461
9462 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9463 has changed. */
9464
9465 static int
9466 overlay_arrows_changed_p ()
9467 {
9468 Lisp_Object vlist;
9469
9470 for (vlist = Voverlay_arrow_variable_list;
9471 CONSP (vlist);
9472 vlist = XCDR (vlist))
9473 {
9474 Lisp_Object var = XCAR (vlist);
9475 Lisp_Object val, pstr;
9476
9477 if (!SYMBOLP (var))
9478 continue;
9479 val = find_symbol_value (var);
9480 if (!MARKERP (val))
9481 continue;
9482 if (! EQ (COERCE_MARKER (val),
9483 Fget (var, Qlast_arrow_position))
9484 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9485 EQ (pstr, Fget (var, Qlast_arrow_string))))
9486 return 1;
9487 }
9488 return 0;
9489 }
9490
9491 /* Mark overlay arrows to be updated on next redisplay. */
9492
9493 static void
9494 update_overlay_arrows (up_to_date)
9495 int up_to_date;
9496 {
9497 Lisp_Object vlist;
9498
9499 for (vlist = Voverlay_arrow_variable_list;
9500 CONSP (vlist);
9501 vlist = XCDR (vlist))
9502 {
9503 Lisp_Object var = XCAR (vlist);
9504
9505 if (!SYMBOLP (var))
9506 continue;
9507
9508 if (up_to_date > 0)
9509 {
9510 Lisp_Object val = find_symbol_value (var);
9511 Fput (var, Qlast_arrow_position,
9512 COERCE_MARKER (val));
9513 Fput (var, Qlast_arrow_string,
9514 overlay_arrow_string_or_property (var, 0));
9515 }
9516 else if (up_to_date < 0
9517 || !NILP (Fget (var, Qlast_arrow_position)))
9518 {
9519 Fput (var, Qlast_arrow_position, Qt);
9520 Fput (var, Qlast_arrow_string, Qt);
9521 }
9522 }
9523 }
9524
9525
9526 /* Return overlay arrow string at row, or nil. */
9527
9528 static Lisp_Object
9529 overlay_arrow_at_row (f, row, pbitmap)
9530 struct frame *f;
9531 struct glyph_row *row;
9532 int *pbitmap;
9533 {
9534 Lisp_Object vlist;
9535
9536 for (vlist = Voverlay_arrow_variable_list;
9537 CONSP (vlist);
9538 vlist = XCDR (vlist))
9539 {
9540 Lisp_Object var = XCAR (vlist);
9541 Lisp_Object val;
9542
9543 if (!SYMBOLP (var))
9544 continue;
9545
9546 val = find_symbol_value (var);
9547
9548 if (MARKERP (val)
9549 && current_buffer == XMARKER (val)->buffer
9550 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9551 {
9552 val = overlay_arrow_string_or_property (var, pbitmap);
9553 if (FRAME_WINDOW_P (f))
9554 return Qt;
9555 else if (STRINGP (val))
9556 return val;
9557 break;
9558 }
9559 }
9560
9561 *pbitmap = 0;
9562 return Qnil;
9563 }
9564
9565 /* Return 1 if point moved out of or into a composition. Otherwise
9566 return 0. PREV_BUF and PREV_PT are the last point buffer and
9567 position. BUF and PT are the current point buffer and position. */
9568
9569 int
9570 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9571 struct buffer *prev_buf, *buf;
9572 int prev_pt, pt;
9573 {
9574 int start, end;
9575 Lisp_Object prop;
9576 Lisp_Object buffer;
9577
9578 XSETBUFFER (buffer, buf);
9579 /* Check a composition at the last point if point moved within the
9580 same buffer. */
9581 if (prev_buf == buf)
9582 {
9583 if (prev_pt == pt)
9584 /* Point didn't move. */
9585 return 0;
9586
9587 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9588 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9589 && COMPOSITION_VALID_P (start, end, prop)
9590 && start < prev_pt && end > prev_pt)
9591 /* The last point was within the composition. Return 1 iff
9592 point moved out of the composition. */
9593 return (pt <= start || pt >= end);
9594 }
9595
9596 /* Check a composition at the current point. */
9597 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9598 && find_composition (pt, -1, &start, &end, &prop, buffer)
9599 && COMPOSITION_VALID_P (start, end, prop)
9600 && start < pt && end > pt);
9601 }
9602
9603
9604 /* Reconsider the setting of B->clip_changed which is displayed
9605 in window W. */
9606
9607 static INLINE void
9608 reconsider_clip_changes (w, b)
9609 struct window *w;
9610 struct buffer *b;
9611 {
9612 if (b->clip_changed
9613 && !NILP (w->window_end_valid)
9614 && w->current_matrix->buffer == b
9615 && w->current_matrix->zv == BUF_ZV (b)
9616 && w->current_matrix->begv == BUF_BEGV (b))
9617 b->clip_changed = 0;
9618
9619 /* If display wasn't paused, and W is not a tool bar window, see if
9620 point has been moved into or out of a composition. In that case,
9621 we set b->clip_changed to 1 to force updating the screen. If
9622 b->clip_changed has already been set to 1, we can skip this
9623 check. */
9624 if (!b->clip_changed
9625 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9626 {
9627 int pt;
9628
9629 if (w == XWINDOW (selected_window))
9630 pt = BUF_PT (current_buffer);
9631 else
9632 pt = marker_position (w->pointm);
9633
9634 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9635 || pt != XINT (w->last_point))
9636 && check_point_in_composition (w->current_matrix->buffer,
9637 XINT (w->last_point),
9638 XBUFFER (w->buffer), pt))
9639 b->clip_changed = 1;
9640 }
9641 }
9642 \f
9643
9644 /* Select FRAME to forward the values of frame-local variables into C
9645 variables so that the redisplay routines can access those values
9646 directly. */
9647
9648 static void
9649 select_frame_for_redisplay (frame)
9650 Lisp_Object frame;
9651 {
9652 Lisp_Object tail, sym, val;
9653 Lisp_Object old = selected_frame;
9654
9655 selected_frame = frame;
9656
9657 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9658 if (CONSP (XCAR (tail))
9659 && (sym = XCAR (XCAR (tail)),
9660 SYMBOLP (sym))
9661 && (sym = indirect_variable (sym),
9662 val = SYMBOL_VALUE (sym),
9663 (BUFFER_LOCAL_VALUEP (val)
9664 || SOME_BUFFER_LOCAL_VALUEP (val)))
9665 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9666 Fsymbol_value (sym);
9667
9668 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9669 if (CONSP (XCAR (tail))
9670 && (sym = XCAR (XCAR (tail)),
9671 SYMBOLP (sym))
9672 && (sym = indirect_variable (sym),
9673 val = SYMBOL_VALUE (sym),
9674 (BUFFER_LOCAL_VALUEP (val)
9675 || SOME_BUFFER_LOCAL_VALUEP (val)))
9676 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9677 Fsymbol_value (sym);
9678 }
9679
9680
9681 #define STOP_POLLING \
9682 do { if (! polling_stopped_here) stop_polling (); \
9683 polling_stopped_here = 1; } while (0)
9684
9685 #define RESUME_POLLING \
9686 do { if (polling_stopped_here) start_polling (); \
9687 polling_stopped_here = 0; } while (0)
9688
9689
9690 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9691 response to any user action; therefore, we should preserve the echo
9692 area. (Actually, our caller does that job.) Perhaps in the future
9693 avoid recentering windows if it is not necessary; currently that
9694 causes some problems. */
9695
9696 static void
9697 redisplay_internal (preserve_echo_area)
9698 int preserve_echo_area;
9699 {
9700 struct window *w = XWINDOW (selected_window);
9701 struct frame *f = XFRAME (w->frame);
9702 int pause;
9703 int must_finish = 0;
9704 struct text_pos tlbufpos, tlendpos;
9705 int number_of_visible_frames;
9706 int count;
9707 struct frame *sf = SELECTED_FRAME ();
9708 int polling_stopped_here = 0;
9709
9710 /* Non-zero means redisplay has to consider all windows on all
9711 frames. Zero means, only selected_window is considered. */
9712 int consider_all_windows_p;
9713
9714 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9715
9716 /* No redisplay if running in batch mode or frame is not yet fully
9717 initialized, or redisplay is explicitly turned off by setting
9718 Vinhibit_redisplay. */
9719 if (noninteractive
9720 || !NILP (Vinhibit_redisplay)
9721 || !f->glyphs_initialized_p)
9722 return;
9723
9724 /* The flag redisplay_performed_directly_p is set by
9725 direct_output_for_insert when it already did the whole screen
9726 update necessary. */
9727 if (redisplay_performed_directly_p)
9728 {
9729 redisplay_performed_directly_p = 0;
9730 if (!hscroll_windows (selected_window))
9731 return;
9732 }
9733
9734 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9735 if (popup_activated ())
9736 return;
9737 #endif
9738
9739 /* I don't think this happens but let's be paranoid. */
9740 if (redisplaying_p)
9741 return;
9742
9743 /* Record a function that resets redisplaying_p to its old value
9744 when we leave this function. */
9745 count = SPECPDL_INDEX ();
9746 record_unwind_protect (unwind_redisplay,
9747 Fcons (make_number (redisplaying_p), selected_frame));
9748 ++redisplaying_p;
9749 specbind (Qinhibit_free_realized_faces, Qnil);
9750
9751 retry:
9752 pause = 0;
9753 reconsider_clip_changes (w, current_buffer);
9754
9755 /* If new fonts have been loaded that make a glyph matrix adjustment
9756 necessary, do it. */
9757 if (fonts_changed_p)
9758 {
9759 adjust_glyphs (NULL);
9760 ++windows_or_buffers_changed;
9761 fonts_changed_p = 0;
9762 }
9763
9764 /* If face_change_count is non-zero, init_iterator will free all
9765 realized faces, which includes the faces referenced from current
9766 matrices. So, we can't reuse current matrices in this case. */
9767 if (face_change_count)
9768 ++windows_or_buffers_changed;
9769
9770 if (! FRAME_WINDOW_P (sf)
9771 && previous_terminal_frame != sf)
9772 {
9773 /* Since frames on an ASCII terminal share the same display
9774 area, displaying a different frame means redisplay the whole
9775 thing. */
9776 windows_or_buffers_changed++;
9777 SET_FRAME_GARBAGED (sf);
9778 XSETFRAME (Vterminal_frame, sf);
9779 }
9780 previous_terminal_frame = sf;
9781
9782 /* Set the visible flags for all frames. Do this before checking
9783 for resized or garbaged frames; they want to know if their frames
9784 are visible. See the comment in frame.h for
9785 FRAME_SAMPLE_VISIBILITY. */
9786 {
9787 Lisp_Object tail, frame;
9788
9789 number_of_visible_frames = 0;
9790
9791 FOR_EACH_FRAME (tail, frame)
9792 {
9793 struct frame *f = XFRAME (frame);
9794
9795 FRAME_SAMPLE_VISIBILITY (f);
9796 if (FRAME_VISIBLE_P (f))
9797 ++number_of_visible_frames;
9798 clear_desired_matrices (f);
9799 }
9800 }
9801
9802 /* Notice any pending interrupt request to change frame size. */
9803 do_pending_window_change (1);
9804
9805 /* Clear frames marked as garbaged. */
9806 if (frame_garbaged)
9807 clear_garbaged_frames ();
9808
9809 /* Build menubar and tool-bar items. */
9810 prepare_menu_bars ();
9811
9812 if (windows_or_buffers_changed)
9813 update_mode_lines++;
9814
9815 /* Detect case that we need to write or remove a star in the mode line. */
9816 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9817 {
9818 w->update_mode_line = Qt;
9819 if (buffer_shared > 1)
9820 update_mode_lines++;
9821 }
9822
9823 /* If %c is in the mode line, update it if needed. */
9824 if (!NILP (w->column_number_displayed)
9825 /* This alternative quickly identifies a common case
9826 where no change is needed. */
9827 && !(PT == XFASTINT (w->last_point)
9828 && XFASTINT (w->last_modified) >= MODIFF
9829 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9830 && (XFASTINT (w->column_number_displayed)
9831 != (int) current_column ())) /* iftc */
9832 w->update_mode_line = Qt;
9833
9834 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9835
9836 /* The variable buffer_shared is set in redisplay_window and
9837 indicates that we redisplay a buffer in different windows. See
9838 there. */
9839 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9840 || cursor_type_changed);
9841
9842 /* If specs for an arrow have changed, do thorough redisplay
9843 to ensure we remove any arrow that should no longer exist. */
9844 if (overlay_arrows_changed_p ())
9845 consider_all_windows_p = windows_or_buffers_changed = 1;
9846
9847 /* Normally the message* functions will have already displayed and
9848 updated the echo area, but the frame may have been trashed, or
9849 the update may have been preempted, so display the echo area
9850 again here. Checking message_cleared_p captures the case that
9851 the echo area should be cleared. */
9852 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9853 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9854 || (message_cleared_p
9855 && minibuf_level == 0
9856 /* If the mini-window is currently selected, this means the
9857 echo-area doesn't show through. */
9858 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9859 {
9860 int window_height_changed_p = echo_area_display (0);
9861 must_finish = 1;
9862
9863 /* If we don't display the current message, don't clear the
9864 message_cleared_p flag, because, if we did, we wouldn't clear
9865 the echo area in the next redisplay which doesn't preserve
9866 the echo area. */
9867 if (!display_last_displayed_message_p)
9868 message_cleared_p = 0;
9869
9870 if (fonts_changed_p)
9871 goto retry;
9872 else if (window_height_changed_p)
9873 {
9874 consider_all_windows_p = 1;
9875 ++update_mode_lines;
9876 ++windows_or_buffers_changed;
9877
9878 /* If window configuration was changed, frames may have been
9879 marked garbaged. Clear them or we will experience
9880 surprises wrt scrolling. */
9881 if (frame_garbaged)
9882 clear_garbaged_frames ();
9883 }
9884 }
9885 else if (EQ (selected_window, minibuf_window)
9886 && (current_buffer->clip_changed
9887 || XFASTINT (w->last_modified) < MODIFF
9888 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9889 && resize_mini_window (w, 0))
9890 {
9891 /* Resized active mini-window to fit the size of what it is
9892 showing if its contents might have changed. */
9893 must_finish = 1;
9894 consider_all_windows_p = 1;
9895 ++windows_or_buffers_changed;
9896 ++update_mode_lines;
9897
9898 /* If window configuration was changed, frames may have been
9899 marked garbaged. Clear them or we will experience
9900 surprises wrt scrolling. */
9901 if (frame_garbaged)
9902 clear_garbaged_frames ();
9903 }
9904
9905
9906 /* If showing the region, and mark has changed, we must redisplay
9907 the whole window. The assignment to this_line_start_pos prevents
9908 the optimization directly below this if-statement. */
9909 if (((!NILP (Vtransient_mark_mode)
9910 && !NILP (XBUFFER (w->buffer)->mark_active))
9911 != !NILP (w->region_showing))
9912 || (!NILP (w->region_showing)
9913 && !EQ (w->region_showing,
9914 Fmarker_position (XBUFFER (w->buffer)->mark))))
9915 CHARPOS (this_line_start_pos) = 0;
9916
9917 /* Optimize the case that only the line containing the cursor in the
9918 selected window has changed. Variables starting with this_ are
9919 set in display_line and record information about the line
9920 containing the cursor. */
9921 tlbufpos = this_line_start_pos;
9922 tlendpos = this_line_end_pos;
9923 if (!consider_all_windows_p
9924 && CHARPOS (tlbufpos) > 0
9925 && NILP (w->update_mode_line)
9926 && !current_buffer->clip_changed
9927 && !current_buffer->prevent_redisplay_optimizations_p
9928 && FRAME_VISIBLE_P (XFRAME (w->frame))
9929 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9930 /* Make sure recorded data applies to current buffer, etc. */
9931 && this_line_buffer == current_buffer
9932 && current_buffer == XBUFFER (w->buffer)
9933 && NILP (w->force_start)
9934 && NILP (w->optional_new_start)
9935 /* Point must be on the line that we have info recorded about. */
9936 && PT >= CHARPOS (tlbufpos)
9937 && PT <= Z - CHARPOS (tlendpos)
9938 /* All text outside that line, including its final newline,
9939 must be unchanged */
9940 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9941 CHARPOS (tlendpos)))
9942 {
9943 if (CHARPOS (tlbufpos) > BEGV
9944 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9945 && (CHARPOS (tlbufpos) == ZV
9946 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9947 /* Former continuation line has disappeared by becoming empty */
9948 goto cancel;
9949 else if (XFASTINT (w->last_modified) < MODIFF
9950 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9951 || MINI_WINDOW_P (w))
9952 {
9953 /* We have to handle the case of continuation around a
9954 wide-column character (See the comment in indent.c around
9955 line 885).
9956
9957 For instance, in the following case:
9958
9959 -------- Insert --------
9960 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9961 J_I_ ==> J_I_ `^^' are cursors.
9962 ^^ ^^
9963 -------- --------
9964
9965 As we have to redraw the line above, we should goto cancel. */
9966
9967 struct it it;
9968 int line_height_before = this_line_pixel_height;
9969
9970 /* Note that start_display will handle the case that the
9971 line starting at tlbufpos is a continuation lines. */
9972 start_display (&it, w, tlbufpos);
9973
9974 /* Implementation note: It this still necessary? */
9975 if (it.current_x != this_line_start_x)
9976 goto cancel;
9977
9978 TRACE ((stderr, "trying display optimization 1\n"));
9979 w->cursor.vpos = -1;
9980 overlay_arrow_seen = 0;
9981 it.vpos = this_line_vpos;
9982 it.current_y = this_line_y;
9983 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9984 display_line (&it);
9985
9986 /* If line contains point, is not continued,
9987 and ends at same distance from eob as before, we win */
9988 if (w->cursor.vpos >= 0
9989 /* Line is not continued, otherwise this_line_start_pos
9990 would have been set to 0 in display_line. */
9991 && CHARPOS (this_line_start_pos)
9992 /* Line ends as before. */
9993 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9994 /* Line has same height as before. Otherwise other lines
9995 would have to be shifted up or down. */
9996 && this_line_pixel_height == line_height_before)
9997 {
9998 /* If this is not the window's last line, we must adjust
9999 the charstarts of the lines below. */
10000 if (it.current_y < it.last_visible_y)
10001 {
10002 struct glyph_row *row
10003 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10004 int delta, delta_bytes;
10005
10006 if (Z - CHARPOS (tlendpos) == ZV)
10007 {
10008 /* This line ends at end of (accessible part of)
10009 buffer. There is no newline to count. */
10010 delta = (Z
10011 - CHARPOS (tlendpos)
10012 - MATRIX_ROW_START_CHARPOS (row));
10013 delta_bytes = (Z_BYTE
10014 - BYTEPOS (tlendpos)
10015 - MATRIX_ROW_START_BYTEPOS (row));
10016 }
10017 else
10018 {
10019 /* This line ends in a newline. Must take
10020 account of the newline and the rest of the
10021 text that follows. */
10022 delta = (Z
10023 - CHARPOS (tlendpos)
10024 - MATRIX_ROW_START_CHARPOS (row));
10025 delta_bytes = (Z_BYTE
10026 - BYTEPOS (tlendpos)
10027 - MATRIX_ROW_START_BYTEPOS (row));
10028 }
10029
10030 increment_matrix_positions (w->current_matrix,
10031 this_line_vpos + 1,
10032 w->current_matrix->nrows,
10033 delta, delta_bytes);
10034 }
10035
10036 /* If this row displays text now but previously didn't,
10037 or vice versa, w->window_end_vpos may have to be
10038 adjusted. */
10039 if ((it.glyph_row - 1)->displays_text_p)
10040 {
10041 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10042 XSETINT (w->window_end_vpos, this_line_vpos);
10043 }
10044 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10045 && this_line_vpos > 0)
10046 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10047 w->window_end_valid = Qnil;
10048
10049 /* Update hint: No need to try to scroll in update_window. */
10050 w->desired_matrix->no_scrolling_p = 1;
10051
10052 #if GLYPH_DEBUG
10053 *w->desired_matrix->method = 0;
10054 debug_method_add (w, "optimization 1");
10055 #endif
10056 #ifdef HAVE_WINDOW_SYSTEM
10057 update_window_fringes (w, 0);
10058 #endif
10059 goto update;
10060 }
10061 else
10062 goto cancel;
10063 }
10064 else if (/* Cursor position hasn't changed. */
10065 PT == XFASTINT (w->last_point)
10066 /* Make sure the cursor was last displayed
10067 in this window. Otherwise we have to reposition it. */
10068 && 0 <= w->cursor.vpos
10069 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10070 {
10071 if (!must_finish)
10072 {
10073 do_pending_window_change (1);
10074
10075 /* We used to always goto end_of_redisplay here, but this
10076 isn't enough if we have a blinking cursor. */
10077 if (w->cursor_off_p == w->last_cursor_off_p)
10078 goto end_of_redisplay;
10079 }
10080 goto update;
10081 }
10082 /* If highlighting the region, or if the cursor is in the echo area,
10083 then we can't just move the cursor. */
10084 else if (! (!NILP (Vtransient_mark_mode)
10085 && !NILP (current_buffer->mark_active))
10086 && (EQ (selected_window, current_buffer->last_selected_window)
10087 || highlight_nonselected_windows)
10088 && NILP (w->region_showing)
10089 && NILP (Vshow_trailing_whitespace)
10090 && !cursor_in_echo_area)
10091 {
10092 struct it it;
10093 struct glyph_row *row;
10094
10095 /* Skip from tlbufpos to PT and see where it is. Note that
10096 PT may be in invisible text. If so, we will end at the
10097 next visible position. */
10098 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10099 NULL, DEFAULT_FACE_ID);
10100 it.current_x = this_line_start_x;
10101 it.current_y = this_line_y;
10102 it.vpos = this_line_vpos;
10103
10104 /* The call to move_it_to stops in front of PT, but
10105 moves over before-strings. */
10106 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10107
10108 if (it.vpos == this_line_vpos
10109 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10110 row->enabled_p))
10111 {
10112 xassert (this_line_vpos == it.vpos);
10113 xassert (this_line_y == it.current_y);
10114 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10115 #if GLYPH_DEBUG
10116 *w->desired_matrix->method = 0;
10117 debug_method_add (w, "optimization 3");
10118 #endif
10119 goto update;
10120 }
10121 else
10122 goto cancel;
10123 }
10124
10125 cancel:
10126 /* Text changed drastically or point moved off of line. */
10127 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10128 }
10129
10130 CHARPOS (this_line_start_pos) = 0;
10131 consider_all_windows_p |= buffer_shared > 1;
10132 ++clear_face_cache_count;
10133
10134
10135 /* Build desired matrices, and update the display. If
10136 consider_all_windows_p is non-zero, do it for all windows on all
10137 frames. Otherwise do it for selected_window, only. */
10138
10139 if (consider_all_windows_p)
10140 {
10141 Lisp_Object tail, frame;
10142 int i, n = 0, size = 50;
10143 struct frame **updated
10144 = (struct frame **) alloca (size * sizeof *updated);
10145
10146 /* Clear the face cache eventually. */
10147 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10148 {
10149 clear_face_cache (0);
10150 clear_face_cache_count = 0;
10151 }
10152
10153 /* Recompute # windows showing selected buffer. This will be
10154 incremented each time such a window is displayed. */
10155 buffer_shared = 0;
10156
10157 FOR_EACH_FRAME (tail, frame)
10158 {
10159 struct frame *f = XFRAME (frame);
10160
10161 if (FRAME_WINDOW_P (f) || f == sf)
10162 {
10163 if (! EQ (frame, selected_frame))
10164 /* Select the frame, for the sake of frame-local
10165 variables. */
10166 select_frame_for_redisplay (frame);
10167
10168 #ifdef HAVE_WINDOW_SYSTEM
10169 if (clear_face_cache_count % 50 == 0
10170 && FRAME_WINDOW_P (f))
10171 clear_image_cache (f, 0);
10172 #endif /* HAVE_WINDOW_SYSTEM */
10173
10174 /* Mark all the scroll bars to be removed; we'll redeem
10175 the ones we want when we redisplay their windows. */
10176 if (condemn_scroll_bars_hook)
10177 condemn_scroll_bars_hook (f);
10178
10179 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10180 redisplay_windows (FRAME_ROOT_WINDOW (f));
10181
10182 /* Any scroll bars which redisplay_windows should have
10183 nuked should now go away. */
10184 if (judge_scroll_bars_hook)
10185 judge_scroll_bars_hook (f);
10186
10187 /* If fonts changed, display again. */
10188 /* ??? rms: I suspect it is a mistake to jump all the way
10189 back to retry here. It should just retry this frame. */
10190 if (fonts_changed_p)
10191 goto retry;
10192
10193 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10194 {
10195 /* See if we have to hscroll. */
10196 if (hscroll_windows (f->root_window))
10197 goto retry;
10198
10199 /* Prevent various kinds of signals during display
10200 update. stdio is not robust about handling
10201 signals, which can cause an apparent I/O
10202 error. */
10203 if (interrupt_input)
10204 unrequest_sigio ();
10205 STOP_POLLING;
10206
10207 /* Update the display. */
10208 set_window_update_flags (XWINDOW (f->root_window), 1);
10209 pause |= update_frame (f, 0, 0);
10210 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10211 if (pause)
10212 break;
10213 #endif
10214
10215 if (n == size)
10216 {
10217 int nbytes = size * sizeof *updated;
10218 struct frame **p = (struct frame **) alloca (2 * nbytes);
10219 bcopy (updated, p, nbytes);
10220 size *= 2;
10221 }
10222
10223 updated[n++] = f;
10224 }
10225 }
10226 }
10227
10228 if (!pause)
10229 {
10230 /* Do the mark_window_display_accurate after all windows have
10231 been redisplayed because this call resets flags in buffers
10232 which are needed for proper redisplay. */
10233 for (i = 0; i < n; ++i)
10234 {
10235 struct frame *f = updated[i];
10236 mark_window_display_accurate (f->root_window, 1);
10237 if (frame_up_to_date_hook)
10238 frame_up_to_date_hook (f);
10239 }
10240 }
10241 }
10242 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10243 {
10244 Lisp_Object mini_window;
10245 struct frame *mini_frame;
10246
10247 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10248 /* Use list_of_error, not Qerror, so that
10249 we catch only errors and don't run the debugger. */
10250 internal_condition_case_1 (redisplay_window_1, selected_window,
10251 list_of_error,
10252 redisplay_window_error);
10253
10254 /* Compare desired and current matrices, perform output. */
10255
10256 update:
10257 /* If fonts changed, display again. */
10258 if (fonts_changed_p)
10259 goto retry;
10260
10261 /* Prevent various kinds of signals during display update.
10262 stdio is not robust about handling signals,
10263 which can cause an apparent I/O error. */
10264 if (interrupt_input)
10265 unrequest_sigio ();
10266 STOP_POLLING;
10267
10268 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10269 {
10270 if (hscroll_windows (selected_window))
10271 goto retry;
10272
10273 XWINDOW (selected_window)->must_be_updated_p = 1;
10274 pause = update_frame (sf, 0, 0);
10275 }
10276
10277 /* We may have called echo_area_display at the top of this
10278 function. If the echo area is on another frame, that may
10279 have put text on a frame other than the selected one, so the
10280 above call to update_frame would not have caught it. Catch
10281 it here. */
10282 mini_window = FRAME_MINIBUF_WINDOW (sf);
10283 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10284
10285 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10286 {
10287 XWINDOW (mini_window)->must_be_updated_p = 1;
10288 pause |= update_frame (mini_frame, 0, 0);
10289 if (!pause && hscroll_windows (mini_window))
10290 goto retry;
10291 }
10292 }
10293
10294 /* If display was paused because of pending input, make sure we do a
10295 thorough update the next time. */
10296 if (pause)
10297 {
10298 /* Prevent the optimization at the beginning of
10299 redisplay_internal that tries a single-line update of the
10300 line containing the cursor in the selected window. */
10301 CHARPOS (this_line_start_pos) = 0;
10302
10303 /* Let the overlay arrow be updated the next time. */
10304 update_overlay_arrows (0);
10305
10306 /* If we pause after scrolling, some rows in the current
10307 matrices of some windows are not valid. */
10308 if (!WINDOW_FULL_WIDTH_P (w)
10309 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10310 update_mode_lines = 1;
10311 }
10312 else
10313 {
10314 if (!consider_all_windows_p)
10315 {
10316 /* This has already been done above if
10317 consider_all_windows_p is set. */
10318 mark_window_display_accurate_1 (w, 1);
10319
10320 /* Say overlay arrows are up to date. */
10321 update_overlay_arrows (1);
10322
10323 if (frame_up_to_date_hook != 0)
10324 frame_up_to_date_hook (sf);
10325 }
10326
10327 update_mode_lines = 0;
10328 windows_or_buffers_changed = 0;
10329 cursor_type_changed = 0;
10330 }
10331
10332 /* Start SIGIO interrupts coming again. Having them off during the
10333 code above makes it less likely one will discard output, but not
10334 impossible, since there might be stuff in the system buffer here.
10335 But it is much hairier to try to do anything about that. */
10336 if (interrupt_input)
10337 request_sigio ();
10338 RESUME_POLLING;
10339
10340 /* If a frame has become visible which was not before, redisplay
10341 again, so that we display it. Expose events for such a frame
10342 (which it gets when becoming visible) don't call the parts of
10343 redisplay constructing glyphs, so simply exposing a frame won't
10344 display anything in this case. So, we have to display these
10345 frames here explicitly. */
10346 if (!pause)
10347 {
10348 Lisp_Object tail, frame;
10349 int new_count = 0;
10350
10351 FOR_EACH_FRAME (tail, frame)
10352 {
10353 int this_is_visible = 0;
10354
10355 if (XFRAME (frame)->visible)
10356 this_is_visible = 1;
10357 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10358 if (XFRAME (frame)->visible)
10359 this_is_visible = 1;
10360
10361 if (this_is_visible)
10362 new_count++;
10363 }
10364
10365 if (new_count != number_of_visible_frames)
10366 windows_or_buffers_changed++;
10367 }
10368
10369 /* Change frame size now if a change is pending. */
10370 do_pending_window_change (1);
10371
10372 /* If we just did a pending size change, or have additional
10373 visible frames, redisplay again. */
10374 if (windows_or_buffers_changed && !pause)
10375 goto retry;
10376
10377 end_of_redisplay:
10378 unbind_to (count, Qnil);
10379 RESUME_POLLING;
10380 }
10381
10382
10383 /* Redisplay, but leave alone any recent echo area message unless
10384 another message has been requested in its place.
10385
10386 This is useful in situations where you need to redisplay but no
10387 user action has occurred, making it inappropriate for the message
10388 area to be cleared. See tracking_off and
10389 wait_reading_process_output for examples of these situations.
10390
10391 FROM_WHERE is an integer saying from where this function was
10392 called. This is useful for debugging. */
10393
10394 void
10395 redisplay_preserve_echo_area (from_where)
10396 int from_where;
10397 {
10398 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10399
10400 if (!NILP (echo_area_buffer[1]))
10401 {
10402 /* We have a previously displayed message, but no current
10403 message. Redisplay the previous message. */
10404 display_last_displayed_message_p = 1;
10405 redisplay_internal (1);
10406 display_last_displayed_message_p = 0;
10407 }
10408 else
10409 redisplay_internal (1);
10410
10411 if (rif != NULL && rif->flush_display_optional)
10412 rif->flush_display_optional (NULL);
10413 }
10414
10415
10416 /* Function registered with record_unwind_protect in
10417 redisplay_internal. Reset redisplaying_p to the value it had
10418 before redisplay_internal was called, and clear
10419 prevent_freeing_realized_faces_p. It also selects the previously
10420 selected frame. */
10421
10422 static Lisp_Object
10423 unwind_redisplay (val)
10424 Lisp_Object val;
10425 {
10426 Lisp_Object old_redisplaying_p, old_frame;
10427
10428 old_redisplaying_p = XCAR (val);
10429 redisplaying_p = XFASTINT (old_redisplaying_p);
10430 old_frame = XCDR (val);
10431 if (! EQ (old_frame, selected_frame))
10432 select_frame_for_redisplay (old_frame);
10433 return Qnil;
10434 }
10435
10436
10437 /* Mark the display of window W as accurate or inaccurate. If
10438 ACCURATE_P is non-zero mark display of W as accurate. If
10439 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10440 redisplay_internal is called. */
10441
10442 static void
10443 mark_window_display_accurate_1 (w, accurate_p)
10444 struct window *w;
10445 int accurate_p;
10446 {
10447 if (BUFFERP (w->buffer))
10448 {
10449 struct buffer *b = XBUFFER (w->buffer);
10450
10451 w->last_modified
10452 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10453 w->last_overlay_modified
10454 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10455 w->last_had_star
10456 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10457
10458 if (accurate_p)
10459 {
10460 b->clip_changed = 0;
10461 b->prevent_redisplay_optimizations_p = 0;
10462
10463 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10464 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10465 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10466 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10467
10468 w->current_matrix->buffer = b;
10469 w->current_matrix->begv = BUF_BEGV (b);
10470 w->current_matrix->zv = BUF_ZV (b);
10471
10472 w->last_cursor = w->cursor;
10473 w->last_cursor_off_p = w->cursor_off_p;
10474
10475 if (w == XWINDOW (selected_window))
10476 w->last_point = make_number (BUF_PT (b));
10477 else
10478 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10479 }
10480 }
10481
10482 if (accurate_p)
10483 {
10484 w->window_end_valid = w->buffer;
10485 #if 0 /* This is incorrect with variable-height lines. */
10486 xassert (XINT (w->window_end_vpos)
10487 < (WINDOW_TOTAL_LINES (w)
10488 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10489 #endif
10490 w->update_mode_line = Qnil;
10491 }
10492 }
10493
10494
10495 /* Mark the display of windows in the window tree rooted at WINDOW as
10496 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10497 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10498 be redisplayed the next time redisplay_internal is called. */
10499
10500 void
10501 mark_window_display_accurate (window, accurate_p)
10502 Lisp_Object window;
10503 int accurate_p;
10504 {
10505 struct window *w;
10506
10507 for (; !NILP (window); window = w->next)
10508 {
10509 w = XWINDOW (window);
10510 mark_window_display_accurate_1 (w, accurate_p);
10511
10512 if (!NILP (w->vchild))
10513 mark_window_display_accurate (w->vchild, accurate_p);
10514 if (!NILP (w->hchild))
10515 mark_window_display_accurate (w->hchild, accurate_p);
10516 }
10517
10518 if (accurate_p)
10519 {
10520 update_overlay_arrows (1);
10521 }
10522 else
10523 {
10524 /* Force a thorough redisplay the next time by setting
10525 last_arrow_position and last_arrow_string to t, which is
10526 unequal to any useful value of Voverlay_arrow_... */
10527 update_overlay_arrows (-1);
10528 }
10529 }
10530
10531
10532 /* Return value in display table DP (Lisp_Char_Table *) for character
10533 C. Since a display table doesn't have any parent, we don't have to
10534 follow parent. Do not call this function directly but use the
10535 macro DISP_CHAR_VECTOR. */
10536
10537 Lisp_Object
10538 disp_char_vector (dp, c)
10539 struct Lisp_Char_Table *dp;
10540 int c;
10541 {
10542 int code[4], i;
10543 Lisp_Object val;
10544
10545 if (SINGLE_BYTE_CHAR_P (c))
10546 return (dp->contents[c]);
10547
10548 SPLIT_CHAR (c, code[0], code[1], code[2]);
10549 if (code[1] < 32)
10550 code[1] = -1;
10551 else if (code[2] < 32)
10552 code[2] = -1;
10553
10554 /* Here, the possible range of code[0] (== charset ID) is
10555 128..max_charset. Since the top level char table contains data
10556 for multibyte characters after 256th element, we must increment
10557 code[0] by 128 to get a correct index. */
10558 code[0] += 128;
10559 code[3] = -1; /* anchor */
10560
10561 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10562 {
10563 val = dp->contents[code[i]];
10564 if (!SUB_CHAR_TABLE_P (val))
10565 return (NILP (val) ? dp->defalt : val);
10566 }
10567
10568 /* Here, val is a sub char table. We return the default value of
10569 it. */
10570 return (dp->defalt);
10571 }
10572
10573
10574 \f
10575 /***********************************************************************
10576 Window Redisplay
10577 ***********************************************************************/
10578
10579 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10580
10581 static void
10582 redisplay_windows (window)
10583 Lisp_Object window;
10584 {
10585 while (!NILP (window))
10586 {
10587 struct window *w = XWINDOW (window);
10588
10589 if (!NILP (w->hchild))
10590 redisplay_windows (w->hchild);
10591 else if (!NILP (w->vchild))
10592 redisplay_windows (w->vchild);
10593 else
10594 {
10595 displayed_buffer = XBUFFER (w->buffer);
10596 /* Use list_of_error, not Qerror, so that
10597 we catch only errors and don't run the debugger. */
10598 internal_condition_case_1 (redisplay_window_0, window,
10599 list_of_error,
10600 redisplay_window_error);
10601 }
10602
10603 window = w->next;
10604 }
10605 }
10606
10607 static Lisp_Object
10608 redisplay_window_error ()
10609 {
10610 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10611 return Qnil;
10612 }
10613
10614 static Lisp_Object
10615 redisplay_window_0 (window)
10616 Lisp_Object window;
10617 {
10618 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10619 redisplay_window (window, 0);
10620 return Qnil;
10621 }
10622
10623 static Lisp_Object
10624 redisplay_window_1 (window)
10625 Lisp_Object window;
10626 {
10627 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10628 redisplay_window (window, 1);
10629 return Qnil;
10630 }
10631 \f
10632
10633 /* Increment GLYPH until it reaches END or CONDITION fails while
10634 adding (GLYPH)->pixel_width to X. */
10635
10636 #define SKIP_GLYPHS(glyph, end, x, condition) \
10637 do \
10638 { \
10639 (x) += (glyph)->pixel_width; \
10640 ++(glyph); \
10641 } \
10642 while ((glyph) < (end) && (condition))
10643
10644
10645 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10646 DELTA is the number of bytes by which positions recorded in ROW
10647 differ from current buffer positions. */
10648
10649 void
10650 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10651 struct window *w;
10652 struct glyph_row *row;
10653 struct glyph_matrix *matrix;
10654 int delta, delta_bytes, dy, dvpos;
10655 {
10656 struct glyph *glyph = row->glyphs[TEXT_AREA];
10657 struct glyph *end = glyph + row->used[TEXT_AREA];
10658 struct glyph *cursor = NULL;
10659 /* The first glyph that starts a sequence of glyphs from string. */
10660 struct glyph *string_start;
10661 /* The X coordinate of string_start. */
10662 int string_start_x;
10663 /* The last known character position. */
10664 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10665 /* The last known character position before string_start. */
10666 int string_before_pos;
10667 int x = row->x;
10668 int cursor_x = x;
10669 int cursor_from_overlay_pos = 0;
10670 int pt_old = PT - delta;
10671
10672 /* Skip over glyphs not having an object at the start of the row.
10673 These are special glyphs like truncation marks on terminal
10674 frames. */
10675 if (row->displays_text_p)
10676 while (glyph < end
10677 && INTEGERP (glyph->object)
10678 && glyph->charpos < 0)
10679 {
10680 x += glyph->pixel_width;
10681 ++glyph;
10682 }
10683
10684 string_start = NULL;
10685 while (glyph < end
10686 && !INTEGERP (glyph->object)
10687 && (!BUFFERP (glyph->object)
10688 || (last_pos = glyph->charpos) < pt_old))
10689 {
10690 if (! STRINGP (glyph->object))
10691 {
10692 string_start = NULL;
10693 x += glyph->pixel_width;
10694 ++glyph;
10695 if (cursor_from_overlay_pos
10696 && last_pos > cursor_from_overlay_pos)
10697 {
10698 cursor_from_overlay_pos = 0;
10699 cursor = 0;
10700 }
10701 }
10702 else
10703 {
10704 string_before_pos = last_pos;
10705 string_start = glyph;
10706 string_start_x = x;
10707 /* Skip all glyphs from string. */
10708 do
10709 {
10710 int pos;
10711 if ((cursor == NULL || glyph > cursor)
10712 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10713 Qcursor, (glyph)->object))
10714 && (pos = string_buffer_position (w, glyph->object,
10715 string_before_pos),
10716 (pos == 0 /* From overlay */
10717 || pos == pt_old)))
10718 {
10719 /* Estimate overlay buffer position from the buffer
10720 positions of the glyphs before and after the overlay.
10721 Add 1 to last_pos so that if point corresponds to the
10722 glyph right after the overlay, we still use a 'cursor'
10723 property found in that overlay. */
10724 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10725 cursor = glyph;
10726 cursor_x = x;
10727 }
10728 x += glyph->pixel_width;
10729 ++glyph;
10730 }
10731 while (glyph < end && STRINGP (glyph->object));
10732 }
10733 }
10734
10735 if (cursor != NULL)
10736 {
10737 glyph = cursor;
10738 x = cursor_x;
10739 }
10740 else if (string_start
10741 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10742 {
10743 /* We may have skipped over point because the previous glyphs
10744 are from string. As there's no easy way to know the
10745 character position of the current glyph, find the correct
10746 glyph on point by scanning from string_start again. */
10747 Lisp_Object limit;
10748 Lisp_Object string;
10749 int pos;
10750
10751 limit = make_number (pt_old + 1);
10752 end = glyph;
10753 glyph = string_start;
10754 x = string_start_x;
10755 string = glyph->object;
10756 pos = string_buffer_position (w, string, string_before_pos);
10757 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10758 because we always put cursor after overlay strings. */
10759 while (pos == 0 && glyph < end)
10760 {
10761 string = glyph->object;
10762 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10763 if (glyph < end)
10764 pos = string_buffer_position (w, glyph->object, string_before_pos);
10765 }
10766
10767 while (glyph < end)
10768 {
10769 pos = XINT (Fnext_single_char_property_change
10770 (make_number (pos), Qdisplay, Qnil, limit));
10771 if (pos > pt_old)
10772 break;
10773 /* Skip glyphs from the same string. */
10774 string = glyph->object;
10775 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10776 /* Skip glyphs from an overlay. */
10777 while (glyph < end
10778 && ! string_buffer_position (w, glyph->object, pos))
10779 {
10780 string = glyph->object;
10781 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10782 }
10783 }
10784 }
10785
10786 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10787 w->cursor.x = x;
10788 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10789 w->cursor.y = row->y + dy;
10790
10791 if (w == XWINDOW (selected_window))
10792 {
10793 if (!row->continued_p
10794 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10795 && row->x == 0)
10796 {
10797 this_line_buffer = XBUFFER (w->buffer);
10798
10799 CHARPOS (this_line_start_pos)
10800 = MATRIX_ROW_START_CHARPOS (row) + delta;
10801 BYTEPOS (this_line_start_pos)
10802 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10803
10804 CHARPOS (this_line_end_pos)
10805 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10806 BYTEPOS (this_line_end_pos)
10807 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10808
10809 this_line_y = w->cursor.y;
10810 this_line_pixel_height = row->height;
10811 this_line_vpos = w->cursor.vpos;
10812 this_line_start_x = row->x;
10813 }
10814 else
10815 CHARPOS (this_line_start_pos) = 0;
10816 }
10817 }
10818
10819
10820 /* Run window scroll functions, if any, for WINDOW with new window
10821 start STARTP. Sets the window start of WINDOW to that position.
10822
10823 We assume that the window's buffer is really current. */
10824
10825 static INLINE struct text_pos
10826 run_window_scroll_functions (window, startp)
10827 Lisp_Object window;
10828 struct text_pos startp;
10829 {
10830 struct window *w = XWINDOW (window);
10831 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10832
10833 if (current_buffer != XBUFFER (w->buffer))
10834 abort ();
10835
10836 if (!NILP (Vwindow_scroll_functions))
10837 {
10838 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10839 make_number (CHARPOS (startp)));
10840 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10841 /* In case the hook functions switch buffers. */
10842 if (current_buffer != XBUFFER (w->buffer))
10843 set_buffer_internal_1 (XBUFFER (w->buffer));
10844 }
10845
10846 return startp;
10847 }
10848
10849
10850 /* Make sure the line containing the cursor is fully visible.
10851 A value of 1 means there is nothing to be done.
10852 (Either the line is fully visible, or it cannot be made so,
10853 or we cannot tell.)
10854
10855 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10856 is higher than window.
10857
10858 A value of 0 means the caller should do scrolling
10859 as if point had gone off the screen. */
10860
10861 static int
10862 make_cursor_line_fully_visible (w, force_p)
10863 struct window *w;
10864 int force_p;
10865 {
10866 struct glyph_matrix *matrix;
10867 struct glyph_row *row;
10868 int window_height;
10869
10870 /* It's not always possible to find the cursor, e.g, when a window
10871 is full of overlay strings. Don't do anything in that case. */
10872 if (w->cursor.vpos < 0)
10873 return 1;
10874
10875 matrix = w->desired_matrix;
10876 row = MATRIX_ROW (matrix, w->cursor.vpos);
10877
10878 /* If the cursor row is not partially visible, there's nothing to do. */
10879 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10880 return 1;
10881
10882 /* If the row the cursor is in is taller than the window's height,
10883 it's not clear what to do, so do nothing. */
10884 window_height = window_box_height (w);
10885 if (row->height >= window_height)
10886 {
10887 if (!force_p || w->vscroll)
10888 return 1;
10889 }
10890 return 0;
10891
10892 #if 0
10893 /* This code used to try to scroll the window just enough to make
10894 the line visible. It returned 0 to say that the caller should
10895 allocate larger glyph matrices. */
10896
10897 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10898 {
10899 int dy = row->height - row->visible_height;
10900 w->vscroll = 0;
10901 w->cursor.y += dy;
10902 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10903 }
10904 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10905 {
10906 int dy = - (row->height - row->visible_height);
10907 w->vscroll = dy;
10908 w->cursor.y += dy;
10909 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10910 }
10911
10912 /* When we change the cursor y-position of the selected window,
10913 change this_line_y as well so that the display optimization for
10914 the cursor line of the selected window in redisplay_internal uses
10915 the correct y-position. */
10916 if (w == XWINDOW (selected_window))
10917 this_line_y = w->cursor.y;
10918
10919 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10920 redisplay with larger matrices. */
10921 if (matrix->nrows < required_matrix_height (w))
10922 {
10923 fonts_changed_p = 1;
10924 return 0;
10925 }
10926
10927 return 1;
10928 #endif /* 0 */
10929 }
10930
10931
10932 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10933 non-zero means only WINDOW is redisplayed in redisplay_internal.
10934 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10935 in redisplay_window to bring a partially visible line into view in
10936 the case that only the cursor has moved.
10937
10938 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10939 last screen line's vertical height extends past the end of the screen.
10940
10941 Value is
10942
10943 1 if scrolling succeeded
10944
10945 0 if scrolling didn't find point.
10946
10947 -1 if new fonts have been loaded so that we must interrupt
10948 redisplay, adjust glyph matrices, and try again. */
10949
10950 enum
10951 {
10952 SCROLLING_SUCCESS,
10953 SCROLLING_FAILED,
10954 SCROLLING_NEED_LARGER_MATRICES
10955 };
10956
10957 static int
10958 try_scrolling (window, just_this_one_p, scroll_conservatively,
10959 scroll_step, temp_scroll_step, last_line_misfit)
10960 Lisp_Object window;
10961 int just_this_one_p;
10962 EMACS_INT scroll_conservatively, scroll_step;
10963 int temp_scroll_step;
10964 int last_line_misfit;
10965 {
10966 struct window *w = XWINDOW (window);
10967 struct frame *f = XFRAME (w->frame);
10968 struct text_pos scroll_margin_pos;
10969 struct text_pos pos;
10970 struct text_pos startp;
10971 struct it it;
10972 Lisp_Object window_end;
10973 int this_scroll_margin;
10974 int dy = 0;
10975 int scroll_max;
10976 int rc;
10977 int amount_to_scroll = 0;
10978 Lisp_Object aggressive;
10979 int height;
10980 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10981
10982 #if GLYPH_DEBUG
10983 debug_method_add (w, "try_scrolling");
10984 #endif
10985
10986 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10987
10988 /* Compute scroll margin height in pixels. We scroll when point is
10989 within this distance from the top or bottom of the window. */
10990 if (scroll_margin > 0)
10991 {
10992 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10993 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10994 }
10995 else
10996 this_scroll_margin = 0;
10997
10998 /* Force scroll_conservatively to have a reasonable value so it doesn't
10999 cause an overflow while computing how much to scroll. */
11000 if (scroll_conservatively)
11001 scroll_conservatively = min (scroll_conservatively,
11002 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11003
11004 /* Compute how much we should try to scroll maximally to bring point
11005 into view. */
11006 if (scroll_step || scroll_conservatively || temp_scroll_step)
11007 scroll_max = max (scroll_step,
11008 max (scroll_conservatively, temp_scroll_step));
11009 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11010 || NUMBERP (current_buffer->scroll_up_aggressively))
11011 /* We're trying to scroll because of aggressive scrolling
11012 but no scroll_step is set. Choose an arbitrary one. Maybe
11013 there should be a variable for this. */
11014 scroll_max = 10;
11015 else
11016 scroll_max = 0;
11017 scroll_max *= FRAME_LINE_HEIGHT (f);
11018
11019 /* Decide whether we have to scroll down. Start at the window end
11020 and move this_scroll_margin up to find the position of the scroll
11021 margin. */
11022 window_end = Fwindow_end (window, Qt);
11023
11024 too_near_end:
11025
11026 CHARPOS (scroll_margin_pos) = XINT (window_end);
11027 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11028
11029 if (this_scroll_margin || extra_scroll_margin_lines)
11030 {
11031 start_display (&it, w, scroll_margin_pos);
11032 if (this_scroll_margin)
11033 move_it_vertically (&it, - this_scroll_margin);
11034 if (extra_scroll_margin_lines)
11035 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11036 scroll_margin_pos = it.current.pos;
11037 }
11038
11039 if (PT >= CHARPOS (scroll_margin_pos))
11040 {
11041 int y0;
11042
11043 /* Point is in the scroll margin at the bottom of the window, or
11044 below. Compute a new window start that makes point visible. */
11045
11046 /* Compute the distance from the scroll margin to PT.
11047 Give up if the distance is greater than scroll_max. */
11048 start_display (&it, w, scroll_margin_pos);
11049 y0 = it.current_y;
11050 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11051 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11052
11053 /* To make point visible, we have to move the window start
11054 down so that the line the cursor is in is visible, which
11055 means we have to add in the height of the cursor line. */
11056 dy = line_bottom_y (&it) - y0;
11057
11058 if (dy > scroll_max)
11059 return SCROLLING_FAILED;
11060
11061 /* Move the window start down. If scrolling conservatively,
11062 move it just enough down to make point visible. If
11063 scroll_step is set, move it down by scroll_step. */
11064 start_display (&it, w, startp);
11065
11066 if (scroll_conservatively)
11067 /* Set AMOUNT_TO_SCROLL to at least one line,
11068 and at most scroll_conservatively lines. */
11069 amount_to_scroll
11070 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11071 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11072 else if (scroll_step || temp_scroll_step)
11073 amount_to_scroll = scroll_max;
11074 else
11075 {
11076 aggressive = current_buffer->scroll_up_aggressively;
11077 height = WINDOW_BOX_TEXT_HEIGHT (w);
11078 if (NUMBERP (aggressive))
11079 {
11080 double float_amount = XFLOATINT (aggressive) * height;
11081 amount_to_scroll = float_amount;
11082 if (amount_to_scroll == 0 && float_amount > 0)
11083 amount_to_scroll = 1;
11084 }
11085 }
11086
11087 if (amount_to_scroll <= 0)
11088 return SCROLLING_FAILED;
11089
11090 /* If moving by amount_to_scroll leaves STARTP unchanged,
11091 move it down one screen line. */
11092
11093 move_it_vertically (&it, amount_to_scroll);
11094 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11095 move_it_by_lines (&it, 1, 1);
11096 startp = it.current.pos;
11097 }
11098 else
11099 {
11100 /* See if point is inside the scroll margin at the top of the
11101 window. */
11102 scroll_margin_pos = startp;
11103 if (this_scroll_margin)
11104 {
11105 start_display (&it, w, startp);
11106 move_it_vertically (&it, this_scroll_margin);
11107 scroll_margin_pos = it.current.pos;
11108 }
11109
11110 if (PT < CHARPOS (scroll_margin_pos))
11111 {
11112 /* Point is in the scroll margin at the top of the window or
11113 above what is displayed in the window. */
11114 int y0;
11115
11116 /* Compute the vertical distance from PT to the scroll
11117 margin position. Give up if distance is greater than
11118 scroll_max. */
11119 SET_TEXT_POS (pos, PT, PT_BYTE);
11120 start_display (&it, w, pos);
11121 y0 = it.current_y;
11122 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11123 it.last_visible_y, -1,
11124 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11125 dy = it.current_y - y0;
11126 if (dy > scroll_max)
11127 return SCROLLING_FAILED;
11128
11129 /* Compute new window start. */
11130 start_display (&it, w, startp);
11131
11132 if (scroll_conservatively)
11133 amount_to_scroll
11134 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11135 else if (scroll_step || temp_scroll_step)
11136 amount_to_scroll = scroll_max;
11137 else
11138 {
11139 aggressive = current_buffer->scroll_down_aggressively;
11140 height = WINDOW_BOX_TEXT_HEIGHT (w);
11141 if (NUMBERP (aggressive))
11142 {
11143 double float_amount = XFLOATINT (aggressive) * height;
11144 amount_to_scroll = float_amount;
11145 if (amount_to_scroll == 0 && float_amount > 0)
11146 amount_to_scroll = 1;
11147 }
11148 }
11149
11150 if (amount_to_scroll <= 0)
11151 return SCROLLING_FAILED;
11152
11153 move_it_vertically (&it, - amount_to_scroll);
11154 startp = it.current.pos;
11155 }
11156 }
11157
11158 /* Run window scroll functions. */
11159 startp = run_window_scroll_functions (window, startp);
11160
11161 /* Display the window. Give up if new fonts are loaded, or if point
11162 doesn't appear. */
11163 if (!try_window (window, startp))
11164 rc = SCROLLING_NEED_LARGER_MATRICES;
11165 else if (w->cursor.vpos < 0)
11166 {
11167 clear_glyph_matrix (w->desired_matrix);
11168 rc = SCROLLING_FAILED;
11169 }
11170 else
11171 {
11172 /* Maybe forget recorded base line for line number display. */
11173 if (!just_this_one_p
11174 || current_buffer->clip_changed
11175 || BEG_UNCHANGED < CHARPOS (startp))
11176 w->base_line_number = Qnil;
11177
11178 /* If cursor ends up on a partially visible line,
11179 treat that as being off the bottom of the screen. */
11180 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11181 {
11182 clear_glyph_matrix (w->desired_matrix);
11183 ++extra_scroll_margin_lines;
11184 goto too_near_end;
11185 }
11186 rc = SCROLLING_SUCCESS;
11187 }
11188
11189 return rc;
11190 }
11191
11192
11193 /* Compute a suitable window start for window W if display of W starts
11194 on a continuation line. Value is non-zero if a new window start
11195 was computed.
11196
11197 The new window start will be computed, based on W's width, starting
11198 from the start of the continued line. It is the start of the
11199 screen line with the minimum distance from the old start W->start. */
11200
11201 static int
11202 compute_window_start_on_continuation_line (w)
11203 struct window *w;
11204 {
11205 struct text_pos pos, start_pos;
11206 int window_start_changed_p = 0;
11207
11208 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11209
11210 /* If window start is on a continuation line... Window start may be
11211 < BEGV in case there's invisible text at the start of the
11212 buffer (M-x rmail, for example). */
11213 if (CHARPOS (start_pos) > BEGV
11214 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11215 {
11216 struct it it;
11217 struct glyph_row *row;
11218
11219 /* Handle the case that the window start is out of range. */
11220 if (CHARPOS (start_pos) < BEGV)
11221 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11222 else if (CHARPOS (start_pos) > ZV)
11223 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11224
11225 /* Find the start of the continued line. This should be fast
11226 because scan_buffer is fast (newline cache). */
11227 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11228 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11229 row, DEFAULT_FACE_ID);
11230 reseat_at_previous_visible_line_start (&it);
11231
11232 /* If the line start is "too far" away from the window start,
11233 say it takes too much time to compute a new window start. */
11234 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11235 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11236 {
11237 int min_distance, distance;
11238
11239 /* Move forward by display lines to find the new window
11240 start. If window width was enlarged, the new start can
11241 be expected to be > the old start. If window width was
11242 decreased, the new window start will be < the old start.
11243 So, we're looking for the display line start with the
11244 minimum distance from the old window start. */
11245 pos = it.current.pos;
11246 min_distance = INFINITY;
11247 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11248 distance < min_distance)
11249 {
11250 min_distance = distance;
11251 pos = it.current.pos;
11252 move_it_by_lines (&it, 1, 0);
11253 }
11254
11255 /* Set the window start there. */
11256 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11257 window_start_changed_p = 1;
11258 }
11259 }
11260
11261 return window_start_changed_p;
11262 }
11263
11264
11265 /* Try cursor movement in case text has not changed in window WINDOW,
11266 with window start STARTP. Value is
11267
11268 CURSOR_MOVEMENT_SUCCESS if successful
11269
11270 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11271
11272 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11273 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11274 we want to scroll as if scroll-step were set to 1. See the code.
11275
11276 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11277 which case we have to abort this redisplay, and adjust matrices
11278 first. */
11279
11280 enum
11281 {
11282 CURSOR_MOVEMENT_SUCCESS,
11283 CURSOR_MOVEMENT_CANNOT_BE_USED,
11284 CURSOR_MOVEMENT_MUST_SCROLL,
11285 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11286 };
11287
11288 static int
11289 try_cursor_movement (window, startp, scroll_step)
11290 Lisp_Object window;
11291 struct text_pos startp;
11292 int *scroll_step;
11293 {
11294 struct window *w = XWINDOW (window);
11295 struct frame *f = XFRAME (w->frame);
11296 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11297
11298 #if GLYPH_DEBUG
11299 if (inhibit_try_cursor_movement)
11300 return rc;
11301 #endif
11302
11303 /* Handle case where text has not changed, only point, and it has
11304 not moved off the frame. */
11305 if (/* Point may be in this window. */
11306 PT >= CHARPOS (startp)
11307 /* Selective display hasn't changed. */
11308 && !current_buffer->clip_changed
11309 /* Function force-mode-line-update is used to force a thorough
11310 redisplay. It sets either windows_or_buffers_changed or
11311 update_mode_lines. So don't take a shortcut here for these
11312 cases. */
11313 && !update_mode_lines
11314 && !windows_or_buffers_changed
11315 && !cursor_type_changed
11316 /* Can't use this case if highlighting a region. When a
11317 region exists, cursor movement has to do more than just
11318 set the cursor. */
11319 && !(!NILP (Vtransient_mark_mode)
11320 && !NILP (current_buffer->mark_active))
11321 && NILP (w->region_showing)
11322 && NILP (Vshow_trailing_whitespace)
11323 /* Right after splitting windows, last_point may be nil. */
11324 && INTEGERP (w->last_point)
11325 /* This code is not used for mini-buffer for the sake of the case
11326 of redisplaying to replace an echo area message; since in
11327 that case the mini-buffer contents per se are usually
11328 unchanged. This code is of no real use in the mini-buffer
11329 since the handling of this_line_start_pos, etc., in redisplay
11330 handles the same cases. */
11331 && !EQ (window, minibuf_window)
11332 /* When splitting windows or for new windows, it happens that
11333 redisplay is called with a nil window_end_vpos or one being
11334 larger than the window. This should really be fixed in
11335 window.c. I don't have this on my list, now, so we do
11336 approximately the same as the old redisplay code. --gerd. */
11337 && INTEGERP (w->window_end_vpos)
11338 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11339 && (FRAME_WINDOW_P (f)
11340 || !overlay_arrow_in_current_buffer_p ()))
11341 {
11342 int this_scroll_margin, top_scroll_margin;
11343 struct glyph_row *row = NULL;
11344
11345 #if GLYPH_DEBUG
11346 debug_method_add (w, "cursor movement");
11347 #endif
11348
11349 /* Scroll if point within this distance from the top or bottom
11350 of the window. This is a pixel value. */
11351 this_scroll_margin = max (0, scroll_margin);
11352 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11353 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11354
11355 top_scroll_margin = this_scroll_margin;
11356 if (WINDOW_WANTS_HEADER_LINE_P (w))
11357 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11358
11359 /* Start with the row the cursor was displayed during the last
11360 not paused redisplay. Give up if that row is not valid. */
11361 if (w->last_cursor.vpos < 0
11362 || w->last_cursor.vpos >= w->current_matrix->nrows)
11363 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11364 else
11365 {
11366 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11367 if (row->mode_line_p)
11368 ++row;
11369 if (!row->enabled_p)
11370 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11371 }
11372
11373 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11374 {
11375 int scroll_p = 0;
11376 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11377
11378 if (PT > XFASTINT (w->last_point))
11379 {
11380 /* Point has moved forward. */
11381 while (MATRIX_ROW_END_CHARPOS (row) < PT
11382 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11383 {
11384 xassert (row->enabled_p);
11385 ++row;
11386 }
11387
11388 /* The end position of a row equals the start position
11389 of the next row. If PT is there, we would rather
11390 display it in the next line. */
11391 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11392 && MATRIX_ROW_END_CHARPOS (row) == PT
11393 && !cursor_row_p (w, row))
11394 ++row;
11395
11396 /* If within the scroll margin, scroll. Note that
11397 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11398 the next line would be drawn, and that
11399 this_scroll_margin can be zero. */
11400 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11401 || PT > MATRIX_ROW_END_CHARPOS (row)
11402 /* Line is completely visible last line in window
11403 and PT is to be set in the next line. */
11404 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11405 && PT == MATRIX_ROW_END_CHARPOS (row)
11406 && !row->ends_at_zv_p
11407 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11408 scroll_p = 1;
11409 }
11410 else if (PT < XFASTINT (w->last_point))
11411 {
11412 /* Cursor has to be moved backward. Note that PT >=
11413 CHARPOS (startp) because of the outer if-statement. */
11414 while (!row->mode_line_p
11415 && (MATRIX_ROW_START_CHARPOS (row) > PT
11416 || (MATRIX_ROW_START_CHARPOS (row) == PT
11417 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11418 && (row->y > top_scroll_margin
11419 || CHARPOS (startp) == BEGV))
11420 {
11421 xassert (row->enabled_p);
11422 --row;
11423 }
11424
11425 /* Consider the following case: Window starts at BEGV,
11426 there is invisible, intangible text at BEGV, so that
11427 display starts at some point START > BEGV. It can
11428 happen that we are called with PT somewhere between
11429 BEGV and START. Try to handle that case. */
11430 if (row < w->current_matrix->rows
11431 || row->mode_line_p)
11432 {
11433 row = w->current_matrix->rows;
11434 if (row->mode_line_p)
11435 ++row;
11436 }
11437
11438 /* Due to newlines in overlay strings, we may have to
11439 skip forward over overlay strings. */
11440 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11441 && MATRIX_ROW_END_CHARPOS (row) == PT
11442 && !cursor_row_p (w, row))
11443 ++row;
11444
11445 /* If within the scroll margin, scroll. */
11446 if (row->y < top_scroll_margin
11447 && CHARPOS (startp) != BEGV)
11448 scroll_p = 1;
11449 }
11450
11451 if (PT < MATRIX_ROW_START_CHARPOS (row)
11452 || PT > MATRIX_ROW_END_CHARPOS (row))
11453 {
11454 /* if PT is not in the glyph row, give up. */
11455 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11456 }
11457 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11458 {
11459 if (PT == MATRIX_ROW_END_CHARPOS (row)
11460 && !row->ends_at_zv_p
11461 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11462 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11463 else if (row->height > window_box_height (w))
11464 {
11465 /* If we end up in a partially visible line, let's
11466 make it fully visible, except when it's taller
11467 than the window, in which case we can't do much
11468 about it. */
11469 *scroll_step = 1;
11470 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11471 }
11472 else
11473 {
11474 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11475 if (!make_cursor_line_fully_visible (w, 0))
11476 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11477 else
11478 rc = CURSOR_MOVEMENT_SUCCESS;
11479 }
11480 }
11481 else if (scroll_p)
11482 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11483 else
11484 {
11485 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11486 rc = CURSOR_MOVEMENT_SUCCESS;
11487 }
11488 }
11489 }
11490
11491 return rc;
11492 }
11493
11494 void
11495 set_vertical_scroll_bar (w)
11496 struct window *w;
11497 {
11498 int start, end, whole;
11499
11500 /* Calculate the start and end positions for the current window.
11501 At some point, it would be nice to choose between scrollbars
11502 which reflect the whole buffer size, with special markers
11503 indicating narrowing, and scrollbars which reflect only the
11504 visible region.
11505
11506 Note that mini-buffers sometimes aren't displaying any text. */
11507 if (!MINI_WINDOW_P (w)
11508 || (w == XWINDOW (minibuf_window)
11509 && NILP (echo_area_buffer[0])))
11510 {
11511 struct buffer *buf = XBUFFER (w->buffer);
11512 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11513 start = marker_position (w->start) - BUF_BEGV (buf);
11514 /* I don't think this is guaranteed to be right. For the
11515 moment, we'll pretend it is. */
11516 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11517
11518 if (end < start)
11519 end = start;
11520 if (whole < (end - start))
11521 whole = end - start;
11522 }
11523 else
11524 start = end = whole = 0;
11525
11526 /* Indicate what this scroll bar ought to be displaying now. */
11527 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11528 }
11529
11530
11531 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11532 selected_window is redisplayed.
11533
11534 We can return without actually redisplaying the window if
11535 fonts_changed_p is nonzero. In that case, redisplay_internal will
11536 retry. */
11537
11538 static void
11539 redisplay_window (window, just_this_one_p)
11540 Lisp_Object window;
11541 int just_this_one_p;
11542 {
11543 struct window *w = XWINDOW (window);
11544 struct frame *f = XFRAME (w->frame);
11545 struct buffer *buffer = XBUFFER (w->buffer);
11546 struct buffer *old = current_buffer;
11547 struct text_pos lpoint, opoint, startp;
11548 int update_mode_line;
11549 int tem;
11550 struct it it;
11551 /* Record it now because it's overwritten. */
11552 int current_matrix_up_to_date_p = 0;
11553 int used_current_matrix_p = 0;
11554 /* This is less strict than current_matrix_up_to_date_p.
11555 It indictes that the buffer contents and narrowing are unchanged. */
11556 int buffer_unchanged_p = 0;
11557 int temp_scroll_step = 0;
11558 int count = SPECPDL_INDEX ();
11559 int rc;
11560 int centering_position;
11561 int last_line_misfit = 0;
11562
11563 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11564 opoint = lpoint;
11565
11566 /* W must be a leaf window here. */
11567 xassert (!NILP (w->buffer));
11568 #if GLYPH_DEBUG
11569 *w->desired_matrix->method = 0;
11570 #endif
11571
11572 specbind (Qinhibit_point_motion_hooks, Qt);
11573
11574 reconsider_clip_changes (w, buffer);
11575
11576 /* Has the mode line to be updated? */
11577 update_mode_line = (!NILP (w->update_mode_line)
11578 || update_mode_lines
11579 || buffer->clip_changed
11580 || buffer->prevent_redisplay_optimizations_p);
11581
11582 if (MINI_WINDOW_P (w))
11583 {
11584 if (w == XWINDOW (echo_area_window)
11585 && !NILP (echo_area_buffer[0]))
11586 {
11587 if (update_mode_line)
11588 /* We may have to update a tty frame's menu bar or a
11589 tool-bar. Example `M-x C-h C-h C-g'. */
11590 goto finish_menu_bars;
11591 else
11592 /* We've already displayed the echo area glyphs in this window. */
11593 goto finish_scroll_bars;
11594 }
11595 else if ((w != XWINDOW (minibuf_window)
11596 || minibuf_level == 0)
11597 /* When buffer is nonempty, redisplay window normally. */
11598 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11599 /* Quail displays non-mini buffers in minibuffer window.
11600 In that case, redisplay the window normally. */
11601 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11602 {
11603 /* W is a mini-buffer window, but it's not active, so clear
11604 it. */
11605 int yb = window_text_bottom_y (w);
11606 struct glyph_row *row;
11607 int y;
11608
11609 for (y = 0, row = w->desired_matrix->rows;
11610 y < yb;
11611 y += row->height, ++row)
11612 blank_row (w, row, y);
11613 goto finish_scroll_bars;
11614 }
11615
11616 clear_glyph_matrix (w->desired_matrix);
11617 }
11618
11619 /* Otherwise set up data on this window; select its buffer and point
11620 value. */
11621 /* Really select the buffer, for the sake of buffer-local
11622 variables. */
11623 set_buffer_internal_1 (XBUFFER (w->buffer));
11624 SET_TEXT_POS (opoint, PT, PT_BYTE);
11625
11626 current_matrix_up_to_date_p
11627 = (!NILP (w->window_end_valid)
11628 && !current_buffer->clip_changed
11629 && !current_buffer->prevent_redisplay_optimizations_p
11630 && XFASTINT (w->last_modified) >= MODIFF
11631 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11632
11633 buffer_unchanged_p
11634 = (!NILP (w->window_end_valid)
11635 && !current_buffer->clip_changed
11636 && XFASTINT (w->last_modified) >= MODIFF
11637 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11638
11639 /* When windows_or_buffers_changed is non-zero, we can't rely on
11640 the window end being valid, so set it to nil there. */
11641 if (windows_or_buffers_changed)
11642 {
11643 /* If window starts on a continuation line, maybe adjust the
11644 window start in case the window's width changed. */
11645 if (XMARKER (w->start)->buffer == current_buffer)
11646 compute_window_start_on_continuation_line (w);
11647
11648 w->window_end_valid = Qnil;
11649 }
11650
11651 /* Some sanity checks. */
11652 CHECK_WINDOW_END (w);
11653 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11654 abort ();
11655 if (BYTEPOS (opoint) < CHARPOS (opoint))
11656 abort ();
11657
11658 /* If %c is in mode line, update it if needed. */
11659 if (!NILP (w->column_number_displayed)
11660 /* This alternative quickly identifies a common case
11661 where no change is needed. */
11662 && !(PT == XFASTINT (w->last_point)
11663 && XFASTINT (w->last_modified) >= MODIFF
11664 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11665 && (XFASTINT (w->column_number_displayed)
11666 != (int) current_column ())) /* iftc */
11667 update_mode_line = 1;
11668
11669 /* Count number of windows showing the selected buffer. An indirect
11670 buffer counts as its base buffer. */
11671 if (!just_this_one_p)
11672 {
11673 struct buffer *current_base, *window_base;
11674 current_base = current_buffer;
11675 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11676 if (current_base->base_buffer)
11677 current_base = current_base->base_buffer;
11678 if (window_base->base_buffer)
11679 window_base = window_base->base_buffer;
11680 if (current_base == window_base)
11681 buffer_shared++;
11682 }
11683
11684 /* Point refers normally to the selected window. For any other
11685 window, set up appropriate value. */
11686 if (!EQ (window, selected_window))
11687 {
11688 int new_pt = XMARKER (w->pointm)->charpos;
11689 int new_pt_byte = marker_byte_position (w->pointm);
11690 if (new_pt < BEGV)
11691 {
11692 new_pt = BEGV;
11693 new_pt_byte = BEGV_BYTE;
11694 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11695 }
11696 else if (new_pt > (ZV - 1))
11697 {
11698 new_pt = ZV;
11699 new_pt_byte = ZV_BYTE;
11700 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11701 }
11702
11703 /* We don't use SET_PT so that the point-motion hooks don't run. */
11704 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11705 }
11706
11707 /* If any of the character widths specified in the display table
11708 have changed, invalidate the width run cache. It's true that
11709 this may be a bit late to catch such changes, but the rest of
11710 redisplay goes (non-fatally) haywire when the display table is
11711 changed, so why should we worry about doing any better? */
11712 if (current_buffer->width_run_cache)
11713 {
11714 struct Lisp_Char_Table *disptab = buffer_display_table ();
11715
11716 if (! disptab_matches_widthtab (disptab,
11717 XVECTOR (current_buffer->width_table)))
11718 {
11719 invalidate_region_cache (current_buffer,
11720 current_buffer->width_run_cache,
11721 BEG, Z);
11722 recompute_width_table (current_buffer, disptab);
11723 }
11724 }
11725
11726 /* If window-start is screwed up, choose a new one. */
11727 if (XMARKER (w->start)->buffer != current_buffer)
11728 goto recenter;
11729
11730 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11731
11732 /* If someone specified a new starting point but did not insist,
11733 check whether it can be used. */
11734 if (!NILP (w->optional_new_start)
11735 && CHARPOS (startp) >= BEGV
11736 && CHARPOS (startp) <= ZV)
11737 {
11738 w->optional_new_start = Qnil;
11739 start_display (&it, w, startp);
11740 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11741 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11742 if (IT_CHARPOS (it) == PT)
11743 w->force_start = Qt;
11744 /* IT may overshoot PT if text at PT is invisible. */
11745 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11746 w->force_start = Qt;
11747
11748
11749 }
11750
11751 /* Handle case where place to start displaying has been specified,
11752 unless the specified location is outside the accessible range. */
11753 if (!NILP (w->force_start)
11754 || w->frozen_window_start_p)
11755 {
11756 /* We set this later on if we have to adjust point. */
11757 int new_vpos = -1;
11758
11759 w->force_start = Qnil;
11760 w->vscroll = 0;
11761 w->window_end_valid = Qnil;
11762
11763 /* Forget any recorded base line for line number display. */
11764 if (!buffer_unchanged_p)
11765 w->base_line_number = Qnil;
11766
11767 /* Redisplay the mode line. Select the buffer properly for that.
11768 Also, run the hook window-scroll-functions
11769 because we have scrolled. */
11770 /* Note, we do this after clearing force_start because
11771 if there's an error, it is better to forget about force_start
11772 than to get into an infinite loop calling the hook functions
11773 and having them get more errors. */
11774 if (!update_mode_line
11775 || ! NILP (Vwindow_scroll_functions))
11776 {
11777 update_mode_line = 1;
11778 w->update_mode_line = Qt;
11779 startp = run_window_scroll_functions (window, startp);
11780 }
11781
11782 w->last_modified = make_number (0);
11783 w->last_overlay_modified = make_number (0);
11784 if (CHARPOS (startp) < BEGV)
11785 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11786 else if (CHARPOS (startp) > ZV)
11787 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11788
11789 /* Redisplay, then check if cursor has been set during the
11790 redisplay. Give up if new fonts were loaded. */
11791 if (!try_window (window, startp))
11792 {
11793 w->force_start = Qt;
11794 clear_glyph_matrix (w->desired_matrix);
11795 goto need_larger_matrices;
11796 }
11797
11798 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11799 {
11800 /* If point does not appear, try to move point so it does
11801 appear. The desired matrix has been built above, so we
11802 can use it here. */
11803 new_vpos = window_box_height (w) / 2;
11804 }
11805
11806 if (!make_cursor_line_fully_visible (w, 0))
11807 {
11808 /* Point does appear, but on a line partly visible at end of window.
11809 Move it back to a fully-visible line. */
11810 new_vpos = window_box_height (w);
11811 }
11812
11813 /* If we need to move point for either of the above reasons,
11814 now actually do it. */
11815 if (new_vpos >= 0)
11816 {
11817 struct glyph_row *row;
11818
11819 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11820 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11821 ++row;
11822
11823 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11824 MATRIX_ROW_START_BYTEPOS (row));
11825
11826 if (w != XWINDOW (selected_window))
11827 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11828 else if (current_buffer == old)
11829 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11830
11831 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11832
11833 /* If we are highlighting the region, then we just changed
11834 the region, so redisplay to show it. */
11835 if (!NILP (Vtransient_mark_mode)
11836 && !NILP (current_buffer->mark_active))
11837 {
11838 clear_glyph_matrix (w->desired_matrix);
11839 if (!try_window (window, startp))
11840 goto need_larger_matrices;
11841 }
11842 }
11843
11844 #if GLYPH_DEBUG
11845 debug_method_add (w, "forced window start");
11846 #endif
11847 goto done;
11848 }
11849
11850 /* Handle case where text has not changed, only point, and it has
11851 not moved off the frame, and we are not retrying after hscroll.
11852 (current_matrix_up_to_date_p is nonzero when retrying.) */
11853 if (current_matrix_up_to_date_p
11854 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11855 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11856 {
11857 switch (rc)
11858 {
11859 case CURSOR_MOVEMENT_SUCCESS:
11860 used_current_matrix_p = 1;
11861 goto done;
11862
11863 #if 0 /* try_cursor_movement never returns this value. */
11864 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11865 goto need_larger_matrices;
11866 #endif
11867
11868 case CURSOR_MOVEMENT_MUST_SCROLL:
11869 goto try_to_scroll;
11870
11871 default:
11872 abort ();
11873 }
11874 }
11875 /* If current starting point was originally the beginning of a line
11876 but no longer is, find a new starting point. */
11877 else if (!NILP (w->start_at_line_beg)
11878 && !(CHARPOS (startp) <= BEGV
11879 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11880 {
11881 #if GLYPH_DEBUG
11882 debug_method_add (w, "recenter 1");
11883 #endif
11884 goto recenter;
11885 }
11886
11887 /* Try scrolling with try_window_id. Value is > 0 if update has
11888 been done, it is -1 if we know that the same window start will
11889 not work. It is 0 if unsuccessful for some other reason. */
11890 else if ((tem = try_window_id (w)) != 0)
11891 {
11892 #if GLYPH_DEBUG
11893 debug_method_add (w, "try_window_id %d", tem);
11894 #endif
11895
11896 if (fonts_changed_p)
11897 goto need_larger_matrices;
11898 if (tem > 0)
11899 goto done;
11900
11901 /* Otherwise try_window_id has returned -1 which means that we
11902 don't want the alternative below this comment to execute. */
11903 }
11904 else if (CHARPOS (startp) >= BEGV
11905 && CHARPOS (startp) <= ZV
11906 && PT >= CHARPOS (startp)
11907 && (CHARPOS (startp) < ZV
11908 /* Avoid starting at end of buffer. */
11909 || CHARPOS (startp) == BEGV
11910 || (XFASTINT (w->last_modified) >= MODIFF
11911 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11912 {
11913 #if GLYPH_DEBUG
11914 debug_method_add (w, "same window start");
11915 #endif
11916
11917 /* Try to redisplay starting at same place as before.
11918 If point has not moved off frame, accept the results. */
11919 if (!current_matrix_up_to_date_p
11920 /* Don't use try_window_reusing_current_matrix in this case
11921 because a window scroll function can have changed the
11922 buffer. */
11923 || !NILP (Vwindow_scroll_functions)
11924 || MINI_WINDOW_P (w)
11925 || !(used_current_matrix_p
11926 = try_window_reusing_current_matrix (w)))
11927 {
11928 IF_DEBUG (debug_method_add (w, "1"));
11929 try_window (window, startp);
11930 }
11931
11932 if (fonts_changed_p)
11933 goto need_larger_matrices;
11934
11935 if (w->cursor.vpos >= 0)
11936 {
11937 if (!just_this_one_p
11938 || current_buffer->clip_changed
11939 || BEG_UNCHANGED < CHARPOS (startp))
11940 /* Forget any recorded base line for line number display. */
11941 w->base_line_number = Qnil;
11942
11943 if (!make_cursor_line_fully_visible (w, 1))
11944 {
11945 clear_glyph_matrix (w->desired_matrix);
11946 last_line_misfit = 1;
11947 }
11948 /* Drop through and scroll. */
11949 else
11950 goto done;
11951 }
11952 else
11953 clear_glyph_matrix (w->desired_matrix);
11954 }
11955
11956 try_to_scroll:
11957
11958 w->last_modified = make_number (0);
11959 w->last_overlay_modified = make_number (0);
11960
11961 /* Redisplay the mode line. Select the buffer properly for that. */
11962 if (!update_mode_line)
11963 {
11964 update_mode_line = 1;
11965 w->update_mode_line = Qt;
11966 }
11967
11968 /* Try to scroll by specified few lines. */
11969 if ((scroll_conservatively
11970 || scroll_step
11971 || temp_scroll_step
11972 || NUMBERP (current_buffer->scroll_up_aggressively)
11973 || NUMBERP (current_buffer->scroll_down_aggressively))
11974 && !current_buffer->clip_changed
11975 && CHARPOS (startp) >= BEGV
11976 && CHARPOS (startp) <= ZV)
11977 {
11978 /* The function returns -1 if new fonts were loaded, 1 if
11979 successful, 0 if not successful. */
11980 int rc = try_scrolling (window, just_this_one_p,
11981 scroll_conservatively,
11982 scroll_step,
11983 temp_scroll_step, last_line_misfit);
11984 switch (rc)
11985 {
11986 case SCROLLING_SUCCESS:
11987 goto done;
11988
11989 case SCROLLING_NEED_LARGER_MATRICES:
11990 goto need_larger_matrices;
11991
11992 case SCROLLING_FAILED:
11993 break;
11994
11995 default:
11996 abort ();
11997 }
11998 }
11999
12000 /* Finally, just choose place to start which centers point */
12001
12002 recenter:
12003 centering_position = window_box_height (w) / 2;
12004
12005 point_at_top:
12006 /* Jump here with centering_position already set to 0. */
12007
12008 #if GLYPH_DEBUG
12009 debug_method_add (w, "recenter");
12010 #endif
12011
12012 /* w->vscroll = 0; */
12013
12014 /* Forget any previously recorded base line for line number display. */
12015 if (!buffer_unchanged_p)
12016 w->base_line_number = Qnil;
12017
12018 /* Move backward half the height of the window. */
12019 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12020 it.current_y = it.last_visible_y;
12021 move_it_vertically_backward (&it, centering_position);
12022 xassert (IT_CHARPOS (it) >= BEGV);
12023
12024 /* The function move_it_vertically_backward may move over more
12025 than the specified y-distance. If it->w is small, e.g. a
12026 mini-buffer window, we may end up in front of the window's
12027 display area. Start displaying at the start of the line
12028 containing PT in this case. */
12029 if (it.current_y <= 0)
12030 {
12031 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12032 move_it_vertically (&it, 0);
12033 xassert (IT_CHARPOS (it) <= PT);
12034 it.current_y = 0;
12035 }
12036
12037 it.current_x = it.hpos = 0;
12038
12039 /* Set startp here explicitly in case that helps avoid an infinite loop
12040 in case the window-scroll-functions functions get errors. */
12041 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12042
12043 /* Run scroll hooks. */
12044 startp = run_window_scroll_functions (window, it.current.pos);
12045
12046 /* Redisplay the window. */
12047 if (!current_matrix_up_to_date_p
12048 || windows_or_buffers_changed
12049 || cursor_type_changed
12050 /* Don't use try_window_reusing_current_matrix in this case
12051 because it can have changed the buffer. */
12052 || !NILP (Vwindow_scroll_functions)
12053 || !just_this_one_p
12054 || MINI_WINDOW_P (w)
12055 || !(used_current_matrix_p
12056 = try_window_reusing_current_matrix (w)))
12057 try_window (window, startp);
12058
12059 /* If new fonts have been loaded (due to fontsets), give up. We
12060 have to start a new redisplay since we need to re-adjust glyph
12061 matrices. */
12062 if (fonts_changed_p)
12063 goto need_larger_matrices;
12064
12065 /* If cursor did not appear assume that the middle of the window is
12066 in the first line of the window. Do it again with the next line.
12067 (Imagine a window of height 100, displaying two lines of height
12068 60. Moving back 50 from it->last_visible_y will end in the first
12069 line.) */
12070 if (w->cursor.vpos < 0)
12071 {
12072 if (!NILP (w->window_end_valid)
12073 && PT >= Z - XFASTINT (w->window_end_pos))
12074 {
12075 clear_glyph_matrix (w->desired_matrix);
12076 move_it_by_lines (&it, 1, 0);
12077 try_window (window, it.current.pos);
12078 }
12079 else if (PT < IT_CHARPOS (it))
12080 {
12081 clear_glyph_matrix (w->desired_matrix);
12082 move_it_by_lines (&it, -1, 0);
12083 try_window (window, it.current.pos);
12084 }
12085 else
12086 {
12087 /* Not much we can do about it. */
12088 }
12089 }
12090
12091 /* Consider the following case: Window starts at BEGV, there is
12092 invisible, intangible text at BEGV, so that display starts at
12093 some point START > BEGV. It can happen that we are called with
12094 PT somewhere between BEGV and START. Try to handle that case. */
12095 if (w->cursor.vpos < 0)
12096 {
12097 struct glyph_row *row = w->current_matrix->rows;
12098 if (row->mode_line_p)
12099 ++row;
12100 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12101 }
12102
12103 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12104 {
12105 /* If vscroll is enabled, disable it and try again. */
12106 if (w->vscroll)
12107 {
12108 w->vscroll = 0;
12109 clear_glyph_matrix (w->desired_matrix);
12110 goto recenter;
12111 }
12112
12113 /* If centering point failed to make the whole line visible,
12114 put point at the top instead. That has to make the whole line
12115 visible, if it can be done. */
12116 clear_glyph_matrix (w->desired_matrix);
12117 centering_position = 0;
12118 goto point_at_top;
12119 }
12120
12121 done:
12122
12123 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12124 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12125 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12126 ? Qt : Qnil);
12127
12128 /* Display the mode line, if we must. */
12129 if ((update_mode_line
12130 /* If window not full width, must redo its mode line
12131 if (a) the window to its side is being redone and
12132 (b) we do a frame-based redisplay. This is a consequence
12133 of how inverted lines are drawn in frame-based redisplay. */
12134 || (!just_this_one_p
12135 && !FRAME_WINDOW_P (f)
12136 && !WINDOW_FULL_WIDTH_P (w))
12137 /* Line number to display. */
12138 || INTEGERP (w->base_line_pos)
12139 /* Column number is displayed and different from the one displayed. */
12140 || (!NILP (w->column_number_displayed)
12141 && (XFASTINT (w->column_number_displayed)
12142 != (int) current_column ()))) /* iftc */
12143 /* This means that the window has a mode line. */
12144 && (WINDOW_WANTS_MODELINE_P (w)
12145 || WINDOW_WANTS_HEADER_LINE_P (w)))
12146 {
12147 display_mode_lines (w);
12148
12149 /* If mode line height has changed, arrange for a thorough
12150 immediate redisplay using the correct mode line height. */
12151 if (WINDOW_WANTS_MODELINE_P (w)
12152 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12153 {
12154 fonts_changed_p = 1;
12155 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12156 = DESIRED_MODE_LINE_HEIGHT (w);
12157 }
12158
12159 /* If top line height has changed, arrange for a thorough
12160 immediate redisplay using the correct mode line height. */
12161 if (WINDOW_WANTS_HEADER_LINE_P (w)
12162 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12163 {
12164 fonts_changed_p = 1;
12165 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12166 = DESIRED_HEADER_LINE_HEIGHT (w);
12167 }
12168
12169 if (fonts_changed_p)
12170 goto need_larger_matrices;
12171 }
12172
12173 if (!line_number_displayed
12174 && !BUFFERP (w->base_line_pos))
12175 {
12176 w->base_line_pos = Qnil;
12177 w->base_line_number = Qnil;
12178 }
12179
12180 finish_menu_bars:
12181
12182 /* When we reach a frame's selected window, redo the frame's menu bar. */
12183 if (update_mode_line
12184 && EQ (FRAME_SELECTED_WINDOW (f), window))
12185 {
12186 int redisplay_menu_p = 0;
12187 int redisplay_tool_bar_p = 0;
12188
12189 if (FRAME_WINDOW_P (f))
12190 {
12191 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12192 || defined (USE_GTK)
12193 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12194 #else
12195 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12196 #endif
12197 }
12198 else
12199 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12200
12201 if (redisplay_menu_p)
12202 display_menu_bar (w);
12203
12204 #ifdef HAVE_WINDOW_SYSTEM
12205 #ifdef USE_GTK
12206 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12207 #else
12208 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12209 && (FRAME_TOOL_BAR_LINES (f) > 0
12210 || auto_resize_tool_bars_p);
12211
12212 #endif
12213
12214 if (redisplay_tool_bar_p)
12215 redisplay_tool_bar (f);
12216 #endif
12217 }
12218
12219 #ifdef HAVE_WINDOW_SYSTEM
12220 if (update_window_fringes (w, 0)
12221 && !just_this_one_p
12222 && (used_current_matrix_p || overlay_arrow_seen)
12223 && !w->pseudo_window_p)
12224 {
12225 update_begin (f);
12226 BLOCK_INPUT;
12227 if (draw_window_fringes (w, 1))
12228 x_draw_vertical_border (w);
12229 UNBLOCK_INPUT;
12230 update_end (f);
12231 }
12232 #endif /* HAVE_WINDOW_SYSTEM */
12233
12234 /* We go to this label, with fonts_changed_p nonzero,
12235 if it is necessary to try again using larger glyph matrices.
12236 We have to redeem the scroll bar even in this case,
12237 because the loop in redisplay_internal expects that. */
12238 need_larger_matrices:
12239 ;
12240 finish_scroll_bars:
12241
12242 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12243 {
12244 /* Set the thumb's position and size. */
12245 set_vertical_scroll_bar (w);
12246
12247 /* Note that we actually used the scroll bar attached to this
12248 window, so it shouldn't be deleted at the end of redisplay. */
12249 redeem_scroll_bar_hook (w);
12250 }
12251
12252 /* Restore current_buffer and value of point in it. */
12253 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12254 set_buffer_internal_1 (old);
12255 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12256
12257 unbind_to (count, Qnil);
12258 }
12259
12260
12261 /* Build the complete desired matrix of WINDOW with a window start
12262 buffer position POS. Value is non-zero if successful. It is zero
12263 if fonts were loaded during redisplay which makes re-adjusting
12264 glyph matrices necessary. */
12265
12266 int
12267 try_window (window, pos)
12268 Lisp_Object window;
12269 struct text_pos pos;
12270 {
12271 struct window *w = XWINDOW (window);
12272 struct it it;
12273 struct glyph_row *last_text_row = NULL;
12274
12275 /* Make POS the new window start. */
12276 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12277
12278 /* Mark cursor position as unknown. No overlay arrow seen. */
12279 w->cursor.vpos = -1;
12280 overlay_arrow_seen = 0;
12281
12282 /* Initialize iterator and info to start at POS. */
12283 start_display (&it, w, pos);
12284
12285 /* Display all lines of W. */
12286 while (it.current_y < it.last_visible_y)
12287 {
12288 if (display_line (&it))
12289 last_text_row = it.glyph_row - 1;
12290 if (fonts_changed_p)
12291 return 0;
12292 }
12293
12294 /* If bottom moved off end of frame, change mode line percentage. */
12295 if (XFASTINT (w->window_end_pos) <= 0
12296 && Z != IT_CHARPOS (it))
12297 w->update_mode_line = Qt;
12298
12299 /* Set window_end_pos to the offset of the last character displayed
12300 on the window from the end of current_buffer. Set
12301 window_end_vpos to its row number. */
12302 if (last_text_row)
12303 {
12304 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12305 w->window_end_bytepos
12306 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12307 w->window_end_pos
12308 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12309 w->window_end_vpos
12310 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12311 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12312 ->displays_text_p);
12313 }
12314 else
12315 {
12316 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12317 w->window_end_pos = make_number (Z - ZV);
12318 w->window_end_vpos = make_number (0);
12319 }
12320
12321 /* But that is not valid info until redisplay finishes. */
12322 w->window_end_valid = Qnil;
12323 return 1;
12324 }
12325
12326
12327 \f
12328 /************************************************************************
12329 Window redisplay reusing current matrix when buffer has not changed
12330 ************************************************************************/
12331
12332 /* Try redisplay of window W showing an unchanged buffer with a
12333 different window start than the last time it was displayed by
12334 reusing its current matrix. Value is non-zero if successful.
12335 W->start is the new window start. */
12336
12337 static int
12338 try_window_reusing_current_matrix (w)
12339 struct window *w;
12340 {
12341 struct frame *f = XFRAME (w->frame);
12342 struct glyph_row *row, *bottom_row;
12343 struct it it;
12344 struct run run;
12345 struct text_pos start, new_start;
12346 int nrows_scrolled, i;
12347 struct glyph_row *last_text_row;
12348 struct glyph_row *last_reused_text_row;
12349 struct glyph_row *start_row;
12350 int start_vpos, min_y, max_y;
12351
12352 #if GLYPH_DEBUG
12353 if (inhibit_try_window_reusing)
12354 return 0;
12355 #endif
12356
12357 if (/* This function doesn't handle terminal frames. */
12358 !FRAME_WINDOW_P (f)
12359 /* Don't try to reuse the display if windows have been split
12360 or such. */
12361 || windows_or_buffers_changed
12362 || cursor_type_changed)
12363 return 0;
12364
12365 /* Can't do this if region may have changed. */
12366 if ((!NILP (Vtransient_mark_mode)
12367 && !NILP (current_buffer->mark_active))
12368 || !NILP (w->region_showing)
12369 || !NILP (Vshow_trailing_whitespace))
12370 return 0;
12371
12372 /* If top-line visibility has changed, give up. */
12373 if (WINDOW_WANTS_HEADER_LINE_P (w)
12374 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12375 return 0;
12376
12377 /* Give up if old or new display is scrolled vertically. We could
12378 make this function handle this, but right now it doesn't. */
12379 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12380 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12381 return 0;
12382
12383 /* The variable new_start now holds the new window start. The old
12384 start `start' can be determined from the current matrix. */
12385 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12386 start = start_row->start.pos;
12387 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12388
12389 /* Clear the desired matrix for the display below. */
12390 clear_glyph_matrix (w->desired_matrix);
12391
12392 if (CHARPOS (new_start) <= CHARPOS (start))
12393 {
12394 int first_row_y;
12395
12396 /* Don't use this method if the display starts with an ellipsis
12397 displayed for invisible text. It's not easy to handle that case
12398 below, and it's certainly not worth the effort since this is
12399 not a frequent case. */
12400 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12401 return 0;
12402
12403 IF_DEBUG (debug_method_add (w, "twu1"));
12404
12405 /* Display up to a row that can be reused. The variable
12406 last_text_row is set to the last row displayed that displays
12407 text. Note that it.vpos == 0 if or if not there is a
12408 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12409 start_display (&it, w, new_start);
12410 first_row_y = it.current_y;
12411 w->cursor.vpos = -1;
12412 last_text_row = last_reused_text_row = NULL;
12413
12414 while (it.current_y < it.last_visible_y
12415 && !fonts_changed_p)
12416 {
12417 /* If we have reached into the characters in the START row,
12418 that means the line boundaries have changed. So we
12419 can't start copying with the row START. Maybe it will
12420 work to start copying with the following row. */
12421 while (IT_CHARPOS (it) > CHARPOS (start))
12422 {
12423 /* Advance to the next row as the "start". */
12424 start_row++;
12425 start = start_row->start.pos;
12426 /* If there are no more rows to try, or just one, give up. */
12427 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12428 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row)
12429 || CHARPOS (start) == ZV)
12430 {
12431 clear_glyph_matrix (w->desired_matrix);
12432 return 0;
12433 }
12434
12435 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12436 }
12437 /* If we have reached alignment,
12438 we can copy the rest of the rows. */
12439 if (IT_CHARPOS (it) == CHARPOS (start))
12440 break;
12441
12442 if (display_line (&it))
12443 last_text_row = it.glyph_row - 1;
12444 }
12445
12446 /* A value of current_y < last_visible_y means that we stopped
12447 at the previous window start, which in turn means that we
12448 have at least one reusable row. */
12449 if (it.current_y < it.last_visible_y)
12450 {
12451 /* IT.vpos always starts from 0; it counts text lines. */
12452 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12453
12454 /* Find PT if not already found in the lines displayed. */
12455 if (w->cursor.vpos < 0)
12456 {
12457 int dy = it.current_y - start_row->y;
12458
12459 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12460 row = row_containing_pos (w, PT, row, NULL, dy);
12461 if (row)
12462 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12463 dy, nrows_scrolled);
12464 else
12465 {
12466 clear_glyph_matrix (w->desired_matrix);
12467 return 0;
12468 }
12469 }
12470
12471 /* Scroll the display. Do it before the current matrix is
12472 changed. The problem here is that update has not yet
12473 run, i.e. part of the current matrix is not up to date.
12474 scroll_run_hook will clear the cursor, and use the
12475 current matrix to get the height of the row the cursor is
12476 in. */
12477 run.current_y = start_row->y;
12478 run.desired_y = it.current_y;
12479 run.height = it.last_visible_y - it.current_y;
12480
12481 if (run.height > 0 && run.current_y != run.desired_y)
12482 {
12483 update_begin (f);
12484 rif->update_window_begin_hook (w);
12485 rif->clear_window_mouse_face (w);
12486 rif->scroll_run_hook (w, &run);
12487 rif->update_window_end_hook (w, 0, 0);
12488 update_end (f);
12489 }
12490
12491 /* Shift current matrix down by nrows_scrolled lines. */
12492 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12493 rotate_matrix (w->current_matrix,
12494 start_vpos,
12495 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12496 nrows_scrolled);
12497
12498 /* Disable lines that must be updated. */
12499 for (i = 0; i < it.vpos; ++i)
12500 (start_row + i)->enabled_p = 0;
12501
12502 /* Re-compute Y positions. */
12503 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12504 max_y = it.last_visible_y;
12505 for (row = start_row + nrows_scrolled;
12506 row < bottom_row;
12507 ++row)
12508 {
12509 row->y = it.current_y;
12510 row->visible_height = row->height;
12511
12512 if (row->y < min_y)
12513 row->visible_height -= min_y - row->y;
12514 if (row->y + row->height > max_y)
12515 row->visible_height -= row->y + row->height - max_y;
12516 row->redraw_fringe_bitmaps_p = 1;
12517
12518 it.current_y += row->height;
12519
12520 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12521 last_reused_text_row = row;
12522 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12523 break;
12524 }
12525
12526 /* Disable lines in the current matrix which are now
12527 below the window. */
12528 for (++row; row < bottom_row; ++row)
12529 row->enabled_p = 0;
12530 }
12531
12532 /* Update window_end_pos etc.; last_reused_text_row is the last
12533 reused row from the current matrix containing text, if any.
12534 The value of last_text_row is the last displayed line
12535 containing text. */
12536 if (last_reused_text_row)
12537 {
12538 w->window_end_bytepos
12539 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12540 w->window_end_pos
12541 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12542 w->window_end_vpos
12543 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12544 w->current_matrix));
12545 }
12546 else if (last_text_row)
12547 {
12548 w->window_end_bytepos
12549 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12550 w->window_end_pos
12551 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12552 w->window_end_vpos
12553 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12554 }
12555 else
12556 {
12557 /* This window must be completely empty. */
12558 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12559 w->window_end_pos = make_number (Z - ZV);
12560 w->window_end_vpos = make_number (0);
12561 }
12562 w->window_end_valid = Qnil;
12563
12564 /* Update hint: don't try scrolling again in update_window. */
12565 w->desired_matrix->no_scrolling_p = 1;
12566
12567 #if GLYPH_DEBUG
12568 debug_method_add (w, "try_window_reusing_current_matrix 1");
12569 #endif
12570 return 1;
12571 }
12572 else if (CHARPOS (new_start) > CHARPOS (start))
12573 {
12574 struct glyph_row *pt_row, *row;
12575 struct glyph_row *first_reusable_row;
12576 struct glyph_row *first_row_to_display;
12577 int dy;
12578 int yb = window_text_bottom_y (w);
12579
12580 /* Find the row starting at new_start, if there is one. Don't
12581 reuse a partially visible line at the end. */
12582 first_reusable_row = start_row;
12583 while (first_reusable_row->enabled_p
12584 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12585 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12586 < CHARPOS (new_start)))
12587 ++first_reusable_row;
12588
12589 /* Give up if there is no row to reuse. */
12590 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12591 || !first_reusable_row->enabled_p
12592 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12593 != CHARPOS (new_start)))
12594 return 0;
12595
12596 /* We can reuse fully visible rows beginning with
12597 first_reusable_row to the end of the window. Set
12598 first_row_to_display to the first row that cannot be reused.
12599 Set pt_row to the row containing point, if there is any. */
12600 pt_row = NULL;
12601 for (first_row_to_display = first_reusable_row;
12602 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12603 ++first_row_to_display)
12604 {
12605 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12606 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12607 pt_row = first_row_to_display;
12608 }
12609
12610 /* Start displaying at the start of first_row_to_display. */
12611 xassert (first_row_to_display->y < yb);
12612 init_to_row_start (&it, w, first_row_to_display);
12613
12614 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12615 - start_vpos);
12616 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12617 - nrows_scrolled);
12618 it.current_y = (first_row_to_display->y - first_reusable_row->y
12619 + WINDOW_HEADER_LINE_HEIGHT (w));
12620
12621 /* Display lines beginning with first_row_to_display in the
12622 desired matrix. Set last_text_row to the last row displayed
12623 that displays text. */
12624 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12625 if (pt_row == NULL)
12626 w->cursor.vpos = -1;
12627 last_text_row = NULL;
12628 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12629 if (display_line (&it))
12630 last_text_row = it.glyph_row - 1;
12631
12632 /* Give up If point isn't in a row displayed or reused. */
12633 if (w->cursor.vpos < 0)
12634 {
12635 clear_glyph_matrix (w->desired_matrix);
12636 return 0;
12637 }
12638
12639 /* If point is in a reused row, adjust y and vpos of the cursor
12640 position. */
12641 if (pt_row)
12642 {
12643 w->cursor.vpos -= nrows_scrolled;
12644 w->cursor.y -= first_reusable_row->y - start_row->y;
12645 }
12646
12647 /* Scroll the display. */
12648 run.current_y = first_reusable_row->y;
12649 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12650 run.height = it.last_visible_y - run.current_y;
12651 dy = run.current_y - run.desired_y;
12652
12653 if (run.height)
12654 {
12655 update_begin (f);
12656 rif->update_window_begin_hook (w);
12657 rif->clear_window_mouse_face (w);
12658 rif->scroll_run_hook (w, &run);
12659 rif->update_window_end_hook (w, 0, 0);
12660 update_end (f);
12661 }
12662
12663 /* Adjust Y positions of reused rows. */
12664 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12665 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12666 max_y = it.last_visible_y;
12667 for (row = first_reusable_row; row < first_row_to_display; ++row)
12668 {
12669 row->y -= dy;
12670 row->visible_height = row->height;
12671 if (row->y < min_y)
12672 row->visible_height -= min_y - row->y;
12673 if (row->y + row->height > max_y)
12674 row->visible_height -= row->y + row->height - max_y;
12675 row->redraw_fringe_bitmaps_p = 1;
12676 }
12677
12678 /* Scroll the current matrix. */
12679 xassert (nrows_scrolled > 0);
12680 rotate_matrix (w->current_matrix,
12681 start_vpos,
12682 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12683 -nrows_scrolled);
12684
12685 /* Disable rows not reused. */
12686 for (row -= nrows_scrolled; row < bottom_row; ++row)
12687 row->enabled_p = 0;
12688
12689 /* Point may have moved to a different line, so we cannot assume that
12690 the previous cursor position is valid; locate the correct row. */
12691 if (pt_row)
12692 {
12693 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12694 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12695 row++)
12696 {
12697 w->cursor.vpos++;
12698 w->cursor.y = row->y;
12699 }
12700 if (row < bottom_row)
12701 {
12702 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12703 while (glyph->charpos < PT)
12704 {
12705 w->cursor.hpos++;
12706 w->cursor.x += glyph->pixel_width;
12707 glyph++;
12708 }
12709 }
12710 }
12711
12712 /* Adjust window end. A null value of last_text_row means that
12713 the window end is in reused rows which in turn means that
12714 only its vpos can have changed. */
12715 if (last_text_row)
12716 {
12717 w->window_end_bytepos
12718 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12719 w->window_end_pos
12720 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12721 w->window_end_vpos
12722 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12723 }
12724 else
12725 {
12726 w->window_end_vpos
12727 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12728 }
12729
12730 w->window_end_valid = Qnil;
12731 w->desired_matrix->no_scrolling_p = 1;
12732
12733 #if GLYPH_DEBUG
12734 debug_method_add (w, "try_window_reusing_current_matrix 2");
12735 #endif
12736 return 1;
12737 }
12738
12739 return 0;
12740 }
12741
12742
12743 \f
12744 /************************************************************************
12745 Window redisplay reusing current matrix when buffer has changed
12746 ************************************************************************/
12747
12748 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12749 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12750 int *, int *));
12751 static struct glyph_row *
12752 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12753 struct glyph_row *));
12754
12755
12756 /* Return the last row in MATRIX displaying text. If row START is
12757 non-null, start searching with that row. IT gives the dimensions
12758 of the display. Value is null if matrix is empty; otherwise it is
12759 a pointer to the row found. */
12760
12761 static struct glyph_row *
12762 find_last_row_displaying_text (matrix, it, start)
12763 struct glyph_matrix *matrix;
12764 struct it *it;
12765 struct glyph_row *start;
12766 {
12767 struct glyph_row *row, *row_found;
12768
12769 /* Set row_found to the last row in IT->w's current matrix
12770 displaying text. The loop looks funny but think of partially
12771 visible lines. */
12772 row_found = NULL;
12773 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12774 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12775 {
12776 xassert (row->enabled_p);
12777 row_found = row;
12778 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12779 break;
12780 ++row;
12781 }
12782
12783 return row_found;
12784 }
12785
12786
12787 /* Return the last row in the current matrix of W that is not affected
12788 by changes at the start of current_buffer that occurred since W's
12789 current matrix was built. Value is null if no such row exists.
12790
12791 BEG_UNCHANGED us the number of characters unchanged at the start of
12792 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12793 first changed character in current_buffer. Characters at positions <
12794 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12795 when the current matrix was built. */
12796
12797 static struct glyph_row *
12798 find_last_unchanged_at_beg_row (w)
12799 struct window *w;
12800 {
12801 int first_changed_pos = BEG + BEG_UNCHANGED;
12802 struct glyph_row *row;
12803 struct glyph_row *row_found = NULL;
12804 int yb = window_text_bottom_y (w);
12805
12806 /* Find the last row displaying unchanged text. */
12807 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12808 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12809 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12810 {
12811 if (/* If row ends before first_changed_pos, it is unchanged,
12812 except in some case. */
12813 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12814 /* When row ends in ZV and we write at ZV it is not
12815 unchanged. */
12816 && !row->ends_at_zv_p
12817 /* When first_changed_pos is the end of a continued line,
12818 row is not unchanged because it may be no longer
12819 continued. */
12820 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12821 && (row->continued_p
12822 || row->exact_window_width_line_p)))
12823 row_found = row;
12824
12825 /* Stop if last visible row. */
12826 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12827 break;
12828
12829 ++row;
12830 }
12831
12832 return row_found;
12833 }
12834
12835
12836 /* Find the first glyph row in the current matrix of W that is not
12837 affected by changes at the end of current_buffer since the
12838 time W's current matrix was built.
12839
12840 Return in *DELTA the number of chars by which buffer positions in
12841 unchanged text at the end of current_buffer must be adjusted.
12842
12843 Return in *DELTA_BYTES the corresponding number of bytes.
12844
12845 Value is null if no such row exists, i.e. all rows are affected by
12846 changes. */
12847
12848 static struct glyph_row *
12849 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12850 struct window *w;
12851 int *delta, *delta_bytes;
12852 {
12853 struct glyph_row *row;
12854 struct glyph_row *row_found = NULL;
12855
12856 *delta = *delta_bytes = 0;
12857
12858 /* Display must not have been paused, otherwise the current matrix
12859 is not up to date. */
12860 if (NILP (w->window_end_valid))
12861 abort ();
12862
12863 /* A value of window_end_pos >= END_UNCHANGED means that the window
12864 end is in the range of changed text. If so, there is no
12865 unchanged row at the end of W's current matrix. */
12866 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12867 return NULL;
12868
12869 /* Set row to the last row in W's current matrix displaying text. */
12870 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12871
12872 /* If matrix is entirely empty, no unchanged row exists. */
12873 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12874 {
12875 /* The value of row is the last glyph row in the matrix having a
12876 meaningful buffer position in it. The end position of row
12877 corresponds to window_end_pos. This allows us to translate
12878 buffer positions in the current matrix to current buffer
12879 positions for characters not in changed text. */
12880 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12881 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12882 int last_unchanged_pos, last_unchanged_pos_old;
12883 struct glyph_row *first_text_row
12884 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12885
12886 *delta = Z - Z_old;
12887 *delta_bytes = Z_BYTE - Z_BYTE_old;
12888
12889 /* Set last_unchanged_pos to the buffer position of the last
12890 character in the buffer that has not been changed. Z is the
12891 index + 1 of the last character in current_buffer, i.e. by
12892 subtracting END_UNCHANGED we get the index of the last
12893 unchanged character, and we have to add BEG to get its buffer
12894 position. */
12895 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12896 last_unchanged_pos_old = last_unchanged_pos - *delta;
12897
12898 /* Search backward from ROW for a row displaying a line that
12899 starts at a minimum position >= last_unchanged_pos_old. */
12900 for (; row > first_text_row; --row)
12901 {
12902 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12903 abort ();
12904
12905 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12906 row_found = row;
12907 }
12908 }
12909
12910 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12911 abort ();
12912
12913 return row_found;
12914 }
12915
12916
12917 /* Make sure that glyph rows in the current matrix of window W
12918 reference the same glyph memory as corresponding rows in the
12919 frame's frame matrix. This function is called after scrolling W's
12920 current matrix on a terminal frame in try_window_id and
12921 try_window_reusing_current_matrix. */
12922
12923 static void
12924 sync_frame_with_window_matrix_rows (w)
12925 struct window *w;
12926 {
12927 struct frame *f = XFRAME (w->frame);
12928 struct glyph_row *window_row, *window_row_end, *frame_row;
12929
12930 /* Preconditions: W must be a leaf window and full-width. Its frame
12931 must have a frame matrix. */
12932 xassert (NILP (w->hchild) && NILP (w->vchild));
12933 xassert (WINDOW_FULL_WIDTH_P (w));
12934 xassert (!FRAME_WINDOW_P (f));
12935
12936 /* If W is a full-width window, glyph pointers in W's current matrix
12937 have, by definition, to be the same as glyph pointers in the
12938 corresponding frame matrix. Note that frame matrices have no
12939 marginal areas (see build_frame_matrix). */
12940 window_row = w->current_matrix->rows;
12941 window_row_end = window_row + w->current_matrix->nrows;
12942 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12943 while (window_row < window_row_end)
12944 {
12945 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12946 struct glyph *end = window_row->glyphs[LAST_AREA];
12947
12948 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12949 frame_row->glyphs[TEXT_AREA] = start;
12950 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12951 frame_row->glyphs[LAST_AREA] = end;
12952
12953 /* Disable frame rows whose corresponding window rows have
12954 been disabled in try_window_id. */
12955 if (!window_row->enabled_p)
12956 frame_row->enabled_p = 0;
12957
12958 ++window_row, ++frame_row;
12959 }
12960 }
12961
12962
12963 /* Find the glyph row in window W containing CHARPOS. Consider all
12964 rows between START and END (not inclusive). END null means search
12965 all rows to the end of the display area of W. Value is the row
12966 containing CHARPOS or null. */
12967
12968 struct glyph_row *
12969 row_containing_pos (w, charpos, start, end, dy)
12970 struct window *w;
12971 int charpos;
12972 struct glyph_row *start, *end;
12973 int dy;
12974 {
12975 struct glyph_row *row = start;
12976 int last_y;
12977
12978 /* If we happen to start on a header-line, skip that. */
12979 if (row->mode_line_p)
12980 ++row;
12981
12982 if ((end && row >= end) || !row->enabled_p)
12983 return NULL;
12984
12985 last_y = window_text_bottom_y (w) - dy;
12986
12987 while (1)
12988 {
12989 /* Give up if we have gone too far. */
12990 if (end && row >= end)
12991 return NULL;
12992 /* This formerly returned if they were equal.
12993 I think that both quantities are of a "last plus one" type;
12994 if so, when they are equal, the row is within the screen. -- rms. */
12995 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12996 return NULL;
12997
12998 /* If it is in this row, return this row. */
12999 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13000 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13001 /* The end position of a row equals the start
13002 position of the next row. If CHARPOS is there, we
13003 would rather display it in the next line, except
13004 when this line ends in ZV. */
13005 && !row->ends_at_zv_p
13006 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13007 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13008 return row;
13009 ++row;
13010 }
13011 }
13012
13013
13014 /* Try to redisplay window W by reusing its existing display. W's
13015 current matrix must be up to date when this function is called,
13016 i.e. window_end_valid must not be nil.
13017
13018 Value is
13019
13020 1 if display has been updated
13021 0 if otherwise unsuccessful
13022 -1 if redisplay with same window start is known not to succeed
13023
13024 The following steps are performed:
13025
13026 1. Find the last row in the current matrix of W that is not
13027 affected by changes at the start of current_buffer. If no such row
13028 is found, give up.
13029
13030 2. Find the first row in W's current matrix that is not affected by
13031 changes at the end of current_buffer. Maybe there is no such row.
13032
13033 3. Display lines beginning with the row + 1 found in step 1 to the
13034 row found in step 2 or, if step 2 didn't find a row, to the end of
13035 the window.
13036
13037 4. If cursor is not known to appear on the window, give up.
13038
13039 5. If display stopped at the row found in step 2, scroll the
13040 display and current matrix as needed.
13041
13042 6. Maybe display some lines at the end of W, if we must. This can
13043 happen under various circumstances, like a partially visible line
13044 becoming fully visible, or because newly displayed lines are displayed
13045 in smaller font sizes.
13046
13047 7. Update W's window end information. */
13048
13049 static int
13050 try_window_id (w)
13051 struct window *w;
13052 {
13053 struct frame *f = XFRAME (w->frame);
13054 struct glyph_matrix *current_matrix = w->current_matrix;
13055 struct glyph_matrix *desired_matrix = w->desired_matrix;
13056 struct glyph_row *last_unchanged_at_beg_row;
13057 struct glyph_row *first_unchanged_at_end_row;
13058 struct glyph_row *row;
13059 struct glyph_row *bottom_row;
13060 int bottom_vpos;
13061 struct it it;
13062 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13063 struct text_pos start_pos;
13064 struct run run;
13065 int first_unchanged_at_end_vpos = 0;
13066 struct glyph_row *last_text_row, *last_text_row_at_end;
13067 struct text_pos start;
13068 int first_changed_charpos, last_changed_charpos;
13069
13070 #if GLYPH_DEBUG
13071 if (inhibit_try_window_id)
13072 return 0;
13073 #endif
13074
13075 /* This is handy for debugging. */
13076 #if 0
13077 #define GIVE_UP(X) \
13078 do { \
13079 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13080 return 0; \
13081 } while (0)
13082 #else
13083 #define GIVE_UP(X) return 0
13084 #endif
13085
13086 SET_TEXT_POS_FROM_MARKER (start, w->start);
13087
13088 /* Don't use this for mini-windows because these can show
13089 messages and mini-buffers, and we don't handle that here. */
13090 if (MINI_WINDOW_P (w))
13091 GIVE_UP (1);
13092
13093 /* This flag is used to prevent redisplay optimizations. */
13094 if (windows_or_buffers_changed || cursor_type_changed)
13095 GIVE_UP (2);
13096
13097 /* Verify that narrowing has not changed.
13098 Also verify that we were not told to prevent redisplay optimizations.
13099 It would be nice to further
13100 reduce the number of cases where this prevents try_window_id. */
13101 if (current_buffer->clip_changed
13102 || current_buffer->prevent_redisplay_optimizations_p)
13103 GIVE_UP (3);
13104
13105 /* Window must either use window-based redisplay or be full width. */
13106 if (!FRAME_WINDOW_P (f)
13107 && (!line_ins_del_ok
13108 || !WINDOW_FULL_WIDTH_P (w)))
13109 GIVE_UP (4);
13110
13111 /* Give up if point is not known NOT to appear in W. */
13112 if (PT < CHARPOS (start))
13113 GIVE_UP (5);
13114
13115 /* Another way to prevent redisplay optimizations. */
13116 if (XFASTINT (w->last_modified) == 0)
13117 GIVE_UP (6);
13118
13119 /* Verify that window is not hscrolled. */
13120 if (XFASTINT (w->hscroll) != 0)
13121 GIVE_UP (7);
13122
13123 /* Verify that display wasn't paused. */
13124 if (NILP (w->window_end_valid))
13125 GIVE_UP (8);
13126
13127 /* Can't use this if highlighting a region because a cursor movement
13128 will do more than just set the cursor. */
13129 if (!NILP (Vtransient_mark_mode)
13130 && !NILP (current_buffer->mark_active))
13131 GIVE_UP (9);
13132
13133 /* Likewise if highlighting trailing whitespace. */
13134 if (!NILP (Vshow_trailing_whitespace))
13135 GIVE_UP (11);
13136
13137 /* Likewise if showing a region. */
13138 if (!NILP (w->region_showing))
13139 GIVE_UP (10);
13140
13141 /* Can use this if overlay arrow position and or string have changed. */
13142 if (overlay_arrows_changed_p ())
13143 GIVE_UP (12);
13144
13145
13146 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13147 only if buffer has really changed. The reason is that the gap is
13148 initially at Z for freshly visited files. The code below would
13149 set end_unchanged to 0 in that case. */
13150 if (MODIFF > SAVE_MODIFF
13151 /* This seems to happen sometimes after saving a buffer. */
13152 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13153 {
13154 if (GPT - BEG < BEG_UNCHANGED)
13155 BEG_UNCHANGED = GPT - BEG;
13156 if (Z - GPT < END_UNCHANGED)
13157 END_UNCHANGED = Z - GPT;
13158 }
13159
13160 /* The position of the first and last character that has been changed. */
13161 first_changed_charpos = BEG + BEG_UNCHANGED;
13162 last_changed_charpos = Z - END_UNCHANGED;
13163
13164 /* If window starts after a line end, and the last change is in
13165 front of that newline, then changes don't affect the display.
13166 This case happens with stealth-fontification. Note that although
13167 the display is unchanged, glyph positions in the matrix have to
13168 be adjusted, of course. */
13169 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13170 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13171 && ((last_changed_charpos < CHARPOS (start)
13172 && CHARPOS (start) == BEGV)
13173 || (last_changed_charpos < CHARPOS (start) - 1
13174 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13175 {
13176 int Z_old, delta, Z_BYTE_old, delta_bytes;
13177 struct glyph_row *r0;
13178
13179 /* Compute how many chars/bytes have been added to or removed
13180 from the buffer. */
13181 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13182 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13183 delta = Z - Z_old;
13184 delta_bytes = Z_BYTE - Z_BYTE_old;
13185
13186 /* Give up if PT is not in the window. Note that it already has
13187 been checked at the start of try_window_id that PT is not in
13188 front of the window start. */
13189 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13190 GIVE_UP (13);
13191
13192 /* If window start is unchanged, we can reuse the whole matrix
13193 as is, after adjusting glyph positions. No need to compute
13194 the window end again, since its offset from Z hasn't changed. */
13195 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13196 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13197 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13198 /* PT must not be in a partially visible line. */
13199 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13200 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13201 {
13202 /* Adjust positions in the glyph matrix. */
13203 if (delta || delta_bytes)
13204 {
13205 struct glyph_row *r1
13206 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13207 increment_matrix_positions (w->current_matrix,
13208 MATRIX_ROW_VPOS (r0, current_matrix),
13209 MATRIX_ROW_VPOS (r1, current_matrix),
13210 delta, delta_bytes);
13211 }
13212
13213 /* Set the cursor. */
13214 row = row_containing_pos (w, PT, r0, NULL, 0);
13215 if (row)
13216 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13217 else
13218 abort ();
13219 return 1;
13220 }
13221 }
13222
13223 /* Handle the case that changes are all below what is displayed in
13224 the window, and that PT is in the window. This shortcut cannot
13225 be taken if ZV is visible in the window, and text has been added
13226 there that is visible in the window. */
13227 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13228 /* ZV is not visible in the window, or there are no
13229 changes at ZV, actually. */
13230 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13231 || first_changed_charpos == last_changed_charpos))
13232 {
13233 struct glyph_row *r0;
13234
13235 /* Give up if PT is not in the window. Note that it already has
13236 been checked at the start of try_window_id that PT is not in
13237 front of the window start. */
13238 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13239 GIVE_UP (14);
13240
13241 /* If window start is unchanged, we can reuse the whole matrix
13242 as is, without changing glyph positions since no text has
13243 been added/removed in front of the window end. */
13244 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13245 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13246 /* PT must not be in a partially visible line. */
13247 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13248 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13249 {
13250 /* We have to compute the window end anew since text
13251 can have been added/removed after it. */
13252 w->window_end_pos
13253 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13254 w->window_end_bytepos
13255 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13256
13257 /* Set the cursor. */
13258 row = row_containing_pos (w, PT, r0, NULL, 0);
13259 if (row)
13260 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13261 else
13262 abort ();
13263 return 2;
13264 }
13265 }
13266
13267 /* Give up if window start is in the changed area.
13268
13269 The condition used to read
13270
13271 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13272
13273 but why that was tested escapes me at the moment. */
13274 if (CHARPOS (start) >= first_changed_charpos
13275 && CHARPOS (start) <= last_changed_charpos)
13276 GIVE_UP (15);
13277
13278 /* Check that window start agrees with the start of the first glyph
13279 row in its current matrix. Check this after we know the window
13280 start is not in changed text, otherwise positions would not be
13281 comparable. */
13282 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13283 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13284 GIVE_UP (16);
13285
13286 /* Give up if the window ends in strings. Overlay strings
13287 at the end are difficult to handle, so don't try. */
13288 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13289 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13290 GIVE_UP (20);
13291
13292 /* Compute the position at which we have to start displaying new
13293 lines. Some of the lines at the top of the window might be
13294 reusable because they are not displaying changed text. Find the
13295 last row in W's current matrix not affected by changes at the
13296 start of current_buffer. Value is null if changes start in the
13297 first line of window. */
13298 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13299 if (last_unchanged_at_beg_row)
13300 {
13301 /* Avoid starting to display in the moddle of a character, a TAB
13302 for instance. This is easier than to set up the iterator
13303 exactly, and it's not a frequent case, so the additional
13304 effort wouldn't really pay off. */
13305 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13306 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13307 && last_unchanged_at_beg_row > w->current_matrix->rows)
13308 --last_unchanged_at_beg_row;
13309
13310 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13311 GIVE_UP (17);
13312
13313 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13314 GIVE_UP (18);
13315 start_pos = it.current.pos;
13316
13317 /* Start displaying new lines in the desired matrix at the same
13318 vpos we would use in the current matrix, i.e. below
13319 last_unchanged_at_beg_row. */
13320 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13321 current_matrix);
13322 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13323 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13324
13325 xassert (it.hpos == 0 && it.current_x == 0);
13326 }
13327 else
13328 {
13329 /* There are no reusable lines at the start of the window.
13330 Start displaying in the first text line. */
13331 start_display (&it, w, start);
13332 it.vpos = it.first_vpos;
13333 start_pos = it.current.pos;
13334 }
13335
13336 /* Find the first row that is not affected by changes at the end of
13337 the buffer. Value will be null if there is no unchanged row, in
13338 which case we must redisplay to the end of the window. delta
13339 will be set to the value by which buffer positions beginning with
13340 first_unchanged_at_end_row have to be adjusted due to text
13341 changes. */
13342 first_unchanged_at_end_row
13343 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13344 IF_DEBUG (debug_delta = delta);
13345 IF_DEBUG (debug_delta_bytes = delta_bytes);
13346
13347 /* Set stop_pos to the buffer position up to which we will have to
13348 display new lines. If first_unchanged_at_end_row != NULL, this
13349 is the buffer position of the start of the line displayed in that
13350 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13351 that we don't stop at a buffer position. */
13352 stop_pos = 0;
13353 if (first_unchanged_at_end_row)
13354 {
13355 xassert (last_unchanged_at_beg_row == NULL
13356 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13357
13358 /* If this is a continuation line, move forward to the next one
13359 that isn't. Changes in lines above affect this line.
13360 Caution: this may move first_unchanged_at_end_row to a row
13361 not displaying text. */
13362 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13363 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13364 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13365 < it.last_visible_y))
13366 ++first_unchanged_at_end_row;
13367
13368 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13369 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13370 >= it.last_visible_y))
13371 first_unchanged_at_end_row = NULL;
13372 else
13373 {
13374 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13375 + delta);
13376 first_unchanged_at_end_vpos
13377 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13378 xassert (stop_pos >= Z - END_UNCHANGED);
13379 }
13380 }
13381 else if (last_unchanged_at_beg_row == NULL)
13382 GIVE_UP (19);
13383
13384
13385 #if GLYPH_DEBUG
13386
13387 /* Either there is no unchanged row at the end, or the one we have
13388 now displays text. This is a necessary condition for the window
13389 end pos calculation at the end of this function. */
13390 xassert (first_unchanged_at_end_row == NULL
13391 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13392
13393 debug_last_unchanged_at_beg_vpos
13394 = (last_unchanged_at_beg_row
13395 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13396 : -1);
13397 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13398
13399 #endif /* GLYPH_DEBUG != 0 */
13400
13401
13402 /* Display new lines. Set last_text_row to the last new line
13403 displayed which has text on it, i.e. might end up as being the
13404 line where the window_end_vpos is. */
13405 w->cursor.vpos = -1;
13406 last_text_row = NULL;
13407 overlay_arrow_seen = 0;
13408 while (it.current_y < it.last_visible_y
13409 && !fonts_changed_p
13410 && (first_unchanged_at_end_row == NULL
13411 || IT_CHARPOS (it) < stop_pos))
13412 {
13413 if (display_line (&it))
13414 last_text_row = it.glyph_row - 1;
13415 }
13416
13417 if (fonts_changed_p)
13418 return -1;
13419
13420
13421 /* Compute differences in buffer positions, y-positions etc. for
13422 lines reused at the bottom of the window. Compute what we can
13423 scroll. */
13424 if (first_unchanged_at_end_row
13425 /* No lines reused because we displayed everything up to the
13426 bottom of the window. */
13427 && it.current_y < it.last_visible_y)
13428 {
13429 dvpos = (it.vpos
13430 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13431 current_matrix));
13432 dy = it.current_y - first_unchanged_at_end_row->y;
13433 run.current_y = first_unchanged_at_end_row->y;
13434 run.desired_y = run.current_y + dy;
13435 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13436 }
13437 else
13438 {
13439 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13440 first_unchanged_at_end_row = NULL;
13441 }
13442 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13443
13444
13445 /* Find the cursor if not already found. We have to decide whether
13446 PT will appear on this window (it sometimes doesn't, but this is
13447 not a very frequent case.) This decision has to be made before
13448 the current matrix is altered. A value of cursor.vpos < 0 means
13449 that PT is either in one of the lines beginning at
13450 first_unchanged_at_end_row or below the window. Don't care for
13451 lines that might be displayed later at the window end; as
13452 mentioned, this is not a frequent case. */
13453 if (w->cursor.vpos < 0)
13454 {
13455 /* Cursor in unchanged rows at the top? */
13456 if (PT < CHARPOS (start_pos)
13457 && last_unchanged_at_beg_row)
13458 {
13459 row = row_containing_pos (w, PT,
13460 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13461 last_unchanged_at_beg_row + 1, 0);
13462 if (row)
13463 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13464 }
13465
13466 /* Start from first_unchanged_at_end_row looking for PT. */
13467 else if (first_unchanged_at_end_row)
13468 {
13469 row = row_containing_pos (w, PT - delta,
13470 first_unchanged_at_end_row, NULL, 0);
13471 if (row)
13472 set_cursor_from_row (w, row, w->current_matrix, delta,
13473 delta_bytes, dy, dvpos);
13474 }
13475
13476 /* Give up if cursor was not found. */
13477 if (w->cursor.vpos < 0)
13478 {
13479 clear_glyph_matrix (w->desired_matrix);
13480 return -1;
13481 }
13482 }
13483
13484 /* Don't let the cursor end in the scroll margins. */
13485 {
13486 int this_scroll_margin, cursor_height;
13487
13488 this_scroll_margin = max (0, scroll_margin);
13489 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13490 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13491 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13492
13493 if ((w->cursor.y < this_scroll_margin
13494 && CHARPOS (start) > BEGV)
13495 /* Old redisplay didn't take scroll margin into account at the bottom,
13496 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13497 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
13498 {
13499 w->cursor.vpos = -1;
13500 clear_glyph_matrix (w->desired_matrix);
13501 return -1;
13502 }
13503 }
13504
13505 /* Scroll the display. Do it before changing the current matrix so
13506 that xterm.c doesn't get confused about where the cursor glyph is
13507 found. */
13508 if (dy && run.height)
13509 {
13510 update_begin (f);
13511
13512 if (FRAME_WINDOW_P (f))
13513 {
13514 rif->update_window_begin_hook (w);
13515 rif->clear_window_mouse_face (w);
13516 rif->scroll_run_hook (w, &run);
13517 rif->update_window_end_hook (w, 0, 0);
13518 }
13519 else
13520 {
13521 /* Terminal frame. In this case, dvpos gives the number of
13522 lines to scroll by; dvpos < 0 means scroll up. */
13523 int first_unchanged_at_end_vpos
13524 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13525 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13526 int end = (WINDOW_TOP_EDGE_LINE (w)
13527 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13528 + window_internal_height (w));
13529
13530 /* Perform the operation on the screen. */
13531 if (dvpos > 0)
13532 {
13533 /* Scroll last_unchanged_at_beg_row to the end of the
13534 window down dvpos lines. */
13535 set_terminal_window (end);
13536
13537 /* On dumb terminals delete dvpos lines at the end
13538 before inserting dvpos empty lines. */
13539 if (!scroll_region_ok)
13540 ins_del_lines (end - dvpos, -dvpos);
13541
13542 /* Insert dvpos empty lines in front of
13543 last_unchanged_at_beg_row. */
13544 ins_del_lines (from, dvpos);
13545 }
13546 else if (dvpos < 0)
13547 {
13548 /* Scroll up last_unchanged_at_beg_vpos to the end of
13549 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13550 set_terminal_window (end);
13551
13552 /* Delete dvpos lines in front of
13553 last_unchanged_at_beg_vpos. ins_del_lines will set
13554 the cursor to the given vpos and emit |dvpos| delete
13555 line sequences. */
13556 ins_del_lines (from + dvpos, dvpos);
13557
13558 /* On a dumb terminal insert dvpos empty lines at the
13559 end. */
13560 if (!scroll_region_ok)
13561 ins_del_lines (end + dvpos, -dvpos);
13562 }
13563
13564 set_terminal_window (0);
13565 }
13566
13567 update_end (f);
13568 }
13569
13570 /* Shift reused rows of the current matrix to the right position.
13571 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13572 text. */
13573 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13574 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13575 if (dvpos < 0)
13576 {
13577 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13578 bottom_vpos, dvpos);
13579 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13580 bottom_vpos, 0);
13581 }
13582 else if (dvpos > 0)
13583 {
13584 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13585 bottom_vpos, dvpos);
13586 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13587 first_unchanged_at_end_vpos + dvpos, 0);
13588 }
13589
13590 /* For frame-based redisplay, make sure that current frame and window
13591 matrix are in sync with respect to glyph memory. */
13592 if (!FRAME_WINDOW_P (f))
13593 sync_frame_with_window_matrix_rows (w);
13594
13595 /* Adjust buffer positions in reused rows. */
13596 if (delta)
13597 increment_matrix_positions (current_matrix,
13598 first_unchanged_at_end_vpos + dvpos,
13599 bottom_vpos, delta, delta_bytes);
13600
13601 /* Adjust Y positions. */
13602 if (dy)
13603 shift_glyph_matrix (w, current_matrix,
13604 first_unchanged_at_end_vpos + dvpos,
13605 bottom_vpos, dy);
13606
13607 if (first_unchanged_at_end_row)
13608 first_unchanged_at_end_row += dvpos;
13609
13610 /* If scrolling up, there may be some lines to display at the end of
13611 the window. */
13612 last_text_row_at_end = NULL;
13613 if (dy < 0)
13614 {
13615 /* Scrolling up can leave for example a partially visible line
13616 at the end of the window to be redisplayed. */
13617 /* Set last_row to the glyph row in the current matrix where the
13618 window end line is found. It has been moved up or down in
13619 the matrix by dvpos. */
13620 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13621 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13622
13623 /* If last_row is the window end line, it should display text. */
13624 xassert (last_row->displays_text_p);
13625
13626 /* If window end line was partially visible before, begin
13627 displaying at that line. Otherwise begin displaying with the
13628 line following it. */
13629 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13630 {
13631 init_to_row_start (&it, w, last_row);
13632 it.vpos = last_vpos;
13633 it.current_y = last_row->y;
13634 }
13635 else
13636 {
13637 init_to_row_end (&it, w, last_row);
13638 it.vpos = 1 + last_vpos;
13639 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13640 ++last_row;
13641 }
13642
13643 /* We may start in a continuation line. If so, we have to
13644 get the right continuation_lines_width and current_x. */
13645 it.continuation_lines_width = last_row->continuation_lines_width;
13646 it.hpos = it.current_x = 0;
13647
13648 /* Display the rest of the lines at the window end. */
13649 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13650 while (it.current_y < it.last_visible_y
13651 && !fonts_changed_p)
13652 {
13653 /* Is it always sure that the display agrees with lines in
13654 the current matrix? I don't think so, so we mark rows
13655 displayed invalid in the current matrix by setting their
13656 enabled_p flag to zero. */
13657 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13658 if (display_line (&it))
13659 last_text_row_at_end = it.glyph_row - 1;
13660 }
13661 }
13662
13663 /* Update window_end_pos and window_end_vpos. */
13664 if (first_unchanged_at_end_row
13665 && first_unchanged_at_end_row->y < it.last_visible_y
13666 && !last_text_row_at_end)
13667 {
13668 /* Window end line if one of the preserved rows from the current
13669 matrix. Set row to the last row displaying text in current
13670 matrix starting at first_unchanged_at_end_row, after
13671 scrolling. */
13672 xassert (first_unchanged_at_end_row->displays_text_p);
13673 row = find_last_row_displaying_text (w->current_matrix, &it,
13674 first_unchanged_at_end_row);
13675 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13676
13677 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13678 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13679 w->window_end_vpos
13680 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13681 xassert (w->window_end_bytepos >= 0);
13682 IF_DEBUG (debug_method_add (w, "A"));
13683 }
13684 else if (last_text_row_at_end)
13685 {
13686 w->window_end_pos
13687 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13688 w->window_end_bytepos
13689 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13690 w->window_end_vpos
13691 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13692 xassert (w->window_end_bytepos >= 0);
13693 IF_DEBUG (debug_method_add (w, "B"));
13694 }
13695 else if (last_text_row)
13696 {
13697 /* We have displayed either to the end of the window or at the
13698 end of the window, i.e. the last row with text is to be found
13699 in the desired matrix. */
13700 w->window_end_pos
13701 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13702 w->window_end_bytepos
13703 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13704 w->window_end_vpos
13705 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13706 xassert (w->window_end_bytepos >= 0);
13707 }
13708 else if (first_unchanged_at_end_row == NULL
13709 && last_text_row == NULL
13710 && last_text_row_at_end == NULL)
13711 {
13712 /* Displayed to end of window, but no line containing text was
13713 displayed. Lines were deleted at the end of the window. */
13714 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13715 int vpos = XFASTINT (w->window_end_vpos);
13716 struct glyph_row *current_row = current_matrix->rows + vpos;
13717 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13718
13719 for (row = NULL;
13720 row == NULL && vpos >= first_vpos;
13721 --vpos, --current_row, --desired_row)
13722 {
13723 if (desired_row->enabled_p)
13724 {
13725 if (desired_row->displays_text_p)
13726 row = desired_row;
13727 }
13728 else if (current_row->displays_text_p)
13729 row = current_row;
13730 }
13731
13732 xassert (row != NULL);
13733 w->window_end_vpos = make_number (vpos + 1);
13734 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13735 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13736 xassert (w->window_end_bytepos >= 0);
13737 IF_DEBUG (debug_method_add (w, "C"));
13738 }
13739 else
13740 abort ();
13741
13742 #if 0 /* This leads to problems, for instance when the cursor is
13743 at ZV, and the cursor line displays no text. */
13744 /* Disable rows below what's displayed in the window. This makes
13745 debugging easier. */
13746 enable_glyph_matrix_rows (current_matrix,
13747 XFASTINT (w->window_end_vpos) + 1,
13748 bottom_vpos, 0);
13749 #endif
13750
13751 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13752 debug_end_vpos = XFASTINT (w->window_end_vpos));
13753
13754 /* Record that display has not been completed. */
13755 w->window_end_valid = Qnil;
13756 w->desired_matrix->no_scrolling_p = 1;
13757 return 3;
13758
13759 #undef GIVE_UP
13760 }
13761
13762
13763 \f
13764 /***********************************************************************
13765 More debugging support
13766 ***********************************************************************/
13767
13768 #if GLYPH_DEBUG
13769
13770 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13771 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13772 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13773
13774
13775 /* Dump the contents of glyph matrix MATRIX on stderr.
13776
13777 GLYPHS 0 means don't show glyph contents.
13778 GLYPHS 1 means show glyphs in short form
13779 GLYPHS > 1 means show glyphs in long form. */
13780
13781 void
13782 dump_glyph_matrix (matrix, glyphs)
13783 struct glyph_matrix *matrix;
13784 int glyphs;
13785 {
13786 int i;
13787 for (i = 0; i < matrix->nrows; ++i)
13788 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13789 }
13790
13791
13792 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13793 the glyph row and area where the glyph comes from. */
13794
13795 void
13796 dump_glyph (row, glyph, area)
13797 struct glyph_row *row;
13798 struct glyph *glyph;
13799 int area;
13800 {
13801 if (glyph->type == CHAR_GLYPH)
13802 {
13803 fprintf (stderr,
13804 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13805 glyph - row->glyphs[TEXT_AREA],
13806 'C',
13807 glyph->charpos,
13808 (BUFFERP (glyph->object)
13809 ? 'B'
13810 : (STRINGP (glyph->object)
13811 ? 'S'
13812 : '-')),
13813 glyph->pixel_width,
13814 glyph->u.ch,
13815 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13816 ? glyph->u.ch
13817 : '.'),
13818 glyph->face_id,
13819 glyph->left_box_line_p,
13820 glyph->right_box_line_p);
13821 }
13822 else if (glyph->type == STRETCH_GLYPH)
13823 {
13824 fprintf (stderr,
13825 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13826 glyph - row->glyphs[TEXT_AREA],
13827 'S',
13828 glyph->charpos,
13829 (BUFFERP (glyph->object)
13830 ? 'B'
13831 : (STRINGP (glyph->object)
13832 ? 'S'
13833 : '-')),
13834 glyph->pixel_width,
13835 0,
13836 '.',
13837 glyph->face_id,
13838 glyph->left_box_line_p,
13839 glyph->right_box_line_p);
13840 }
13841 else if (glyph->type == IMAGE_GLYPH)
13842 {
13843 fprintf (stderr,
13844 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13845 glyph - row->glyphs[TEXT_AREA],
13846 'I',
13847 glyph->charpos,
13848 (BUFFERP (glyph->object)
13849 ? 'B'
13850 : (STRINGP (glyph->object)
13851 ? 'S'
13852 : '-')),
13853 glyph->pixel_width,
13854 glyph->u.img_id,
13855 '.',
13856 glyph->face_id,
13857 glyph->left_box_line_p,
13858 glyph->right_box_line_p);
13859 }
13860 }
13861
13862
13863 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13864 GLYPHS 0 means don't show glyph contents.
13865 GLYPHS 1 means show glyphs in short form
13866 GLYPHS > 1 means show glyphs in long form. */
13867
13868 void
13869 dump_glyph_row (row, vpos, glyphs)
13870 struct glyph_row *row;
13871 int vpos, glyphs;
13872 {
13873 if (glyphs != 1)
13874 {
13875 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13876 fprintf (stderr, "=======================================================================\n");
13877
13878 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13879 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13880 vpos,
13881 MATRIX_ROW_START_CHARPOS (row),
13882 MATRIX_ROW_END_CHARPOS (row),
13883 row->used[TEXT_AREA],
13884 row->contains_overlapping_glyphs_p,
13885 row->enabled_p,
13886 row->truncated_on_left_p,
13887 row->truncated_on_right_p,
13888 row->overlay_arrow_p,
13889 row->continued_p,
13890 MATRIX_ROW_CONTINUATION_LINE_P (row),
13891 row->displays_text_p,
13892 row->ends_at_zv_p,
13893 row->fill_line_p,
13894 row->ends_in_middle_of_char_p,
13895 row->starts_in_middle_of_char_p,
13896 row->mouse_face_p,
13897 row->x,
13898 row->y,
13899 row->pixel_width,
13900 row->height,
13901 row->visible_height,
13902 row->ascent,
13903 row->phys_ascent);
13904 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13905 row->end.overlay_string_index,
13906 row->continuation_lines_width);
13907 fprintf (stderr, "%9d %5d\n",
13908 CHARPOS (row->start.string_pos),
13909 CHARPOS (row->end.string_pos));
13910 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13911 row->end.dpvec_index);
13912 }
13913
13914 if (glyphs > 1)
13915 {
13916 int area;
13917
13918 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13919 {
13920 struct glyph *glyph = row->glyphs[area];
13921 struct glyph *glyph_end = glyph + row->used[area];
13922
13923 /* Glyph for a line end in text. */
13924 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13925 ++glyph_end;
13926
13927 if (glyph < glyph_end)
13928 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13929
13930 for (; glyph < glyph_end; ++glyph)
13931 dump_glyph (row, glyph, area);
13932 }
13933 }
13934 else if (glyphs == 1)
13935 {
13936 int area;
13937
13938 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13939 {
13940 char *s = (char *) alloca (row->used[area] + 1);
13941 int i;
13942
13943 for (i = 0; i < row->used[area]; ++i)
13944 {
13945 struct glyph *glyph = row->glyphs[area] + i;
13946 if (glyph->type == CHAR_GLYPH
13947 && glyph->u.ch < 0x80
13948 && glyph->u.ch >= ' ')
13949 s[i] = glyph->u.ch;
13950 else
13951 s[i] = '.';
13952 }
13953
13954 s[i] = '\0';
13955 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13956 }
13957 }
13958 }
13959
13960
13961 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13962 Sdump_glyph_matrix, 0, 1, "p",
13963 doc: /* Dump the current matrix of the selected window to stderr.
13964 Shows contents of glyph row structures. With non-nil
13965 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13966 glyphs in short form, otherwise show glyphs in long form. */)
13967 (glyphs)
13968 Lisp_Object glyphs;
13969 {
13970 struct window *w = XWINDOW (selected_window);
13971 struct buffer *buffer = XBUFFER (w->buffer);
13972
13973 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13974 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13975 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13976 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13977 fprintf (stderr, "=============================================\n");
13978 dump_glyph_matrix (w->current_matrix,
13979 NILP (glyphs) ? 0 : XINT (glyphs));
13980 return Qnil;
13981 }
13982
13983
13984 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13985 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13986 ()
13987 {
13988 struct frame *f = XFRAME (selected_frame);
13989 dump_glyph_matrix (f->current_matrix, 1);
13990 return Qnil;
13991 }
13992
13993
13994 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13995 doc: /* Dump glyph row ROW to stderr.
13996 GLYPH 0 means don't dump glyphs.
13997 GLYPH 1 means dump glyphs in short form.
13998 GLYPH > 1 or omitted means dump glyphs in long form. */)
13999 (row, glyphs)
14000 Lisp_Object row, glyphs;
14001 {
14002 struct glyph_matrix *matrix;
14003 int vpos;
14004
14005 CHECK_NUMBER (row);
14006 matrix = XWINDOW (selected_window)->current_matrix;
14007 vpos = XINT (row);
14008 if (vpos >= 0 && vpos < matrix->nrows)
14009 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14010 vpos,
14011 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14012 return Qnil;
14013 }
14014
14015
14016 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14017 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14018 GLYPH 0 means don't dump glyphs.
14019 GLYPH 1 means dump glyphs in short form.
14020 GLYPH > 1 or omitted means dump glyphs in long form. */)
14021 (row, glyphs)
14022 Lisp_Object row, glyphs;
14023 {
14024 struct frame *sf = SELECTED_FRAME ();
14025 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14026 int vpos;
14027
14028 CHECK_NUMBER (row);
14029 vpos = XINT (row);
14030 if (vpos >= 0 && vpos < m->nrows)
14031 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14032 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14033 return Qnil;
14034 }
14035
14036
14037 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14038 doc: /* Toggle tracing of redisplay.
14039 With ARG, turn tracing on if and only if ARG is positive. */)
14040 (arg)
14041 Lisp_Object arg;
14042 {
14043 if (NILP (arg))
14044 trace_redisplay_p = !trace_redisplay_p;
14045 else
14046 {
14047 arg = Fprefix_numeric_value (arg);
14048 trace_redisplay_p = XINT (arg) > 0;
14049 }
14050
14051 return Qnil;
14052 }
14053
14054
14055 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14056 doc: /* Like `format', but print result to stderr.
14057 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14058 (nargs, args)
14059 int nargs;
14060 Lisp_Object *args;
14061 {
14062 Lisp_Object s = Fformat (nargs, args);
14063 fprintf (stderr, "%s", SDATA (s));
14064 return Qnil;
14065 }
14066
14067 #endif /* GLYPH_DEBUG */
14068
14069
14070 \f
14071 /***********************************************************************
14072 Building Desired Matrix Rows
14073 ***********************************************************************/
14074
14075 /* Return a temporary glyph row holding the glyphs of an overlay
14076 arrow. Only used for non-window-redisplay windows. */
14077
14078 static struct glyph_row *
14079 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14080 struct window *w;
14081 Lisp_Object overlay_arrow_string;
14082 {
14083 struct frame *f = XFRAME (WINDOW_FRAME (w));
14084 struct buffer *buffer = XBUFFER (w->buffer);
14085 struct buffer *old = current_buffer;
14086 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14087 int arrow_len = SCHARS (overlay_arrow_string);
14088 const unsigned char *arrow_end = arrow_string + arrow_len;
14089 const unsigned char *p;
14090 struct it it;
14091 int multibyte_p;
14092 int n_glyphs_before;
14093
14094 set_buffer_temp (buffer);
14095 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14096 it.glyph_row->used[TEXT_AREA] = 0;
14097 SET_TEXT_POS (it.position, 0, 0);
14098
14099 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14100 p = arrow_string;
14101 while (p < arrow_end)
14102 {
14103 Lisp_Object face, ilisp;
14104
14105 /* Get the next character. */
14106 if (multibyte_p)
14107 it.c = string_char_and_length (p, arrow_len, &it.len);
14108 else
14109 it.c = *p, it.len = 1;
14110 p += it.len;
14111
14112 /* Get its face. */
14113 ilisp = make_number (p - arrow_string);
14114 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14115 it.face_id = compute_char_face (f, it.c, face);
14116
14117 /* Compute its width, get its glyphs. */
14118 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14119 SET_TEXT_POS (it.position, -1, -1);
14120 PRODUCE_GLYPHS (&it);
14121
14122 /* If this character doesn't fit any more in the line, we have
14123 to remove some glyphs. */
14124 if (it.current_x > it.last_visible_x)
14125 {
14126 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14127 break;
14128 }
14129 }
14130
14131 set_buffer_temp (old);
14132 return it.glyph_row;
14133 }
14134
14135
14136 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14137 glyphs are only inserted for terminal frames since we can't really
14138 win with truncation glyphs when partially visible glyphs are
14139 involved. Which glyphs to insert is determined by
14140 produce_special_glyphs. */
14141
14142 static void
14143 insert_left_trunc_glyphs (it)
14144 struct it *it;
14145 {
14146 struct it truncate_it;
14147 struct glyph *from, *end, *to, *toend;
14148
14149 xassert (!FRAME_WINDOW_P (it->f));
14150
14151 /* Get the truncation glyphs. */
14152 truncate_it = *it;
14153 truncate_it.current_x = 0;
14154 truncate_it.face_id = DEFAULT_FACE_ID;
14155 truncate_it.glyph_row = &scratch_glyph_row;
14156 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14157 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14158 truncate_it.object = make_number (0);
14159 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14160
14161 /* Overwrite glyphs from IT with truncation glyphs. */
14162 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14163 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14164 to = it->glyph_row->glyphs[TEXT_AREA];
14165 toend = to + it->glyph_row->used[TEXT_AREA];
14166
14167 while (from < end)
14168 *to++ = *from++;
14169
14170 /* There may be padding glyphs left over. Overwrite them too. */
14171 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14172 {
14173 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14174 while (from < end)
14175 *to++ = *from++;
14176 }
14177
14178 if (to > toend)
14179 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14180 }
14181
14182
14183 /* Compute the pixel height and width of IT->glyph_row.
14184
14185 Most of the time, ascent and height of a display line will be equal
14186 to the max_ascent and max_height values of the display iterator
14187 structure. This is not the case if
14188
14189 1. We hit ZV without displaying anything. In this case, max_ascent
14190 and max_height will be zero.
14191
14192 2. We have some glyphs that don't contribute to the line height.
14193 (The glyph row flag contributes_to_line_height_p is for future
14194 pixmap extensions).
14195
14196 The first case is easily covered by using default values because in
14197 these cases, the line height does not really matter, except that it
14198 must not be zero. */
14199
14200 static void
14201 compute_line_metrics (it)
14202 struct it *it;
14203 {
14204 struct glyph_row *row = it->glyph_row;
14205 int area, i;
14206
14207 if (FRAME_WINDOW_P (it->f))
14208 {
14209 int i, min_y, max_y;
14210
14211 /* The line may consist of one space only, that was added to
14212 place the cursor on it. If so, the row's height hasn't been
14213 computed yet. */
14214 if (row->height == 0)
14215 {
14216 if (it->max_ascent + it->max_descent == 0)
14217 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14218 row->ascent = it->max_ascent;
14219 row->height = it->max_ascent + it->max_descent;
14220 row->phys_ascent = it->max_phys_ascent;
14221 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14222 }
14223
14224 /* Compute the width of this line. */
14225 row->pixel_width = row->x;
14226 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14227 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14228
14229 xassert (row->pixel_width >= 0);
14230 xassert (row->ascent >= 0 && row->height > 0);
14231
14232 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14233 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14234
14235 /* If first line's physical ascent is larger than its logical
14236 ascent, use the physical ascent, and make the row taller.
14237 This makes accented characters fully visible. */
14238 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14239 && row->phys_ascent > row->ascent)
14240 {
14241 row->height += row->phys_ascent - row->ascent;
14242 row->ascent = row->phys_ascent;
14243 }
14244
14245 /* Compute how much of the line is visible. */
14246 row->visible_height = row->height;
14247
14248 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14249 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14250
14251 if (row->y < min_y)
14252 row->visible_height -= min_y - row->y;
14253 if (row->y + row->height > max_y)
14254 row->visible_height -= row->y + row->height - max_y;
14255 }
14256 else
14257 {
14258 row->pixel_width = row->used[TEXT_AREA];
14259 if (row->continued_p)
14260 row->pixel_width -= it->continuation_pixel_width;
14261 else if (row->truncated_on_right_p)
14262 row->pixel_width -= it->truncation_pixel_width;
14263 row->ascent = row->phys_ascent = 0;
14264 row->height = row->phys_height = row->visible_height = 1;
14265 }
14266
14267 /* Compute a hash code for this row. */
14268 row->hash = 0;
14269 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14270 for (i = 0; i < row->used[area]; ++i)
14271 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14272 + row->glyphs[area][i].u.val
14273 + row->glyphs[area][i].face_id
14274 + row->glyphs[area][i].padding_p
14275 + (row->glyphs[area][i].type << 2));
14276
14277 it->max_ascent = it->max_descent = 0;
14278 it->max_phys_ascent = it->max_phys_descent = 0;
14279 }
14280
14281
14282 /* Append one space to the glyph row of iterator IT if doing a
14283 window-based redisplay. The space has the same face as
14284 IT->face_id. Value is non-zero if a space was added.
14285
14286 This function is called to make sure that there is always one glyph
14287 at the end of a glyph row that the cursor can be set on under
14288 window-systems. (If there weren't such a glyph we would not know
14289 how wide and tall a box cursor should be displayed).
14290
14291 At the same time this space let's a nicely handle clearing to the
14292 end of the line if the row ends in italic text. */
14293
14294 static int
14295 append_space_for_newline (it, default_face_p)
14296 struct it *it;
14297 int default_face_p;
14298 {
14299 if (FRAME_WINDOW_P (it->f))
14300 {
14301 int n = it->glyph_row->used[TEXT_AREA];
14302
14303 if (it->glyph_row->glyphs[TEXT_AREA] + n
14304 < it->glyph_row->glyphs[1 + TEXT_AREA])
14305 {
14306 /* Save some values that must not be changed.
14307 Must save IT->c and IT->len because otherwise
14308 ITERATOR_AT_END_P wouldn't work anymore after
14309 append_space_for_newline has been called. */
14310 enum display_element_type saved_what = it->what;
14311 int saved_c = it->c, saved_len = it->len;
14312 int saved_x = it->current_x;
14313 int saved_face_id = it->face_id;
14314 struct text_pos saved_pos;
14315 Lisp_Object saved_object;
14316 struct face *face;
14317
14318 saved_object = it->object;
14319 saved_pos = it->position;
14320
14321 it->what = IT_CHARACTER;
14322 bzero (&it->position, sizeof it->position);
14323 it->object = make_number (0);
14324 it->c = ' ';
14325 it->len = 1;
14326
14327 if (default_face_p)
14328 it->face_id = DEFAULT_FACE_ID;
14329 else if (it->face_before_selective_p)
14330 it->face_id = it->saved_face_id;
14331 face = FACE_FROM_ID (it->f, it->face_id);
14332 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14333
14334 PRODUCE_GLYPHS (it);
14335
14336 it->override_ascent = -1;
14337 it->constrain_row_ascent_descent_p = 0;
14338 it->current_x = saved_x;
14339 it->object = saved_object;
14340 it->position = saved_pos;
14341 it->what = saved_what;
14342 it->face_id = saved_face_id;
14343 it->len = saved_len;
14344 it->c = saved_c;
14345 return 1;
14346 }
14347 }
14348
14349 return 0;
14350 }
14351
14352
14353 /* Extend the face of the last glyph in the text area of IT->glyph_row
14354 to the end of the display line. Called from display_line.
14355 If the glyph row is empty, add a space glyph to it so that we
14356 know the face to draw. Set the glyph row flag fill_line_p. */
14357
14358 static void
14359 extend_face_to_end_of_line (it)
14360 struct it *it;
14361 {
14362 struct face *face;
14363 struct frame *f = it->f;
14364
14365 /* If line is already filled, do nothing. */
14366 if (it->current_x >= it->last_visible_x)
14367 return;
14368
14369 /* Face extension extends the background and box of IT->face_id
14370 to the end of the line. If the background equals the background
14371 of the frame, we don't have to do anything. */
14372 if (it->face_before_selective_p)
14373 face = FACE_FROM_ID (it->f, it->saved_face_id);
14374 else
14375 face = FACE_FROM_ID (f, it->face_id);
14376
14377 if (FRAME_WINDOW_P (f)
14378 && face->box == FACE_NO_BOX
14379 && face->background == FRAME_BACKGROUND_PIXEL (f)
14380 && !face->stipple)
14381 return;
14382
14383 /* Set the glyph row flag indicating that the face of the last glyph
14384 in the text area has to be drawn to the end of the text area. */
14385 it->glyph_row->fill_line_p = 1;
14386
14387 /* If current character of IT is not ASCII, make sure we have the
14388 ASCII face. This will be automatically undone the next time
14389 get_next_display_element returns a multibyte character. Note
14390 that the character will always be single byte in unibyte text. */
14391 if (!SINGLE_BYTE_CHAR_P (it->c))
14392 {
14393 it->face_id = FACE_FOR_CHAR (f, face, 0);
14394 }
14395
14396 if (FRAME_WINDOW_P (f))
14397 {
14398 /* If the row is empty, add a space with the current face of IT,
14399 so that we know which face to draw. */
14400 if (it->glyph_row->used[TEXT_AREA] == 0)
14401 {
14402 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14403 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14404 it->glyph_row->used[TEXT_AREA] = 1;
14405 }
14406 }
14407 else
14408 {
14409 /* Save some values that must not be changed. */
14410 int saved_x = it->current_x;
14411 struct text_pos saved_pos;
14412 Lisp_Object saved_object;
14413 enum display_element_type saved_what = it->what;
14414 int saved_face_id = it->face_id;
14415
14416 saved_object = it->object;
14417 saved_pos = it->position;
14418
14419 it->what = IT_CHARACTER;
14420 bzero (&it->position, sizeof it->position);
14421 it->object = make_number (0);
14422 it->c = ' ';
14423 it->len = 1;
14424 it->face_id = face->id;
14425
14426 PRODUCE_GLYPHS (it);
14427
14428 while (it->current_x <= it->last_visible_x)
14429 PRODUCE_GLYPHS (it);
14430
14431 /* Don't count these blanks really. It would let us insert a left
14432 truncation glyph below and make us set the cursor on them, maybe. */
14433 it->current_x = saved_x;
14434 it->object = saved_object;
14435 it->position = saved_pos;
14436 it->what = saved_what;
14437 it->face_id = saved_face_id;
14438 }
14439 }
14440
14441
14442 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14443 trailing whitespace. */
14444
14445 static int
14446 trailing_whitespace_p (charpos)
14447 int charpos;
14448 {
14449 int bytepos = CHAR_TO_BYTE (charpos);
14450 int c = 0;
14451
14452 while (bytepos < ZV_BYTE
14453 && (c = FETCH_CHAR (bytepos),
14454 c == ' ' || c == '\t'))
14455 ++bytepos;
14456
14457 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14458 {
14459 if (bytepos != PT_BYTE)
14460 return 1;
14461 }
14462 return 0;
14463 }
14464
14465
14466 /* Highlight trailing whitespace, if any, in ROW. */
14467
14468 void
14469 highlight_trailing_whitespace (f, row)
14470 struct frame *f;
14471 struct glyph_row *row;
14472 {
14473 int used = row->used[TEXT_AREA];
14474
14475 if (used)
14476 {
14477 struct glyph *start = row->glyphs[TEXT_AREA];
14478 struct glyph *glyph = start + used - 1;
14479
14480 /* Skip over glyphs inserted to display the cursor at the
14481 end of a line, for extending the face of the last glyph
14482 to the end of the line on terminals, and for truncation
14483 and continuation glyphs. */
14484 while (glyph >= start
14485 && glyph->type == CHAR_GLYPH
14486 && INTEGERP (glyph->object))
14487 --glyph;
14488
14489 /* If last glyph is a space or stretch, and it's trailing
14490 whitespace, set the face of all trailing whitespace glyphs in
14491 IT->glyph_row to `trailing-whitespace'. */
14492 if (glyph >= start
14493 && BUFFERP (glyph->object)
14494 && (glyph->type == STRETCH_GLYPH
14495 || (glyph->type == CHAR_GLYPH
14496 && glyph->u.ch == ' '))
14497 && trailing_whitespace_p (glyph->charpos))
14498 {
14499 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14500
14501 while (glyph >= start
14502 && BUFFERP (glyph->object)
14503 && (glyph->type == STRETCH_GLYPH
14504 || (glyph->type == CHAR_GLYPH
14505 && glyph->u.ch == ' ')))
14506 (glyph--)->face_id = face_id;
14507 }
14508 }
14509 }
14510
14511
14512 /* Value is non-zero if glyph row ROW in window W should be
14513 used to hold the cursor. */
14514
14515 static int
14516 cursor_row_p (w, row)
14517 struct window *w;
14518 struct glyph_row *row;
14519 {
14520 int cursor_row_p = 1;
14521
14522 if (PT == MATRIX_ROW_END_CHARPOS (row))
14523 {
14524 /* If the row ends with a newline from a string, we don't want
14525 the cursor there (if the row is continued it doesn't end in a
14526 newline). */
14527 if (CHARPOS (row->end.string_pos) >= 0
14528 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14529 cursor_row_p = row->continued_p;
14530
14531 /* If the row ends at ZV, display the cursor at the end of that
14532 row instead of at the start of the row below. */
14533 else if (row->ends_at_zv_p)
14534 cursor_row_p = 1;
14535 else
14536 cursor_row_p = 0;
14537 }
14538
14539 return cursor_row_p;
14540 }
14541
14542
14543 /* Construct the glyph row IT->glyph_row in the desired matrix of
14544 IT->w from text at the current position of IT. See dispextern.h
14545 for an overview of struct it. Value is non-zero if
14546 IT->glyph_row displays text, as opposed to a line displaying ZV
14547 only. */
14548
14549 static int
14550 display_line (it)
14551 struct it *it;
14552 {
14553 struct glyph_row *row = it->glyph_row;
14554 int overlay_arrow_bitmap;
14555 Lisp_Object overlay_arrow_string;
14556
14557 /* We always start displaying at hpos zero even if hscrolled. */
14558 xassert (it->hpos == 0 && it->current_x == 0);
14559
14560 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14561 >= it->w->desired_matrix->nrows)
14562 {
14563 it->w->nrows_scale_factor++;
14564 fonts_changed_p = 1;
14565 return 0;
14566 }
14567
14568 /* Is IT->w showing the region? */
14569 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14570
14571 /* Clear the result glyph row and enable it. */
14572 prepare_desired_row (row);
14573
14574 row->y = it->current_y;
14575 row->start = it->start;
14576 row->continuation_lines_width = it->continuation_lines_width;
14577 row->displays_text_p = 1;
14578 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14579 it->starts_in_middle_of_char_p = 0;
14580
14581 /* Arrange the overlays nicely for our purposes. Usually, we call
14582 display_line on only one line at a time, in which case this
14583 can't really hurt too much, or we call it on lines which appear
14584 one after another in the buffer, in which case all calls to
14585 recenter_overlay_lists but the first will be pretty cheap. */
14586 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14587
14588 /* Move over display elements that are not visible because we are
14589 hscrolled. This may stop at an x-position < IT->first_visible_x
14590 if the first glyph is partially visible or if we hit a line end. */
14591 if (it->current_x < it->first_visible_x)
14592 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14593 MOVE_TO_POS | MOVE_TO_X);
14594
14595 /* Get the initial row height. This is either the height of the
14596 text hscrolled, if there is any, or zero. */
14597 row->ascent = it->max_ascent;
14598 row->height = it->max_ascent + it->max_descent;
14599 row->phys_ascent = it->max_phys_ascent;
14600 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14601
14602 /* Loop generating characters. The loop is left with IT on the next
14603 character to display. */
14604 while (1)
14605 {
14606 int n_glyphs_before, hpos_before, x_before;
14607 int x, i, nglyphs;
14608 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14609
14610 /* Retrieve the next thing to display. Value is zero if end of
14611 buffer reached. */
14612 if (!get_next_display_element (it))
14613 {
14614 /* Maybe add a space at the end of this line that is used to
14615 display the cursor there under X. Set the charpos of the
14616 first glyph of blank lines not corresponding to any text
14617 to -1. */
14618 #ifdef HAVE_WINDOW_SYSTEM
14619 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14620 row->exact_window_width_line_p = 1;
14621 else
14622 #endif /* HAVE_WINDOW_SYSTEM */
14623 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14624 || row->used[TEXT_AREA] == 0)
14625 {
14626 row->glyphs[TEXT_AREA]->charpos = -1;
14627 row->displays_text_p = 0;
14628
14629 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14630 && (!MINI_WINDOW_P (it->w)
14631 || (minibuf_level && EQ (it->window, minibuf_window))))
14632 row->indicate_empty_line_p = 1;
14633 }
14634
14635 it->continuation_lines_width = 0;
14636 row->ends_at_zv_p = 1;
14637 break;
14638 }
14639
14640 /* Now, get the metrics of what we want to display. This also
14641 generates glyphs in `row' (which is IT->glyph_row). */
14642 n_glyphs_before = row->used[TEXT_AREA];
14643 x = it->current_x;
14644
14645 /* Remember the line height so far in case the next element doesn't
14646 fit on the line. */
14647 if (!it->truncate_lines_p)
14648 {
14649 ascent = it->max_ascent;
14650 descent = it->max_descent;
14651 phys_ascent = it->max_phys_ascent;
14652 phys_descent = it->max_phys_descent;
14653 }
14654
14655 PRODUCE_GLYPHS (it);
14656
14657 /* If this display element was in marginal areas, continue with
14658 the next one. */
14659 if (it->area != TEXT_AREA)
14660 {
14661 row->ascent = max (row->ascent, it->max_ascent);
14662 row->height = max (row->height, it->max_ascent + it->max_descent);
14663 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14664 row->phys_height = max (row->phys_height,
14665 it->max_phys_ascent + it->max_phys_descent);
14666 set_iterator_to_next (it, 1);
14667 continue;
14668 }
14669
14670 /* Does the display element fit on the line? If we truncate
14671 lines, we should draw past the right edge of the window. If
14672 we don't truncate, we want to stop so that we can display the
14673 continuation glyph before the right margin. If lines are
14674 continued, there are two possible strategies for characters
14675 resulting in more than 1 glyph (e.g. tabs): Display as many
14676 glyphs as possible in this line and leave the rest for the
14677 continuation line, or display the whole element in the next
14678 line. Original redisplay did the former, so we do it also. */
14679 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14680 hpos_before = it->hpos;
14681 x_before = x;
14682
14683 if (/* Not a newline. */
14684 nglyphs > 0
14685 /* Glyphs produced fit entirely in the line. */
14686 && it->current_x < it->last_visible_x)
14687 {
14688 it->hpos += nglyphs;
14689 row->ascent = max (row->ascent, it->max_ascent);
14690 row->height = max (row->height, it->max_ascent + it->max_descent);
14691 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14692 row->phys_height = max (row->phys_height,
14693 it->max_phys_ascent + it->max_phys_descent);
14694 if (it->current_x - it->pixel_width < it->first_visible_x)
14695 row->x = x - it->first_visible_x;
14696 }
14697 else
14698 {
14699 int new_x;
14700 struct glyph *glyph;
14701
14702 for (i = 0; i < nglyphs; ++i, x = new_x)
14703 {
14704 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14705 new_x = x + glyph->pixel_width;
14706
14707 if (/* Lines are continued. */
14708 !it->truncate_lines_p
14709 && (/* Glyph doesn't fit on the line. */
14710 new_x > it->last_visible_x
14711 /* Or it fits exactly on a window system frame. */
14712 || (new_x == it->last_visible_x
14713 && FRAME_WINDOW_P (it->f))))
14714 {
14715 /* End of a continued line. */
14716
14717 if (it->hpos == 0
14718 || (new_x == it->last_visible_x
14719 && FRAME_WINDOW_P (it->f)))
14720 {
14721 /* Current glyph is the only one on the line or
14722 fits exactly on the line. We must continue
14723 the line because we can't draw the cursor
14724 after the glyph. */
14725 row->continued_p = 1;
14726 it->current_x = new_x;
14727 it->continuation_lines_width += new_x;
14728 ++it->hpos;
14729 if (i == nglyphs - 1)
14730 {
14731 set_iterator_to_next (it, 1);
14732 #ifdef HAVE_WINDOW_SYSTEM
14733 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14734 {
14735 if (!get_next_display_element (it))
14736 {
14737 row->exact_window_width_line_p = 1;
14738 it->continuation_lines_width = 0;
14739 row->continued_p = 0;
14740 row->ends_at_zv_p = 1;
14741 }
14742 else if (ITERATOR_AT_END_OF_LINE_P (it))
14743 {
14744 row->continued_p = 0;
14745 row->exact_window_width_line_p = 1;
14746 }
14747 }
14748 #endif /* HAVE_WINDOW_SYSTEM */
14749 }
14750 }
14751 else if (CHAR_GLYPH_PADDING_P (*glyph)
14752 && !FRAME_WINDOW_P (it->f))
14753 {
14754 /* A padding glyph that doesn't fit on this line.
14755 This means the whole character doesn't fit
14756 on the line. */
14757 row->used[TEXT_AREA] = n_glyphs_before;
14758
14759 /* Fill the rest of the row with continuation
14760 glyphs like in 20.x. */
14761 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14762 < row->glyphs[1 + TEXT_AREA])
14763 produce_special_glyphs (it, IT_CONTINUATION);
14764
14765 row->continued_p = 1;
14766 it->current_x = x_before;
14767 it->continuation_lines_width += x_before;
14768
14769 /* Restore the height to what it was before the
14770 element not fitting on the line. */
14771 it->max_ascent = ascent;
14772 it->max_descent = descent;
14773 it->max_phys_ascent = phys_ascent;
14774 it->max_phys_descent = phys_descent;
14775 }
14776 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14777 {
14778 /* A TAB that extends past the right edge of the
14779 window. This produces a single glyph on
14780 window system frames. We leave the glyph in
14781 this row and let it fill the row, but don't
14782 consume the TAB. */
14783 it->continuation_lines_width += it->last_visible_x;
14784 row->ends_in_middle_of_char_p = 1;
14785 row->continued_p = 1;
14786 glyph->pixel_width = it->last_visible_x - x;
14787 it->starts_in_middle_of_char_p = 1;
14788 }
14789 else
14790 {
14791 /* Something other than a TAB that draws past
14792 the right edge of the window. Restore
14793 positions to values before the element. */
14794 row->used[TEXT_AREA] = n_glyphs_before + i;
14795
14796 /* Display continuation glyphs. */
14797 if (!FRAME_WINDOW_P (it->f))
14798 produce_special_glyphs (it, IT_CONTINUATION);
14799 row->continued_p = 1;
14800
14801 it->continuation_lines_width += x;
14802
14803 if (nglyphs > 1 && i > 0)
14804 {
14805 row->ends_in_middle_of_char_p = 1;
14806 it->starts_in_middle_of_char_p = 1;
14807 }
14808
14809 /* Restore the height to what it was before the
14810 element not fitting on the line. */
14811 it->max_ascent = ascent;
14812 it->max_descent = descent;
14813 it->max_phys_ascent = phys_ascent;
14814 it->max_phys_descent = phys_descent;
14815 }
14816
14817 break;
14818 }
14819 else if (new_x > it->first_visible_x)
14820 {
14821 /* Increment number of glyphs actually displayed. */
14822 ++it->hpos;
14823
14824 if (x < it->first_visible_x)
14825 /* Glyph is partially visible, i.e. row starts at
14826 negative X position. */
14827 row->x = x - it->first_visible_x;
14828 }
14829 else
14830 {
14831 /* Glyph is completely off the left margin of the
14832 window. This should not happen because of the
14833 move_it_in_display_line at the start of this
14834 function, unless the text display area of the
14835 window is empty. */
14836 xassert (it->first_visible_x <= it->last_visible_x);
14837 }
14838 }
14839
14840 row->ascent = max (row->ascent, it->max_ascent);
14841 row->height = max (row->height, it->max_ascent + it->max_descent);
14842 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14843 row->phys_height = max (row->phys_height,
14844 it->max_phys_ascent + it->max_phys_descent);
14845
14846 /* End of this display line if row is continued. */
14847 if (row->continued_p || row->ends_at_zv_p)
14848 break;
14849 }
14850
14851 at_end_of_line:
14852 /* Is this a line end? If yes, we're also done, after making
14853 sure that a non-default face is extended up to the right
14854 margin of the window. */
14855 if (ITERATOR_AT_END_OF_LINE_P (it))
14856 {
14857 int used_before = row->used[TEXT_AREA];
14858
14859 row->ends_in_newline_from_string_p = STRINGP (it->object);
14860
14861 #ifdef HAVE_WINDOW_SYSTEM
14862 /* Add a space at the end of the line that is used to
14863 display the cursor there. */
14864 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14865 append_space_for_newline (it, 0);
14866 #endif /* HAVE_WINDOW_SYSTEM */
14867
14868 /* Extend the face to the end of the line. */
14869 extend_face_to_end_of_line (it);
14870
14871 /* Make sure we have the position. */
14872 if (used_before == 0)
14873 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14874
14875 /* Consume the line end. This skips over invisible lines. */
14876 set_iterator_to_next (it, 1);
14877 it->continuation_lines_width = 0;
14878 break;
14879 }
14880
14881 /* Proceed with next display element. Note that this skips
14882 over lines invisible because of selective display. */
14883 set_iterator_to_next (it, 1);
14884
14885 /* If we truncate lines, we are done when the last displayed
14886 glyphs reach past the right margin of the window. */
14887 if (it->truncate_lines_p
14888 && (FRAME_WINDOW_P (it->f)
14889 ? (it->current_x >= it->last_visible_x)
14890 : (it->current_x > it->last_visible_x)))
14891 {
14892 /* Maybe add truncation glyphs. */
14893 if (!FRAME_WINDOW_P (it->f))
14894 {
14895 int i, n;
14896
14897 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14898 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14899 break;
14900
14901 for (n = row->used[TEXT_AREA]; i < n; ++i)
14902 {
14903 row->used[TEXT_AREA] = i;
14904 produce_special_glyphs (it, IT_TRUNCATION);
14905 }
14906 }
14907 #ifdef HAVE_WINDOW_SYSTEM
14908 else
14909 {
14910 /* Don't truncate if we can overflow newline into fringe. */
14911 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14912 {
14913 if (!get_next_display_element (it))
14914 {
14915 #ifdef HAVE_WINDOW_SYSTEM
14916 it->continuation_lines_width = 0;
14917 row->ends_at_zv_p = 1;
14918 row->exact_window_width_line_p = 1;
14919 break;
14920 #endif /* HAVE_WINDOW_SYSTEM */
14921 }
14922 if (ITERATOR_AT_END_OF_LINE_P (it))
14923 {
14924 row->exact_window_width_line_p = 1;
14925 goto at_end_of_line;
14926 }
14927 }
14928 }
14929 #endif /* HAVE_WINDOW_SYSTEM */
14930
14931 row->truncated_on_right_p = 1;
14932 it->continuation_lines_width = 0;
14933 reseat_at_next_visible_line_start (it, 0);
14934 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14935 it->hpos = hpos_before;
14936 it->current_x = x_before;
14937 break;
14938 }
14939 }
14940
14941 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14942 at the left window margin. */
14943 if (it->first_visible_x
14944 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14945 {
14946 if (!FRAME_WINDOW_P (it->f))
14947 insert_left_trunc_glyphs (it);
14948 row->truncated_on_left_p = 1;
14949 }
14950
14951 /* If the start of this line is the overlay arrow-position, then
14952 mark this glyph row as the one containing the overlay arrow.
14953 This is clearly a mess with variable size fonts. It would be
14954 better to let it be displayed like cursors under X. */
14955 if (! overlay_arrow_seen
14956 && (overlay_arrow_string
14957 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14958 !NILP (overlay_arrow_string)))
14959 {
14960 /* Overlay arrow in window redisplay is a fringe bitmap. */
14961 if (!FRAME_WINDOW_P (it->f))
14962 {
14963 struct glyph_row *arrow_row
14964 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14965 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14966 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14967 struct glyph *p = row->glyphs[TEXT_AREA];
14968 struct glyph *p2, *end;
14969
14970 /* Copy the arrow glyphs. */
14971 while (glyph < arrow_end)
14972 *p++ = *glyph++;
14973
14974 /* Throw away padding glyphs. */
14975 p2 = p;
14976 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14977 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14978 ++p2;
14979 if (p2 > p)
14980 {
14981 while (p2 < end)
14982 *p++ = *p2++;
14983 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14984 }
14985 }
14986
14987 overlay_arrow_seen = 1;
14988 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14989 row->overlay_arrow_p = 1;
14990 }
14991
14992 /* Compute pixel dimensions of this line. */
14993 compute_line_metrics (it);
14994
14995 /* Remember the position at which this line ends. */
14996 row->end = it->current;
14997
14998 /* Save fringe bitmaps in this row. */
14999 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15000 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15001 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15002 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15003
15004 it->left_user_fringe_bitmap = 0;
15005 it->left_user_fringe_face_id = 0;
15006 it->right_user_fringe_bitmap = 0;
15007 it->right_user_fringe_face_id = 0;
15008
15009 /* Maybe set the cursor. */
15010 if (it->w->cursor.vpos < 0
15011 && PT >= MATRIX_ROW_START_CHARPOS (row)
15012 && PT <= MATRIX_ROW_END_CHARPOS (row)
15013 && cursor_row_p (it->w, row))
15014 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15015
15016 /* Highlight trailing whitespace. */
15017 if (!NILP (Vshow_trailing_whitespace))
15018 highlight_trailing_whitespace (it->f, it->glyph_row);
15019
15020 /* Prepare for the next line. This line starts horizontally at (X
15021 HPOS) = (0 0). Vertical positions are incremented. As a
15022 convenience for the caller, IT->glyph_row is set to the next
15023 row to be used. */
15024 it->current_x = it->hpos = 0;
15025 it->current_y += row->height;
15026 ++it->vpos;
15027 ++it->glyph_row;
15028 it->start = it->current;
15029 return row->displays_text_p;
15030 }
15031
15032
15033 \f
15034 /***********************************************************************
15035 Menu Bar
15036 ***********************************************************************/
15037
15038 /* Redisplay the menu bar in the frame for window W.
15039
15040 The menu bar of X frames that don't have X toolkit support is
15041 displayed in a special window W->frame->menu_bar_window.
15042
15043 The menu bar of terminal frames is treated specially as far as
15044 glyph matrices are concerned. Menu bar lines are not part of
15045 windows, so the update is done directly on the frame matrix rows
15046 for the menu bar. */
15047
15048 static void
15049 display_menu_bar (w)
15050 struct window *w;
15051 {
15052 struct frame *f = XFRAME (WINDOW_FRAME (w));
15053 struct it it;
15054 Lisp_Object items;
15055 int i;
15056
15057 /* Don't do all this for graphical frames. */
15058 #ifdef HAVE_NTGUI
15059 if (!NILP (Vwindow_system))
15060 return;
15061 #endif
15062 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15063 if (FRAME_X_P (f))
15064 return;
15065 #endif
15066 #ifdef MAC_OS
15067 if (FRAME_MAC_P (f))
15068 return;
15069 #endif
15070
15071 #ifdef USE_X_TOOLKIT
15072 xassert (!FRAME_WINDOW_P (f));
15073 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15074 it.first_visible_x = 0;
15075 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15076 #else /* not USE_X_TOOLKIT */
15077 if (FRAME_WINDOW_P (f))
15078 {
15079 /* Menu bar lines are displayed in the desired matrix of the
15080 dummy window menu_bar_window. */
15081 struct window *menu_w;
15082 xassert (WINDOWP (f->menu_bar_window));
15083 menu_w = XWINDOW (f->menu_bar_window);
15084 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15085 MENU_FACE_ID);
15086 it.first_visible_x = 0;
15087 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15088 }
15089 else
15090 {
15091 /* This is a TTY frame, i.e. character hpos/vpos are used as
15092 pixel x/y. */
15093 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15094 MENU_FACE_ID);
15095 it.first_visible_x = 0;
15096 it.last_visible_x = FRAME_COLS (f);
15097 }
15098 #endif /* not USE_X_TOOLKIT */
15099
15100 if (! mode_line_inverse_video)
15101 /* Force the menu-bar to be displayed in the default face. */
15102 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15103
15104 /* Clear all rows of the menu bar. */
15105 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15106 {
15107 struct glyph_row *row = it.glyph_row + i;
15108 clear_glyph_row (row);
15109 row->enabled_p = 1;
15110 row->full_width_p = 1;
15111 }
15112
15113 /* Display all items of the menu bar. */
15114 items = FRAME_MENU_BAR_ITEMS (it.f);
15115 for (i = 0; i < XVECTOR (items)->size; i += 4)
15116 {
15117 Lisp_Object string;
15118
15119 /* Stop at nil string. */
15120 string = AREF (items, i + 1);
15121 if (NILP (string))
15122 break;
15123
15124 /* Remember where item was displayed. */
15125 AREF (items, i + 3) = make_number (it.hpos);
15126
15127 /* Display the item, pad with one space. */
15128 if (it.current_x < it.last_visible_x)
15129 display_string (NULL, string, Qnil, 0, 0, &it,
15130 SCHARS (string) + 1, 0, 0, -1);
15131 }
15132
15133 /* Fill out the line with spaces. */
15134 if (it.current_x < it.last_visible_x)
15135 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15136
15137 /* Compute the total height of the lines. */
15138 compute_line_metrics (&it);
15139 }
15140
15141
15142 \f
15143 /***********************************************************************
15144 Mode Line
15145 ***********************************************************************/
15146
15147 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15148 FORCE is non-zero, redisplay mode lines unconditionally.
15149 Otherwise, redisplay only mode lines that are garbaged. Value is
15150 the number of windows whose mode lines were redisplayed. */
15151
15152 static int
15153 redisplay_mode_lines (window, force)
15154 Lisp_Object window;
15155 int force;
15156 {
15157 int nwindows = 0;
15158
15159 while (!NILP (window))
15160 {
15161 struct window *w = XWINDOW (window);
15162
15163 if (WINDOWP (w->hchild))
15164 nwindows += redisplay_mode_lines (w->hchild, force);
15165 else if (WINDOWP (w->vchild))
15166 nwindows += redisplay_mode_lines (w->vchild, force);
15167 else if (force
15168 || FRAME_GARBAGED_P (XFRAME (w->frame))
15169 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15170 {
15171 struct text_pos lpoint;
15172 struct buffer *old = current_buffer;
15173
15174 /* Set the window's buffer for the mode line display. */
15175 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15176 set_buffer_internal_1 (XBUFFER (w->buffer));
15177
15178 /* Point refers normally to the selected window. For any
15179 other window, set up appropriate value. */
15180 if (!EQ (window, selected_window))
15181 {
15182 struct text_pos pt;
15183
15184 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15185 if (CHARPOS (pt) < BEGV)
15186 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15187 else if (CHARPOS (pt) > (ZV - 1))
15188 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15189 else
15190 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15191 }
15192
15193 /* Display mode lines. */
15194 clear_glyph_matrix (w->desired_matrix);
15195 if (display_mode_lines (w))
15196 {
15197 ++nwindows;
15198 w->must_be_updated_p = 1;
15199 }
15200
15201 /* Restore old settings. */
15202 set_buffer_internal_1 (old);
15203 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15204 }
15205
15206 window = w->next;
15207 }
15208
15209 return nwindows;
15210 }
15211
15212
15213 /* Display the mode and/or top line of window W. Value is the number
15214 of mode lines displayed. */
15215
15216 static int
15217 display_mode_lines (w)
15218 struct window *w;
15219 {
15220 Lisp_Object old_selected_window, old_selected_frame;
15221 int n = 0;
15222
15223 old_selected_frame = selected_frame;
15224 selected_frame = w->frame;
15225 old_selected_window = selected_window;
15226 XSETWINDOW (selected_window, w);
15227
15228 /* These will be set while the mode line specs are processed. */
15229 line_number_displayed = 0;
15230 w->column_number_displayed = Qnil;
15231
15232 if (WINDOW_WANTS_MODELINE_P (w))
15233 {
15234 struct window *sel_w = XWINDOW (old_selected_window);
15235
15236 /* Select mode line face based on the real selected window. */
15237 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15238 current_buffer->mode_line_format);
15239 ++n;
15240 }
15241
15242 if (WINDOW_WANTS_HEADER_LINE_P (w))
15243 {
15244 display_mode_line (w, HEADER_LINE_FACE_ID,
15245 current_buffer->header_line_format);
15246 ++n;
15247 }
15248
15249 selected_frame = old_selected_frame;
15250 selected_window = old_selected_window;
15251 return n;
15252 }
15253
15254
15255 /* Display mode or top line of window W. FACE_ID specifies which line
15256 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15257 FORMAT is the mode line format to display. Value is the pixel
15258 height of the mode line displayed. */
15259
15260 static int
15261 display_mode_line (w, face_id, format)
15262 struct window *w;
15263 enum face_id face_id;
15264 Lisp_Object format;
15265 {
15266 struct it it;
15267 struct face *face;
15268
15269 init_iterator (&it, w, -1, -1, NULL, face_id);
15270 prepare_desired_row (it.glyph_row);
15271
15272 it.glyph_row->mode_line_p = 1;
15273
15274 if (! mode_line_inverse_video)
15275 /* Force the mode-line to be displayed in the default face. */
15276 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15277
15278 /* Temporarily make frame's keyboard the current kboard so that
15279 kboard-local variables in the mode_line_format will get the right
15280 values. */
15281 push_frame_kboard (it.f);
15282 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15283 pop_frame_kboard ();
15284
15285 /* Fill up with spaces. */
15286 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15287
15288 compute_line_metrics (&it);
15289 it.glyph_row->full_width_p = 1;
15290 it.glyph_row->continued_p = 0;
15291 it.glyph_row->truncated_on_left_p = 0;
15292 it.glyph_row->truncated_on_right_p = 0;
15293
15294 /* Make a 3D mode-line have a shadow at its right end. */
15295 face = FACE_FROM_ID (it.f, face_id);
15296 extend_face_to_end_of_line (&it);
15297 if (face->box != FACE_NO_BOX)
15298 {
15299 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15300 + it.glyph_row->used[TEXT_AREA] - 1);
15301 last->right_box_line_p = 1;
15302 }
15303
15304 return it.glyph_row->height;
15305 }
15306
15307 /* Alist that caches the results of :propertize.
15308 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15309 Lisp_Object mode_line_proptrans_alist;
15310
15311 /* List of strings making up the mode-line. */
15312 Lisp_Object mode_line_string_list;
15313
15314 /* Base face property when building propertized mode line string. */
15315 static Lisp_Object mode_line_string_face;
15316 static Lisp_Object mode_line_string_face_prop;
15317
15318
15319 /* Contribute ELT to the mode line for window IT->w. How it
15320 translates into text depends on its data type.
15321
15322 IT describes the display environment in which we display, as usual.
15323
15324 DEPTH is the depth in recursion. It is used to prevent
15325 infinite recursion here.
15326
15327 FIELD_WIDTH is the number of characters the display of ELT should
15328 occupy in the mode line, and PRECISION is the maximum number of
15329 characters to display from ELT's representation. See
15330 display_string for details.
15331
15332 Returns the hpos of the end of the text generated by ELT.
15333
15334 PROPS is a property list to add to any string we encounter.
15335
15336 If RISKY is nonzero, remove (disregard) any properties in any string
15337 we encounter, and ignore :eval and :propertize.
15338
15339 If the global variable `frame_title_ptr' is non-NULL, then the output
15340 is passed to `store_frame_title' instead of `display_string'. */
15341
15342 static int
15343 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15344 struct it *it;
15345 int depth;
15346 int field_width, precision;
15347 Lisp_Object elt, props;
15348 int risky;
15349 {
15350 int n = 0, field, prec;
15351 int literal = 0;
15352
15353 tail_recurse:
15354 if (depth > 100)
15355 elt = build_string ("*too-deep*");
15356
15357 depth++;
15358
15359 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15360 {
15361 case Lisp_String:
15362 {
15363 /* A string: output it and check for %-constructs within it. */
15364 unsigned char c;
15365 const unsigned char *this, *lisp_string;
15366
15367 if (!NILP (props) || risky)
15368 {
15369 Lisp_Object oprops, aelt;
15370 oprops = Ftext_properties_at (make_number (0), elt);
15371
15372 /* If the starting string's properties are not what
15373 we want, translate the string. Also, if the string
15374 is risky, do that anyway. */
15375
15376 if (NILP (Fequal (props, oprops)) || risky)
15377 {
15378 /* If the starting string has properties,
15379 merge the specified ones onto the existing ones. */
15380 if (! NILP (oprops) && !risky)
15381 {
15382 Lisp_Object tem;
15383
15384 oprops = Fcopy_sequence (oprops);
15385 tem = props;
15386 while (CONSP (tem))
15387 {
15388 oprops = Fplist_put (oprops, XCAR (tem),
15389 XCAR (XCDR (tem)));
15390 tem = XCDR (XCDR (tem));
15391 }
15392 props = oprops;
15393 }
15394
15395 aelt = Fassoc (elt, mode_line_proptrans_alist);
15396 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15397 {
15398 mode_line_proptrans_alist
15399 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15400 elt = XCAR (aelt);
15401 }
15402 else
15403 {
15404 Lisp_Object tem;
15405
15406 elt = Fcopy_sequence (elt);
15407 Fset_text_properties (make_number (0), Flength (elt),
15408 props, elt);
15409 /* Add this item to mode_line_proptrans_alist. */
15410 mode_line_proptrans_alist
15411 = Fcons (Fcons (elt, props),
15412 mode_line_proptrans_alist);
15413 /* Truncate mode_line_proptrans_alist
15414 to at most 50 elements. */
15415 tem = Fnthcdr (make_number (50),
15416 mode_line_proptrans_alist);
15417 if (! NILP (tem))
15418 XSETCDR (tem, Qnil);
15419 }
15420 }
15421 }
15422
15423 this = SDATA (elt);
15424 lisp_string = this;
15425
15426 if (literal)
15427 {
15428 prec = precision - n;
15429 if (frame_title_ptr)
15430 n += store_frame_title (SDATA (elt), -1, prec);
15431 else if (!NILP (mode_line_string_list))
15432 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15433 else
15434 n += display_string (NULL, elt, Qnil, 0, 0, it,
15435 0, prec, 0, STRING_MULTIBYTE (elt));
15436
15437 break;
15438 }
15439
15440 while ((precision <= 0 || n < precision)
15441 && *this
15442 && (frame_title_ptr
15443 || !NILP (mode_line_string_list)
15444 || it->current_x < it->last_visible_x))
15445 {
15446 const unsigned char *last = this;
15447
15448 /* Advance to end of string or next format specifier. */
15449 while ((c = *this++) != '\0' && c != '%')
15450 ;
15451
15452 if (this - 1 != last)
15453 {
15454 /* Output to end of string or up to '%'. Field width
15455 is length of string. Don't output more than
15456 PRECISION allows us. */
15457 --this;
15458
15459 prec = chars_in_text (last, this - last);
15460 if (precision > 0 && prec > precision - n)
15461 prec = precision - n;
15462
15463 if (frame_title_ptr)
15464 n += store_frame_title (last, 0, prec);
15465 else if (!NILP (mode_line_string_list))
15466 {
15467 int bytepos = last - lisp_string;
15468 int charpos = string_byte_to_char (elt, bytepos);
15469 n += store_mode_line_string (NULL,
15470 Fsubstring (elt, make_number (charpos),
15471 make_number (charpos + prec)),
15472 0, 0, 0, Qnil);
15473 }
15474 else
15475 {
15476 int bytepos = last - lisp_string;
15477 int charpos = string_byte_to_char (elt, bytepos);
15478 n += display_string (NULL, elt, Qnil, 0, charpos,
15479 it, 0, prec, 0,
15480 STRING_MULTIBYTE (elt));
15481 }
15482 }
15483 else /* c == '%' */
15484 {
15485 const unsigned char *percent_position = this;
15486
15487 /* Get the specified minimum width. Zero means
15488 don't pad. */
15489 field = 0;
15490 while ((c = *this++) >= '0' && c <= '9')
15491 field = field * 10 + c - '0';
15492
15493 /* Don't pad beyond the total padding allowed. */
15494 if (field_width - n > 0 && field > field_width - n)
15495 field = field_width - n;
15496
15497 /* Note that either PRECISION <= 0 or N < PRECISION. */
15498 prec = precision - n;
15499
15500 if (c == 'M')
15501 n += display_mode_element (it, depth, field, prec,
15502 Vglobal_mode_string, props,
15503 risky);
15504 else if (c != 0)
15505 {
15506 int multibyte;
15507 int bytepos, charpos;
15508 unsigned char *spec;
15509
15510 bytepos = percent_position - lisp_string;
15511 charpos = (STRING_MULTIBYTE (elt)
15512 ? string_byte_to_char (elt, bytepos)
15513 : bytepos);
15514
15515 spec
15516 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15517
15518 if (frame_title_ptr)
15519 n += store_frame_title (spec, field, prec);
15520 else if (!NILP (mode_line_string_list))
15521 {
15522 int len = strlen (spec);
15523 Lisp_Object tem = make_string (spec, len);
15524 props = Ftext_properties_at (make_number (charpos), elt);
15525 /* Should only keep face property in props */
15526 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15527 }
15528 else
15529 {
15530 int nglyphs_before, nwritten;
15531
15532 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15533 nwritten = display_string (spec, Qnil, elt,
15534 charpos, 0, it,
15535 field, prec, 0,
15536 multibyte);
15537
15538 /* Assign to the glyphs written above the
15539 string where the `%x' came from, position
15540 of the `%'. */
15541 if (nwritten > 0)
15542 {
15543 struct glyph *glyph
15544 = (it->glyph_row->glyphs[TEXT_AREA]
15545 + nglyphs_before);
15546 int i;
15547
15548 for (i = 0; i < nwritten; ++i)
15549 {
15550 glyph[i].object = elt;
15551 glyph[i].charpos = charpos;
15552 }
15553
15554 n += nwritten;
15555 }
15556 }
15557 }
15558 else /* c == 0 */
15559 break;
15560 }
15561 }
15562 }
15563 break;
15564
15565 case Lisp_Symbol:
15566 /* A symbol: process the value of the symbol recursively
15567 as if it appeared here directly. Avoid error if symbol void.
15568 Special case: if value of symbol is a string, output the string
15569 literally. */
15570 {
15571 register Lisp_Object tem;
15572
15573 /* If the variable is not marked as risky to set
15574 then its contents are risky to use. */
15575 if (NILP (Fget (elt, Qrisky_local_variable)))
15576 risky = 1;
15577
15578 tem = Fboundp (elt);
15579 if (!NILP (tem))
15580 {
15581 tem = Fsymbol_value (elt);
15582 /* If value is a string, output that string literally:
15583 don't check for % within it. */
15584 if (STRINGP (tem))
15585 literal = 1;
15586
15587 if (!EQ (tem, elt))
15588 {
15589 /* Give up right away for nil or t. */
15590 elt = tem;
15591 goto tail_recurse;
15592 }
15593 }
15594 }
15595 break;
15596
15597 case Lisp_Cons:
15598 {
15599 register Lisp_Object car, tem;
15600
15601 /* A cons cell: five distinct cases.
15602 If first element is :eval or :propertize, do something special.
15603 If first element is a string or a cons, process all the elements
15604 and effectively concatenate them.
15605 If first element is a negative number, truncate displaying cdr to
15606 at most that many characters. If positive, pad (with spaces)
15607 to at least that many characters.
15608 If first element is a symbol, process the cadr or caddr recursively
15609 according to whether the symbol's value is non-nil or nil. */
15610 car = XCAR (elt);
15611 if (EQ (car, QCeval))
15612 {
15613 /* An element of the form (:eval FORM) means evaluate FORM
15614 and use the result as mode line elements. */
15615
15616 if (risky)
15617 break;
15618
15619 if (CONSP (XCDR (elt)))
15620 {
15621 Lisp_Object spec;
15622 spec = safe_eval (XCAR (XCDR (elt)));
15623 n += display_mode_element (it, depth, field_width - n,
15624 precision - n, spec, props,
15625 risky);
15626 }
15627 }
15628 else if (EQ (car, QCpropertize))
15629 {
15630 /* An element of the form (:propertize ELT PROPS...)
15631 means display ELT but applying properties PROPS. */
15632
15633 if (risky)
15634 break;
15635
15636 if (CONSP (XCDR (elt)))
15637 n += display_mode_element (it, depth, field_width - n,
15638 precision - n, XCAR (XCDR (elt)),
15639 XCDR (XCDR (elt)), risky);
15640 }
15641 else if (SYMBOLP (car))
15642 {
15643 tem = Fboundp (car);
15644 elt = XCDR (elt);
15645 if (!CONSP (elt))
15646 goto invalid;
15647 /* elt is now the cdr, and we know it is a cons cell.
15648 Use its car if CAR has a non-nil value. */
15649 if (!NILP (tem))
15650 {
15651 tem = Fsymbol_value (car);
15652 if (!NILP (tem))
15653 {
15654 elt = XCAR (elt);
15655 goto tail_recurse;
15656 }
15657 }
15658 /* Symbol's value is nil (or symbol is unbound)
15659 Get the cddr of the original list
15660 and if possible find the caddr and use that. */
15661 elt = XCDR (elt);
15662 if (NILP (elt))
15663 break;
15664 else if (!CONSP (elt))
15665 goto invalid;
15666 elt = XCAR (elt);
15667 goto tail_recurse;
15668 }
15669 else if (INTEGERP (car))
15670 {
15671 register int lim = XINT (car);
15672 elt = XCDR (elt);
15673 if (lim < 0)
15674 {
15675 /* Negative int means reduce maximum width. */
15676 if (precision <= 0)
15677 precision = -lim;
15678 else
15679 precision = min (precision, -lim);
15680 }
15681 else if (lim > 0)
15682 {
15683 /* Padding specified. Don't let it be more than
15684 current maximum. */
15685 if (precision > 0)
15686 lim = min (precision, lim);
15687
15688 /* If that's more padding than already wanted, queue it.
15689 But don't reduce padding already specified even if
15690 that is beyond the current truncation point. */
15691 field_width = max (lim, field_width);
15692 }
15693 goto tail_recurse;
15694 }
15695 else if (STRINGP (car) || CONSP (car))
15696 {
15697 register int limit = 50;
15698 /* Limit is to protect against circular lists. */
15699 while (CONSP (elt)
15700 && --limit > 0
15701 && (precision <= 0 || n < precision))
15702 {
15703 n += display_mode_element (it, depth, field_width - n,
15704 precision - n, XCAR (elt),
15705 props, risky);
15706 elt = XCDR (elt);
15707 }
15708 }
15709 }
15710 break;
15711
15712 default:
15713 invalid:
15714 elt = build_string ("*invalid*");
15715 goto tail_recurse;
15716 }
15717
15718 /* Pad to FIELD_WIDTH. */
15719 if (field_width > 0 && n < field_width)
15720 {
15721 if (frame_title_ptr)
15722 n += store_frame_title ("", field_width - n, 0);
15723 else if (!NILP (mode_line_string_list))
15724 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15725 else
15726 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15727 0, 0, 0);
15728 }
15729
15730 return n;
15731 }
15732
15733 /* Store a mode-line string element in mode_line_string_list.
15734
15735 If STRING is non-null, display that C string. Otherwise, the Lisp
15736 string LISP_STRING is displayed.
15737
15738 FIELD_WIDTH is the minimum number of output glyphs to produce.
15739 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15740 with spaces. FIELD_WIDTH <= 0 means don't pad.
15741
15742 PRECISION is the maximum number of characters to output from
15743 STRING. PRECISION <= 0 means don't truncate the string.
15744
15745 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15746 properties to the string.
15747
15748 PROPS are the properties to add to the string.
15749 The mode_line_string_face face property is always added to the string.
15750 */
15751
15752 static int
15753 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15754 char *string;
15755 Lisp_Object lisp_string;
15756 int copy_string;
15757 int field_width;
15758 int precision;
15759 Lisp_Object props;
15760 {
15761 int len;
15762 int n = 0;
15763
15764 if (string != NULL)
15765 {
15766 len = strlen (string);
15767 if (precision > 0 && len > precision)
15768 len = precision;
15769 lisp_string = make_string (string, len);
15770 if (NILP (props))
15771 props = mode_line_string_face_prop;
15772 else if (!NILP (mode_line_string_face))
15773 {
15774 Lisp_Object face = Fplist_get (props, Qface);
15775 props = Fcopy_sequence (props);
15776 if (NILP (face))
15777 face = mode_line_string_face;
15778 else
15779 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15780 props = Fplist_put (props, Qface, face);
15781 }
15782 Fadd_text_properties (make_number (0), make_number (len),
15783 props, lisp_string);
15784 }
15785 else
15786 {
15787 len = XFASTINT (Flength (lisp_string));
15788 if (precision > 0 && len > precision)
15789 {
15790 len = precision;
15791 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15792 precision = -1;
15793 }
15794 if (!NILP (mode_line_string_face))
15795 {
15796 Lisp_Object face;
15797 if (NILP (props))
15798 props = Ftext_properties_at (make_number (0), lisp_string);
15799 face = Fplist_get (props, Qface);
15800 if (NILP (face))
15801 face = mode_line_string_face;
15802 else
15803 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15804 props = Fcons (Qface, Fcons (face, Qnil));
15805 if (copy_string)
15806 lisp_string = Fcopy_sequence (lisp_string);
15807 }
15808 if (!NILP (props))
15809 Fadd_text_properties (make_number (0), make_number (len),
15810 props, lisp_string);
15811 }
15812
15813 if (len > 0)
15814 {
15815 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15816 n += len;
15817 }
15818
15819 if (field_width > len)
15820 {
15821 field_width -= len;
15822 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15823 if (!NILP (props))
15824 Fadd_text_properties (make_number (0), make_number (field_width),
15825 props, lisp_string);
15826 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15827 n += field_width;
15828 }
15829
15830 return n;
15831 }
15832
15833
15834 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15835 0, 4, 0,
15836 doc: /* Return the mode-line of selected window as a string.
15837 First optional arg FORMAT specifies a different format string (see
15838 `mode-line-format' for details) to use. If FORMAT is t, return
15839 the buffer's header-line. Second optional arg WINDOW specifies a
15840 different window to use as the context for the formatting.
15841 If third optional arg NO-PROPS is non-nil, string is not propertized.
15842 Fourth optional arg BUFFER specifies which buffer to use. */)
15843 (format, window, no_props, buffer)
15844 Lisp_Object format, window, no_props, buffer;
15845 {
15846 struct it it;
15847 int len;
15848 struct window *w;
15849 struct buffer *old_buffer = NULL;
15850 enum face_id face_id = DEFAULT_FACE_ID;
15851
15852 if (NILP (window))
15853 window = selected_window;
15854 CHECK_WINDOW (window);
15855 w = XWINDOW (window);
15856
15857 if (NILP (buffer))
15858 buffer = w->buffer;
15859
15860 CHECK_BUFFER (buffer);
15861
15862 if (XBUFFER (buffer) != current_buffer)
15863 {
15864 old_buffer = current_buffer;
15865 set_buffer_internal_1 (XBUFFER (buffer));
15866 }
15867
15868 if (NILP (format) || EQ (format, Qt))
15869 {
15870 face_id = (NILP (format)
15871 ? CURRENT_MODE_LINE_FACE_ID (w)
15872 : HEADER_LINE_FACE_ID);
15873 format = (NILP (format)
15874 ? current_buffer->mode_line_format
15875 : current_buffer->header_line_format);
15876 }
15877
15878 init_iterator (&it, w, -1, -1, NULL, face_id);
15879
15880 if (NILP (no_props))
15881 {
15882 mode_line_string_face
15883 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15884 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15885 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15886
15887 mode_line_string_face_prop
15888 = (NILP (mode_line_string_face) ? Qnil
15889 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15890
15891 /* We need a dummy last element in mode_line_string_list to
15892 indicate we are building the propertized mode-line string.
15893 Using mode_line_string_face_prop here GC protects it. */
15894 mode_line_string_list
15895 = Fcons (mode_line_string_face_prop, Qnil);
15896 frame_title_ptr = NULL;
15897 }
15898 else
15899 {
15900 mode_line_string_face_prop = Qnil;
15901 mode_line_string_list = Qnil;
15902 frame_title_ptr = frame_title_buf;
15903 }
15904
15905 push_frame_kboard (it.f);
15906 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15907 pop_frame_kboard ();
15908
15909 if (old_buffer)
15910 set_buffer_internal_1 (old_buffer);
15911
15912 if (NILP (no_props))
15913 {
15914 Lisp_Object str;
15915 mode_line_string_list = Fnreverse (mode_line_string_list);
15916 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15917 make_string ("", 0));
15918 mode_line_string_face_prop = Qnil;
15919 mode_line_string_list = Qnil;
15920 return str;
15921 }
15922
15923 len = frame_title_ptr - frame_title_buf;
15924 if (len > 0 && frame_title_ptr[-1] == '-')
15925 {
15926 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15927 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15928 ;
15929 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15930 if (len > frame_title_ptr - frame_title_buf)
15931 len = frame_title_ptr - frame_title_buf;
15932 }
15933
15934 frame_title_ptr = NULL;
15935 return make_string (frame_title_buf, len);
15936 }
15937
15938 /* Write a null-terminated, right justified decimal representation of
15939 the positive integer D to BUF using a minimal field width WIDTH. */
15940
15941 static void
15942 pint2str (buf, width, d)
15943 register char *buf;
15944 register int width;
15945 register int d;
15946 {
15947 register char *p = buf;
15948
15949 if (d <= 0)
15950 *p++ = '0';
15951 else
15952 {
15953 while (d > 0)
15954 {
15955 *p++ = d % 10 + '0';
15956 d /= 10;
15957 }
15958 }
15959
15960 for (width -= (int) (p - buf); width > 0; --width)
15961 *p++ = ' ';
15962 *p-- = '\0';
15963 while (p > buf)
15964 {
15965 d = *buf;
15966 *buf++ = *p;
15967 *p-- = d;
15968 }
15969 }
15970
15971 /* Write a null-terminated, right justified decimal and "human
15972 readable" representation of the nonnegative integer D to BUF using
15973 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15974
15975 static const char power_letter[] =
15976 {
15977 0, /* not used */
15978 'k', /* kilo */
15979 'M', /* mega */
15980 'G', /* giga */
15981 'T', /* tera */
15982 'P', /* peta */
15983 'E', /* exa */
15984 'Z', /* zetta */
15985 'Y' /* yotta */
15986 };
15987
15988 static void
15989 pint2hrstr (buf, width, d)
15990 char *buf;
15991 int width;
15992 int d;
15993 {
15994 /* We aim to represent the nonnegative integer D as
15995 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15996 int quotient = d;
15997 int remainder = 0;
15998 /* -1 means: do not use TENTHS. */
15999 int tenths = -1;
16000 int exponent = 0;
16001
16002 /* Length of QUOTIENT.TENTHS as a string. */
16003 int length;
16004
16005 char * psuffix;
16006 char * p;
16007
16008 if (1000 <= quotient)
16009 {
16010 /* Scale to the appropriate EXPONENT. */
16011 do
16012 {
16013 remainder = quotient % 1000;
16014 quotient /= 1000;
16015 exponent++;
16016 }
16017 while (1000 <= quotient);
16018
16019 /* Round to nearest and decide whether to use TENTHS or not. */
16020 if (quotient <= 9)
16021 {
16022 tenths = remainder / 100;
16023 if (50 <= remainder % 100)
16024 if (tenths < 9)
16025 tenths++;
16026 else
16027 {
16028 quotient++;
16029 if (quotient == 10)
16030 tenths = -1;
16031 else
16032 tenths = 0;
16033 }
16034 }
16035 else
16036 if (500 <= remainder)
16037 if (quotient < 999)
16038 quotient++;
16039 else
16040 {
16041 quotient = 1;
16042 exponent++;
16043 tenths = 0;
16044 }
16045 }
16046
16047 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16048 if (tenths == -1 && quotient <= 99)
16049 if (quotient <= 9)
16050 length = 1;
16051 else
16052 length = 2;
16053 else
16054 length = 3;
16055 p = psuffix = buf + max (width, length);
16056
16057 /* Print EXPONENT. */
16058 if (exponent)
16059 *psuffix++ = power_letter[exponent];
16060 *psuffix = '\0';
16061
16062 /* Print TENTHS. */
16063 if (tenths >= 0)
16064 {
16065 *--p = '0' + tenths;
16066 *--p = '.';
16067 }
16068
16069 /* Print QUOTIENT. */
16070 do
16071 {
16072 int digit = quotient % 10;
16073 *--p = '0' + digit;
16074 }
16075 while ((quotient /= 10) != 0);
16076
16077 /* Print leading spaces. */
16078 while (buf < p)
16079 *--p = ' ';
16080 }
16081
16082 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16083 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16084 type of CODING_SYSTEM. Return updated pointer into BUF. */
16085
16086 static unsigned char invalid_eol_type[] = "(*invalid*)";
16087
16088 static char *
16089 decode_mode_spec_coding (coding_system, buf, eol_flag)
16090 Lisp_Object coding_system;
16091 register char *buf;
16092 int eol_flag;
16093 {
16094 Lisp_Object val;
16095 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16096 const unsigned char *eol_str;
16097 int eol_str_len;
16098 /* The EOL conversion we are using. */
16099 Lisp_Object eoltype;
16100
16101 val = Fget (coding_system, Qcoding_system);
16102 eoltype = Qnil;
16103
16104 if (!VECTORP (val)) /* Not yet decided. */
16105 {
16106 if (multibyte)
16107 *buf++ = '-';
16108 if (eol_flag)
16109 eoltype = eol_mnemonic_undecided;
16110 /* Don't mention EOL conversion if it isn't decided. */
16111 }
16112 else
16113 {
16114 Lisp_Object eolvalue;
16115
16116 eolvalue = Fget (coding_system, Qeol_type);
16117
16118 if (multibyte)
16119 *buf++ = XFASTINT (AREF (val, 1));
16120
16121 if (eol_flag)
16122 {
16123 /* The EOL conversion that is normal on this system. */
16124
16125 if (NILP (eolvalue)) /* Not yet decided. */
16126 eoltype = eol_mnemonic_undecided;
16127 else if (VECTORP (eolvalue)) /* Not yet decided. */
16128 eoltype = eol_mnemonic_undecided;
16129 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16130 eoltype = (XFASTINT (eolvalue) == 0
16131 ? eol_mnemonic_unix
16132 : (XFASTINT (eolvalue) == 1
16133 ? eol_mnemonic_dos : eol_mnemonic_mac));
16134 }
16135 }
16136
16137 if (eol_flag)
16138 {
16139 /* Mention the EOL conversion if it is not the usual one. */
16140 if (STRINGP (eoltype))
16141 {
16142 eol_str = SDATA (eoltype);
16143 eol_str_len = SBYTES (eoltype);
16144 }
16145 else if (INTEGERP (eoltype)
16146 && CHAR_VALID_P (XINT (eoltype), 0))
16147 {
16148 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16149 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16150 eol_str = tmp;
16151 }
16152 else
16153 {
16154 eol_str = invalid_eol_type;
16155 eol_str_len = sizeof (invalid_eol_type) - 1;
16156 }
16157 bcopy (eol_str, buf, eol_str_len);
16158 buf += eol_str_len;
16159 }
16160
16161 return buf;
16162 }
16163
16164 /* Return a string for the output of a mode line %-spec for window W,
16165 generated by character C. PRECISION >= 0 means don't return a
16166 string longer than that value. FIELD_WIDTH > 0 means pad the
16167 string returned with spaces to that value. Return 1 in *MULTIBYTE
16168 if the result is multibyte text.
16169
16170 Note we operate on the current buffer for most purposes,
16171 the exception being w->base_line_pos. */
16172
16173 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16174
16175 static char *
16176 decode_mode_spec (w, c, field_width, precision, multibyte)
16177 struct window *w;
16178 register int c;
16179 int field_width, precision;
16180 int *multibyte;
16181 {
16182 Lisp_Object obj;
16183 struct frame *f = XFRAME (WINDOW_FRAME (w));
16184 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16185 struct buffer *b = current_buffer;
16186
16187 obj = Qnil;
16188 *multibyte = 0;
16189
16190 switch (c)
16191 {
16192 case '*':
16193 if (!NILP (b->read_only))
16194 return "%";
16195 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16196 return "*";
16197 return "-";
16198
16199 case '+':
16200 /* This differs from %* only for a modified read-only buffer. */
16201 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16202 return "*";
16203 if (!NILP (b->read_only))
16204 return "%";
16205 return "-";
16206
16207 case '&':
16208 /* This differs from %* in ignoring read-only-ness. */
16209 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16210 return "*";
16211 return "-";
16212
16213 case '%':
16214 return "%";
16215
16216 case '[':
16217 {
16218 int i;
16219 char *p;
16220
16221 if (command_loop_level > 5)
16222 return "[[[... ";
16223 p = decode_mode_spec_buf;
16224 for (i = 0; i < command_loop_level; i++)
16225 *p++ = '[';
16226 *p = 0;
16227 return decode_mode_spec_buf;
16228 }
16229
16230 case ']':
16231 {
16232 int i;
16233 char *p;
16234
16235 if (command_loop_level > 5)
16236 return " ...]]]";
16237 p = decode_mode_spec_buf;
16238 for (i = 0; i < command_loop_level; i++)
16239 *p++ = ']';
16240 *p = 0;
16241 return decode_mode_spec_buf;
16242 }
16243
16244 case '-':
16245 {
16246 register int i;
16247
16248 /* Let lots_of_dashes be a string of infinite length. */
16249 if (!NILP (mode_line_string_list))
16250 return "--";
16251 if (field_width <= 0
16252 || field_width > sizeof (lots_of_dashes))
16253 {
16254 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16255 decode_mode_spec_buf[i] = '-';
16256 decode_mode_spec_buf[i] = '\0';
16257 return decode_mode_spec_buf;
16258 }
16259 else
16260 return lots_of_dashes;
16261 }
16262
16263 case 'b':
16264 obj = b->name;
16265 break;
16266
16267 case 'c':
16268 {
16269 int col = (int) current_column (); /* iftc */
16270 w->column_number_displayed = make_number (col);
16271 pint2str (decode_mode_spec_buf, field_width, col);
16272 return decode_mode_spec_buf;
16273 }
16274
16275 case 'F':
16276 /* %F displays the frame name. */
16277 if (!NILP (f->title))
16278 return (char *) SDATA (f->title);
16279 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16280 return (char *) SDATA (f->name);
16281 return "Emacs";
16282
16283 case 'f':
16284 obj = b->filename;
16285 break;
16286
16287 case 'i':
16288 {
16289 int size = ZV - BEGV;
16290 pint2str (decode_mode_spec_buf, field_width, size);
16291 return decode_mode_spec_buf;
16292 }
16293
16294 case 'I':
16295 {
16296 int size = ZV - BEGV;
16297 pint2hrstr (decode_mode_spec_buf, field_width, size);
16298 return decode_mode_spec_buf;
16299 }
16300
16301 case 'l':
16302 {
16303 int startpos = XMARKER (w->start)->charpos;
16304 int startpos_byte = marker_byte_position (w->start);
16305 int line, linepos, linepos_byte, topline;
16306 int nlines, junk;
16307 int height = WINDOW_TOTAL_LINES (w);
16308
16309 /* If we decided that this buffer isn't suitable for line numbers,
16310 don't forget that too fast. */
16311 if (EQ (w->base_line_pos, w->buffer))
16312 goto no_value;
16313 /* But do forget it, if the window shows a different buffer now. */
16314 else if (BUFFERP (w->base_line_pos))
16315 w->base_line_pos = Qnil;
16316
16317 /* If the buffer is very big, don't waste time. */
16318 if (INTEGERP (Vline_number_display_limit)
16319 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16320 {
16321 w->base_line_pos = Qnil;
16322 w->base_line_number = Qnil;
16323 goto no_value;
16324 }
16325
16326 if (!NILP (w->base_line_number)
16327 && !NILP (w->base_line_pos)
16328 && XFASTINT (w->base_line_pos) <= startpos)
16329 {
16330 line = XFASTINT (w->base_line_number);
16331 linepos = XFASTINT (w->base_line_pos);
16332 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16333 }
16334 else
16335 {
16336 line = 1;
16337 linepos = BUF_BEGV (b);
16338 linepos_byte = BUF_BEGV_BYTE (b);
16339 }
16340
16341 /* Count lines from base line to window start position. */
16342 nlines = display_count_lines (linepos, linepos_byte,
16343 startpos_byte,
16344 startpos, &junk);
16345
16346 topline = nlines + line;
16347
16348 /* Determine a new base line, if the old one is too close
16349 or too far away, or if we did not have one.
16350 "Too close" means it's plausible a scroll-down would
16351 go back past it. */
16352 if (startpos == BUF_BEGV (b))
16353 {
16354 w->base_line_number = make_number (topline);
16355 w->base_line_pos = make_number (BUF_BEGV (b));
16356 }
16357 else if (nlines < height + 25 || nlines > height * 3 + 50
16358 || linepos == BUF_BEGV (b))
16359 {
16360 int limit = BUF_BEGV (b);
16361 int limit_byte = BUF_BEGV_BYTE (b);
16362 int position;
16363 int distance = (height * 2 + 30) * line_number_display_limit_width;
16364
16365 if (startpos - distance > limit)
16366 {
16367 limit = startpos - distance;
16368 limit_byte = CHAR_TO_BYTE (limit);
16369 }
16370
16371 nlines = display_count_lines (startpos, startpos_byte,
16372 limit_byte,
16373 - (height * 2 + 30),
16374 &position);
16375 /* If we couldn't find the lines we wanted within
16376 line_number_display_limit_width chars per line,
16377 give up on line numbers for this window. */
16378 if (position == limit_byte && limit == startpos - distance)
16379 {
16380 w->base_line_pos = w->buffer;
16381 w->base_line_number = Qnil;
16382 goto no_value;
16383 }
16384
16385 w->base_line_number = make_number (topline - nlines);
16386 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16387 }
16388
16389 /* Now count lines from the start pos to point. */
16390 nlines = display_count_lines (startpos, startpos_byte,
16391 PT_BYTE, PT, &junk);
16392
16393 /* Record that we did display the line number. */
16394 line_number_displayed = 1;
16395
16396 /* Make the string to show. */
16397 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16398 return decode_mode_spec_buf;
16399 no_value:
16400 {
16401 char* p = decode_mode_spec_buf;
16402 int pad = field_width - 2;
16403 while (pad-- > 0)
16404 *p++ = ' ';
16405 *p++ = '?';
16406 *p++ = '?';
16407 *p = '\0';
16408 return decode_mode_spec_buf;
16409 }
16410 }
16411 break;
16412
16413 case 'm':
16414 obj = b->mode_name;
16415 break;
16416
16417 case 'n':
16418 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16419 return " Narrow";
16420 break;
16421
16422 case 'p':
16423 {
16424 int pos = marker_position (w->start);
16425 int total = BUF_ZV (b) - BUF_BEGV (b);
16426
16427 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16428 {
16429 if (pos <= BUF_BEGV (b))
16430 return "All";
16431 else
16432 return "Bottom";
16433 }
16434 else if (pos <= BUF_BEGV (b))
16435 return "Top";
16436 else
16437 {
16438 if (total > 1000000)
16439 /* Do it differently for a large value, to avoid overflow. */
16440 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16441 else
16442 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16443 /* We can't normally display a 3-digit number,
16444 so get us a 2-digit number that is close. */
16445 if (total == 100)
16446 total = 99;
16447 sprintf (decode_mode_spec_buf, "%2d%%", total);
16448 return decode_mode_spec_buf;
16449 }
16450 }
16451
16452 /* Display percentage of size above the bottom of the screen. */
16453 case 'P':
16454 {
16455 int toppos = marker_position (w->start);
16456 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16457 int total = BUF_ZV (b) - BUF_BEGV (b);
16458
16459 if (botpos >= BUF_ZV (b))
16460 {
16461 if (toppos <= BUF_BEGV (b))
16462 return "All";
16463 else
16464 return "Bottom";
16465 }
16466 else
16467 {
16468 if (total > 1000000)
16469 /* Do it differently for a large value, to avoid overflow. */
16470 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16471 else
16472 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16473 /* We can't normally display a 3-digit number,
16474 so get us a 2-digit number that is close. */
16475 if (total == 100)
16476 total = 99;
16477 if (toppos <= BUF_BEGV (b))
16478 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16479 else
16480 sprintf (decode_mode_spec_buf, "%2d%%", total);
16481 return decode_mode_spec_buf;
16482 }
16483 }
16484
16485 case 's':
16486 /* status of process */
16487 obj = Fget_buffer_process (Fcurrent_buffer ());
16488 if (NILP (obj))
16489 return "no process";
16490 #ifdef subprocesses
16491 obj = Fsymbol_name (Fprocess_status (obj));
16492 #endif
16493 break;
16494
16495 case 't': /* indicate TEXT or BINARY */
16496 #ifdef MODE_LINE_BINARY_TEXT
16497 return MODE_LINE_BINARY_TEXT (b);
16498 #else
16499 return "T";
16500 #endif
16501
16502 case 'z':
16503 /* coding-system (not including end-of-line format) */
16504 case 'Z':
16505 /* coding-system (including end-of-line type) */
16506 {
16507 int eol_flag = (c == 'Z');
16508 char *p = decode_mode_spec_buf;
16509
16510 if (! FRAME_WINDOW_P (f))
16511 {
16512 /* No need to mention EOL here--the terminal never needs
16513 to do EOL conversion. */
16514 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16515 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16516 }
16517 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16518 p, eol_flag);
16519
16520 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16521 #ifdef subprocesses
16522 obj = Fget_buffer_process (Fcurrent_buffer ());
16523 if (PROCESSP (obj))
16524 {
16525 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16526 p, eol_flag);
16527 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16528 p, eol_flag);
16529 }
16530 #endif /* subprocesses */
16531 #endif /* 0 */
16532 *p = 0;
16533 return decode_mode_spec_buf;
16534 }
16535 }
16536
16537 if (STRINGP (obj))
16538 {
16539 *multibyte = STRING_MULTIBYTE (obj);
16540 return (char *) SDATA (obj);
16541 }
16542 else
16543 return "";
16544 }
16545
16546
16547 /* Count up to COUNT lines starting from START / START_BYTE.
16548 But don't go beyond LIMIT_BYTE.
16549 Return the number of lines thus found (always nonnegative).
16550
16551 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16552
16553 static int
16554 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16555 int start, start_byte, limit_byte, count;
16556 int *byte_pos_ptr;
16557 {
16558 register unsigned char *cursor;
16559 unsigned char *base;
16560
16561 register int ceiling;
16562 register unsigned char *ceiling_addr;
16563 int orig_count = count;
16564
16565 /* If we are not in selective display mode,
16566 check only for newlines. */
16567 int selective_display = (!NILP (current_buffer->selective_display)
16568 && !INTEGERP (current_buffer->selective_display));
16569
16570 if (count > 0)
16571 {
16572 while (start_byte < limit_byte)
16573 {
16574 ceiling = BUFFER_CEILING_OF (start_byte);
16575 ceiling = min (limit_byte - 1, ceiling);
16576 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16577 base = (cursor = BYTE_POS_ADDR (start_byte));
16578 while (1)
16579 {
16580 if (selective_display)
16581 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16582 ;
16583 else
16584 while (*cursor != '\n' && ++cursor != ceiling_addr)
16585 ;
16586
16587 if (cursor != ceiling_addr)
16588 {
16589 if (--count == 0)
16590 {
16591 start_byte += cursor - base + 1;
16592 *byte_pos_ptr = start_byte;
16593 return orig_count;
16594 }
16595 else
16596 if (++cursor == ceiling_addr)
16597 break;
16598 }
16599 else
16600 break;
16601 }
16602 start_byte += cursor - base;
16603 }
16604 }
16605 else
16606 {
16607 while (start_byte > limit_byte)
16608 {
16609 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16610 ceiling = max (limit_byte, ceiling);
16611 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16612 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16613 while (1)
16614 {
16615 if (selective_display)
16616 while (--cursor != ceiling_addr
16617 && *cursor != '\n' && *cursor != 015)
16618 ;
16619 else
16620 while (--cursor != ceiling_addr && *cursor != '\n')
16621 ;
16622
16623 if (cursor != ceiling_addr)
16624 {
16625 if (++count == 0)
16626 {
16627 start_byte += cursor - base + 1;
16628 *byte_pos_ptr = start_byte;
16629 /* When scanning backwards, we should
16630 not count the newline posterior to which we stop. */
16631 return - orig_count - 1;
16632 }
16633 }
16634 else
16635 break;
16636 }
16637 /* Here we add 1 to compensate for the last decrement
16638 of CURSOR, which took it past the valid range. */
16639 start_byte += cursor - base + 1;
16640 }
16641 }
16642
16643 *byte_pos_ptr = limit_byte;
16644
16645 if (count < 0)
16646 return - orig_count + count;
16647 return orig_count - count;
16648
16649 }
16650
16651
16652 \f
16653 /***********************************************************************
16654 Displaying strings
16655 ***********************************************************************/
16656
16657 /* Display a NUL-terminated string, starting with index START.
16658
16659 If STRING is non-null, display that C string. Otherwise, the Lisp
16660 string LISP_STRING is displayed.
16661
16662 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16663 FACE_STRING. Display STRING or LISP_STRING with the face at
16664 FACE_STRING_POS in FACE_STRING:
16665
16666 Display the string in the environment given by IT, but use the
16667 standard display table, temporarily.
16668
16669 FIELD_WIDTH is the minimum number of output glyphs to produce.
16670 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16671 with spaces. If STRING has more characters, more than FIELD_WIDTH
16672 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16673
16674 PRECISION is the maximum number of characters to output from
16675 STRING. PRECISION < 0 means don't truncate the string.
16676
16677 This is roughly equivalent to printf format specifiers:
16678
16679 FIELD_WIDTH PRECISION PRINTF
16680 ----------------------------------------
16681 -1 -1 %s
16682 -1 10 %.10s
16683 10 -1 %10s
16684 20 10 %20.10s
16685
16686 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16687 display them, and < 0 means obey the current buffer's value of
16688 enable_multibyte_characters.
16689
16690 Value is the number of glyphs produced. */
16691
16692 static int
16693 display_string (string, lisp_string, face_string, face_string_pos,
16694 start, it, field_width, precision, max_x, multibyte)
16695 unsigned char *string;
16696 Lisp_Object lisp_string;
16697 Lisp_Object face_string;
16698 int face_string_pos;
16699 int start;
16700 struct it *it;
16701 int field_width, precision, max_x;
16702 int multibyte;
16703 {
16704 int hpos_at_start = it->hpos;
16705 int saved_face_id = it->face_id;
16706 struct glyph_row *row = it->glyph_row;
16707
16708 /* Initialize the iterator IT for iteration over STRING beginning
16709 with index START. */
16710 reseat_to_string (it, string, lisp_string, start,
16711 precision, field_width, multibyte);
16712
16713 /* If displaying STRING, set up the face of the iterator
16714 from LISP_STRING, if that's given. */
16715 if (STRINGP (face_string))
16716 {
16717 int endptr;
16718 struct face *face;
16719
16720 it->face_id
16721 = face_at_string_position (it->w, face_string, face_string_pos,
16722 0, it->region_beg_charpos,
16723 it->region_end_charpos,
16724 &endptr, it->base_face_id, 0);
16725 face = FACE_FROM_ID (it->f, it->face_id);
16726 it->face_box_p = face->box != FACE_NO_BOX;
16727 }
16728
16729 /* Set max_x to the maximum allowed X position. Don't let it go
16730 beyond the right edge of the window. */
16731 if (max_x <= 0)
16732 max_x = it->last_visible_x;
16733 else
16734 max_x = min (max_x, it->last_visible_x);
16735
16736 /* Skip over display elements that are not visible. because IT->w is
16737 hscrolled. */
16738 if (it->current_x < it->first_visible_x)
16739 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16740 MOVE_TO_POS | MOVE_TO_X);
16741
16742 row->ascent = it->max_ascent;
16743 row->height = it->max_ascent + it->max_descent;
16744 row->phys_ascent = it->max_phys_ascent;
16745 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16746
16747 /* This condition is for the case that we are called with current_x
16748 past last_visible_x. */
16749 while (it->current_x < max_x)
16750 {
16751 int x_before, x, n_glyphs_before, i, nglyphs;
16752
16753 /* Get the next display element. */
16754 if (!get_next_display_element (it))
16755 break;
16756
16757 /* Produce glyphs. */
16758 x_before = it->current_x;
16759 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16760 PRODUCE_GLYPHS (it);
16761
16762 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16763 i = 0;
16764 x = x_before;
16765 while (i < nglyphs)
16766 {
16767 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16768
16769 if (!it->truncate_lines_p
16770 && x + glyph->pixel_width > max_x)
16771 {
16772 /* End of continued line or max_x reached. */
16773 if (CHAR_GLYPH_PADDING_P (*glyph))
16774 {
16775 /* A wide character is unbreakable. */
16776 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16777 it->current_x = x_before;
16778 }
16779 else
16780 {
16781 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16782 it->current_x = x;
16783 }
16784 break;
16785 }
16786 else if (x + glyph->pixel_width > it->first_visible_x)
16787 {
16788 /* Glyph is at least partially visible. */
16789 ++it->hpos;
16790 if (x < it->first_visible_x)
16791 it->glyph_row->x = x - it->first_visible_x;
16792 }
16793 else
16794 {
16795 /* Glyph is off the left margin of the display area.
16796 Should not happen. */
16797 abort ();
16798 }
16799
16800 row->ascent = max (row->ascent, it->max_ascent);
16801 row->height = max (row->height, it->max_ascent + it->max_descent);
16802 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16803 row->phys_height = max (row->phys_height,
16804 it->max_phys_ascent + it->max_phys_descent);
16805 x += glyph->pixel_width;
16806 ++i;
16807 }
16808
16809 /* Stop if max_x reached. */
16810 if (i < nglyphs)
16811 break;
16812
16813 /* Stop at line ends. */
16814 if (ITERATOR_AT_END_OF_LINE_P (it))
16815 {
16816 it->continuation_lines_width = 0;
16817 break;
16818 }
16819
16820 set_iterator_to_next (it, 1);
16821
16822 /* Stop if truncating at the right edge. */
16823 if (it->truncate_lines_p
16824 && it->current_x >= it->last_visible_x)
16825 {
16826 /* Add truncation mark, but don't do it if the line is
16827 truncated at a padding space. */
16828 if (IT_CHARPOS (*it) < it->string_nchars)
16829 {
16830 if (!FRAME_WINDOW_P (it->f))
16831 {
16832 int i, n;
16833
16834 if (it->current_x > it->last_visible_x)
16835 {
16836 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16837 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16838 break;
16839 for (n = row->used[TEXT_AREA]; i < n; ++i)
16840 {
16841 row->used[TEXT_AREA] = i;
16842 produce_special_glyphs (it, IT_TRUNCATION);
16843 }
16844 }
16845 produce_special_glyphs (it, IT_TRUNCATION);
16846 }
16847 it->glyph_row->truncated_on_right_p = 1;
16848 }
16849 break;
16850 }
16851 }
16852
16853 /* Maybe insert a truncation at the left. */
16854 if (it->first_visible_x
16855 && IT_CHARPOS (*it) > 0)
16856 {
16857 if (!FRAME_WINDOW_P (it->f))
16858 insert_left_trunc_glyphs (it);
16859 it->glyph_row->truncated_on_left_p = 1;
16860 }
16861
16862 it->face_id = saved_face_id;
16863
16864 /* Value is number of columns displayed. */
16865 return it->hpos - hpos_at_start;
16866 }
16867
16868
16869 \f
16870 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16871 appears as an element of LIST or as the car of an element of LIST.
16872 If PROPVAL is a list, compare each element against LIST in that
16873 way, and return 1/2 if any element of PROPVAL is found in LIST.
16874 Otherwise return 0. This function cannot quit.
16875 The return value is 2 if the text is invisible but with an ellipsis
16876 and 1 if it's invisible and without an ellipsis. */
16877
16878 int
16879 invisible_p (propval, list)
16880 register Lisp_Object propval;
16881 Lisp_Object list;
16882 {
16883 register Lisp_Object tail, proptail;
16884
16885 for (tail = list; CONSP (tail); tail = XCDR (tail))
16886 {
16887 register Lisp_Object tem;
16888 tem = XCAR (tail);
16889 if (EQ (propval, tem))
16890 return 1;
16891 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16892 return NILP (XCDR (tem)) ? 1 : 2;
16893 }
16894
16895 if (CONSP (propval))
16896 {
16897 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16898 {
16899 Lisp_Object propelt;
16900 propelt = XCAR (proptail);
16901 for (tail = list; CONSP (tail); tail = XCDR (tail))
16902 {
16903 register Lisp_Object tem;
16904 tem = XCAR (tail);
16905 if (EQ (propelt, tem))
16906 return 1;
16907 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16908 return NILP (XCDR (tem)) ? 1 : 2;
16909 }
16910 }
16911 }
16912
16913 return 0;
16914 }
16915
16916 /* Calculate a width or height in pixels from a specification using
16917 the following elements:
16918
16919 SPEC ::=
16920 NUM - a (fractional) multiple of the default font width/height
16921 (NUM) - specifies exactly NUM pixels
16922 UNIT - a fixed number of pixels, see below.
16923 ELEMENT - size of a display element in pixels, see below.
16924 (NUM . SPEC) - equals NUM * SPEC
16925 (+ SPEC SPEC ...) - add pixel values
16926 (- SPEC SPEC ...) - subtract pixel values
16927 (- SPEC) - negate pixel value
16928
16929 NUM ::=
16930 INT or FLOAT - a number constant
16931 SYMBOL - use symbol's (buffer local) variable binding.
16932
16933 UNIT ::=
16934 in - pixels per inch *)
16935 mm - pixels per 1/1000 meter *)
16936 cm - pixels per 1/100 meter *)
16937 width - width of current font in pixels.
16938 height - height of current font in pixels.
16939
16940 *) using the ratio(s) defined in display-pixels-per-inch.
16941
16942 ELEMENT ::=
16943
16944 left-fringe - left fringe width in pixels
16945 right-fringe - right fringe width in pixels
16946
16947 left-margin - left margin width in pixels
16948 right-margin - right margin width in pixels
16949
16950 scroll-bar - scroll-bar area width in pixels
16951
16952 Examples:
16953
16954 Pixels corresponding to 5 inches:
16955 (5 . in)
16956
16957 Total width of non-text areas on left side of window (if scroll-bar is on left):
16958 '(space :width (+ left-fringe left-margin scroll-bar))
16959
16960 Align to first text column (in header line):
16961 '(space :align-to 0)
16962
16963 Align to middle of text area minus half the width of variable `my-image'
16964 containing a loaded image:
16965 '(space :align-to (0.5 . (- text my-image)))
16966
16967 Width of left margin minus width of 1 character in the default font:
16968 '(space :width (- left-margin 1))
16969
16970 Width of left margin minus width of 2 characters in the current font:
16971 '(space :width (- left-margin (2 . width)))
16972
16973 Center 1 character over left-margin (in header line):
16974 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16975
16976 Different ways to express width of left fringe plus left margin minus one pixel:
16977 '(space :width (- (+ left-fringe left-margin) (1)))
16978 '(space :width (+ left-fringe left-margin (- (1))))
16979 '(space :width (+ left-fringe left-margin (-1)))
16980
16981 */
16982
16983 #define NUMVAL(X) \
16984 ((INTEGERP (X) || FLOATP (X)) \
16985 ? XFLOATINT (X) \
16986 : - 1)
16987
16988 int
16989 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
16990 double *res;
16991 struct it *it;
16992 Lisp_Object prop;
16993 void *font;
16994 int width_p, *align_to;
16995 {
16996 double pixels;
16997
16998 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16999 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17000
17001 if (NILP (prop))
17002 return OK_PIXELS (0);
17003
17004 if (SYMBOLP (prop))
17005 {
17006 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17007 {
17008 char *unit = SDATA (SYMBOL_NAME (prop));
17009
17010 if (unit[0] == 'i' && unit[1] == 'n')
17011 pixels = 1.0;
17012 else if (unit[0] == 'm' && unit[1] == 'm')
17013 pixels = 25.4;
17014 else if (unit[0] == 'c' && unit[1] == 'm')
17015 pixels = 2.54;
17016 else
17017 pixels = 0;
17018 if (pixels > 0)
17019 {
17020 double ppi;
17021 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17022 || (CONSP (Vdisplay_pixels_per_inch)
17023 && (ppi = (width_p
17024 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17025 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17026 ppi > 0)))
17027 return OK_PIXELS (ppi / pixels);
17028
17029 return 0;
17030 }
17031 }
17032
17033 #ifdef HAVE_WINDOW_SYSTEM
17034 if (EQ (prop, Qheight))
17035 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17036 if (EQ (prop, Qwidth))
17037 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17038 #else
17039 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17040 return OK_PIXELS (1);
17041 #endif
17042
17043 if (EQ (prop, Qtext))
17044 return OK_PIXELS (width_p
17045 ? window_box_width (it->w, TEXT_AREA)
17046 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17047
17048 if (align_to && *align_to < 0)
17049 {
17050 *res = 0;
17051 if (EQ (prop, Qleft))
17052 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17053 if (EQ (prop, Qright))
17054 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17055 if (EQ (prop, Qcenter))
17056 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17057 + window_box_width (it->w, TEXT_AREA) / 2);
17058 if (EQ (prop, Qleft_fringe))
17059 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17060 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17061 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17062 if (EQ (prop, Qright_fringe))
17063 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17064 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17065 : window_box_right_offset (it->w, TEXT_AREA));
17066 if (EQ (prop, Qleft_margin))
17067 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17068 if (EQ (prop, Qright_margin))
17069 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17070 if (EQ (prop, Qscroll_bar))
17071 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17072 ? 0
17073 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17074 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17075 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17076 : 0)));
17077 }
17078 else
17079 {
17080 if (EQ (prop, Qleft_fringe))
17081 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17082 if (EQ (prop, Qright_fringe))
17083 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17084 if (EQ (prop, Qleft_margin))
17085 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17086 if (EQ (prop, Qright_margin))
17087 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17088 if (EQ (prop, Qscroll_bar))
17089 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17090 }
17091
17092 prop = Fbuffer_local_value (prop, it->w->buffer);
17093 }
17094
17095 if (INTEGERP (prop) || FLOATP (prop))
17096 {
17097 int base_unit = (width_p
17098 ? FRAME_COLUMN_WIDTH (it->f)
17099 : FRAME_LINE_HEIGHT (it->f));
17100 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17101 }
17102
17103 if (CONSP (prop))
17104 {
17105 Lisp_Object car = XCAR (prop);
17106 Lisp_Object cdr = XCDR (prop);
17107
17108 if (SYMBOLP (car))
17109 {
17110 #ifdef HAVE_WINDOW_SYSTEM
17111 if (valid_image_p (prop))
17112 {
17113 int id = lookup_image (it->f, prop);
17114 struct image *img = IMAGE_FROM_ID (it->f, id);
17115
17116 return OK_PIXELS (width_p ? img->width : img->height);
17117 }
17118 #endif
17119 if (EQ (car, Qplus) || EQ (car, Qminus))
17120 {
17121 int first = 1;
17122 double px;
17123
17124 pixels = 0;
17125 while (CONSP (cdr))
17126 {
17127 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17128 font, width_p, align_to))
17129 return 0;
17130 if (first)
17131 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17132 else
17133 pixels += px;
17134 cdr = XCDR (cdr);
17135 }
17136 if (EQ (car, Qminus))
17137 pixels = -pixels;
17138 return OK_PIXELS (pixels);
17139 }
17140
17141 car = Fbuffer_local_value (car, it->w->buffer);
17142 }
17143
17144 if (INTEGERP (car) || FLOATP (car))
17145 {
17146 double fact;
17147 pixels = XFLOATINT (car);
17148 if (NILP (cdr))
17149 return OK_PIXELS (pixels);
17150 if (calc_pixel_width_or_height (&fact, it, cdr,
17151 font, width_p, align_to))
17152 return OK_PIXELS (pixels * fact);
17153 return 0;
17154 }
17155
17156 return 0;
17157 }
17158
17159 return 0;
17160 }
17161
17162 \f
17163 /***********************************************************************
17164 Glyph Display
17165 ***********************************************************************/
17166
17167 #ifdef HAVE_WINDOW_SYSTEM
17168
17169 #if GLYPH_DEBUG
17170
17171 void
17172 dump_glyph_string (s)
17173 struct glyph_string *s;
17174 {
17175 fprintf (stderr, "glyph string\n");
17176 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17177 s->x, s->y, s->width, s->height);
17178 fprintf (stderr, " ybase = %d\n", s->ybase);
17179 fprintf (stderr, " hl = %d\n", s->hl);
17180 fprintf (stderr, " left overhang = %d, right = %d\n",
17181 s->left_overhang, s->right_overhang);
17182 fprintf (stderr, " nchars = %d\n", s->nchars);
17183 fprintf (stderr, " extends to end of line = %d\n",
17184 s->extends_to_end_of_line_p);
17185 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17186 fprintf (stderr, " bg width = %d\n", s->background_width);
17187 }
17188
17189 #endif /* GLYPH_DEBUG */
17190
17191 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17192 of XChar2b structures for S; it can't be allocated in
17193 init_glyph_string because it must be allocated via `alloca'. W
17194 is the window on which S is drawn. ROW and AREA are the glyph row
17195 and area within the row from which S is constructed. START is the
17196 index of the first glyph structure covered by S. HL is a
17197 face-override for drawing S. */
17198
17199 #ifdef HAVE_NTGUI
17200 #define OPTIONAL_HDC(hdc) hdc,
17201 #define DECLARE_HDC(hdc) HDC hdc;
17202 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17203 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17204 #endif
17205
17206 #ifndef OPTIONAL_HDC
17207 #define OPTIONAL_HDC(hdc)
17208 #define DECLARE_HDC(hdc)
17209 #define ALLOCATE_HDC(hdc, f)
17210 #define RELEASE_HDC(hdc, f)
17211 #endif
17212
17213 static void
17214 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17215 struct glyph_string *s;
17216 DECLARE_HDC (hdc)
17217 XChar2b *char2b;
17218 struct window *w;
17219 struct glyph_row *row;
17220 enum glyph_row_area area;
17221 int start;
17222 enum draw_glyphs_face hl;
17223 {
17224 bzero (s, sizeof *s);
17225 s->w = w;
17226 s->f = XFRAME (w->frame);
17227 #ifdef HAVE_NTGUI
17228 s->hdc = hdc;
17229 #endif
17230 s->display = FRAME_X_DISPLAY (s->f);
17231 s->window = FRAME_X_WINDOW (s->f);
17232 s->char2b = char2b;
17233 s->hl = hl;
17234 s->row = row;
17235 s->area = area;
17236 s->first_glyph = row->glyphs[area] + start;
17237 s->height = row->height;
17238 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17239
17240 /* Display the internal border below the tool-bar window. */
17241 if (s->w == XWINDOW (s->f->tool_bar_window))
17242 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17243
17244 s->ybase = s->y + row->ascent;
17245 }
17246
17247
17248 /* Append the list of glyph strings with head H and tail T to the list
17249 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17250
17251 static INLINE void
17252 append_glyph_string_lists (head, tail, h, t)
17253 struct glyph_string **head, **tail;
17254 struct glyph_string *h, *t;
17255 {
17256 if (h)
17257 {
17258 if (*head)
17259 (*tail)->next = h;
17260 else
17261 *head = h;
17262 h->prev = *tail;
17263 *tail = t;
17264 }
17265 }
17266
17267
17268 /* Prepend the list of glyph strings with head H and tail T to the
17269 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17270 result. */
17271
17272 static INLINE void
17273 prepend_glyph_string_lists (head, tail, h, t)
17274 struct glyph_string **head, **tail;
17275 struct glyph_string *h, *t;
17276 {
17277 if (h)
17278 {
17279 if (*head)
17280 (*head)->prev = t;
17281 else
17282 *tail = t;
17283 t->next = *head;
17284 *head = h;
17285 }
17286 }
17287
17288
17289 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17290 Set *HEAD and *TAIL to the resulting list. */
17291
17292 static INLINE void
17293 append_glyph_string (head, tail, s)
17294 struct glyph_string **head, **tail;
17295 struct glyph_string *s;
17296 {
17297 s->next = s->prev = NULL;
17298 append_glyph_string_lists (head, tail, s, s);
17299 }
17300
17301
17302 /* Get face and two-byte form of character glyph GLYPH on frame F.
17303 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17304 a pointer to a realized face that is ready for display. */
17305
17306 static INLINE struct face *
17307 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17308 struct frame *f;
17309 struct glyph *glyph;
17310 XChar2b *char2b;
17311 int *two_byte_p;
17312 {
17313 struct face *face;
17314
17315 xassert (glyph->type == CHAR_GLYPH);
17316 face = FACE_FROM_ID (f, glyph->face_id);
17317
17318 if (two_byte_p)
17319 *two_byte_p = 0;
17320
17321 if (!glyph->multibyte_p)
17322 {
17323 /* Unibyte case. We don't have to encode, but we have to make
17324 sure to use a face suitable for unibyte. */
17325 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17326 }
17327 else if (glyph->u.ch < 128
17328 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17329 {
17330 /* Case of ASCII in a face known to fit ASCII. */
17331 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17332 }
17333 else
17334 {
17335 int c1, c2, charset;
17336
17337 /* Split characters into bytes. If c2 is -1 afterwards, C is
17338 really a one-byte character so that byte1 is zero. */
17339 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17340 if (c2 > 0)
17341 STORE_XCHAR2B (char2b, c1, c2);
17342 else
17343 STORE_XCHAR2B (char2b, 0, c1);
17344
17345 /* Maybe encode the character in *CHAR2B. */
17346 if (charset != CHARSET_ASCII)
17347 {
17348 struct font_info *font_info
17349 = FONT_INFO_FROM_ID (f, face->font_info_id);
17350 if (font_info)
17351 glyph->font_type
17352 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17353 }
17354 }
17355
17356 /* Make sure X resources of the face are allocated. */
17357 xassert (face != NULL);
17358 PREPARE_FACE_FOR_DISPLAY (f, face);
17359 return face;
17360 }
17361
17362
17363 /* Fill glyph string S with composition components specified by S->cmp.
17364
17365 FACES is an array of faces for all components of this composition.
17366 S->gidx is the index of the first component for S.
17367 OVERLAPS_P non-zero means S should draw the foreground only, and
17368 use its physical height for clipping.
17369
17370 Value is the index of a component not in S. */
17371
17372 static int
17373 fill_composite_glyph_string (s, faces, overlaps_p)
17374 struct glyph_string *s;
17375 struct face **faces;
17376 int overlaps_p;
17377 {
17378 int i;
17379
17380 xassert (s);
17381
17382 s->for_overlaps_p = overlaps_p;
17383
17384 s->face = faces[s->gidx];
17385 s->font = s->face->font;
17386 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17387
17388 /* For all glyphs of this composition, starting at the offset
17389 S->gidx, until we reach the end of the definition or encounter a
17390 glyph that requires the different face, add it to S. */
17391 ++s->nchars;
17392 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17393 ++s->nchars;
17394
17395 /* All glyph strings for the same composition has the same width,
17396 i.e. the width set for the first component of the composition. */
17397
17398 s->width = s->first_glyph->pixel_width;
17399
17400 /* If the specified font could not be loaded, use the frame's
17401 default font, but record the fact that we couldn't load it in
17402 the glyph string so that we can draw rectangles for the
17403 characters of the glyph string. */
17404 if (s->font == NULL)
17405 {
17406 s->font_not_found_p = 1;
17407 s->font = FRAME_FONT (s->f);
17408 }
17409
17410 /* Adjust base line for subscript/superscript text. */
17411 s->ybase += s->first_glyph->voffset;
17412
17413 xassert (s->face && s->face->gc);
17414
17415 /* This glyph string must always be drawn with 16-bit functions. */
17416 s->two_byte_p = 1;
17417
17418 return s->gidx + s->nchars;
17419 }
17420
17421
17422 /* Fill glyph string S from a sequence of character glyphs.
17423
17424 FACE_ID is the face id of the string. START is the index of the
17425 first glyph to consider, END is the index of the last + 1.
17426 OVERLAPS_P non-zero means S should draw the foreground only, and
17427 use its physical height for clipping.
17428
17429 Value is the index of the first glyph not in S. */
17430
17431 static int
17432 fill_glyph_string (s, face_id, start, end, overlaps_p)
17433 struct glyph_string *s;
17434 int face_id;
17435 int start, end, overlaps_p;
17436 {
17437 struct glyph *glyph, *last;
17438 int voffset;
17439 int glyph_not_available_p;
17440
17441 xassert (s->f == XFRAME (s->w->frame));
17442 xassert (s->nchars == 0);
17443 xassert (start >= 0 && end > start);
17444
17445 s->for_overlaps_p = overlaps_p,
17446 glyph = s->row->glyphs[s->area] + start;
17447 last = s->row->glyphs[s->area] + end;
17448 voffset = glyph->voffset;
17449
17450 glyph_not_available_p = glyph->glyph_not_available_p;
17451
17452 while (glyph < last
17453 && glyph->type == CHAR_GLYPH
17454 && glyph->voffset == voffset
17455 /* Same face id implies same font, nowadays. */
17456 && glyph->face_id == face_id
17457 && glyph->glyph_not_available_p == glyph_not_available_p)
17458 {
17459 int two_byte_p;
17460
17461 s->face = get_glyph_face_and_encoding (s->f, glyph,
17462 s->char2b + s->nchars,
17463 &two_byte_p);
17464 s->two_byte_p = two_byte_p;
17465 ++s->nchars;
17466 xassert (s->nchars <= end - start);
17467 s->width += glyph->pixel_width;
17468 ++glyph;
17469 }
17470
17471 s->font = s->face->font;
17472 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17473
17474 /* If the specified font could not be loaded, use the frame's font,
17475 but record the fact that we couldn't load it in
17476 S->font_not_found_p so that we can draw rectangles for the
17477 characters of the glyph string. */
17478 if (s->font == NULL || glyph_not_available_p)
17479 {
17480 s->font_not_found_p = 1;
17481 s->font = FRAME_FONT (s->f);
17482 }
17483
17484 /* Adjust base line for subscript/superscript text. */
17485 s->ybase += voffset;
17486
17487 xassert (s->face && s->face->gc);
17488 return glyph - s->row->glyphs[s->area];
17489 }
17490
17491
17492 /* Fill glyph string S from image glyph S->first_glyph. */
17493
17494 static void
17495 fill_image_glyph_string (s)
17496 struct glyph_string *s;
17497 {
17498 xassert (s->first_glyph->type == IMAGE_GLYPH);
17499 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17500 xassert (s->img);
17501 s->slice = s->first_glyph->slice;
17502 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17503 s->font = s->face->font;
17504 s->width = s->first_glyph->pixel_width;
17505
17506 /* Adjust base line for subscript/superscript text. */
17507 s->ybase += s->first_glyph->voffset;
17508 }
17509
17510
17511 /* Fill glyph string S from a sequence of stretch glyphs.
17512
17513 ROW is the glyph row in which the glyphs are found, AREA is the
17514 area within the row. START is the index of the first glyph to
17515 consider, END is the index of the last + 1.
17516
17517 Value is the index of the first glyph not in S. */
17518
17519 static int
17520 fill_stretch_glyph_string (s, row, area, start, end)
17521 struct glyph_string *s;
17522 struct glyph_row *row;
17523 enum glyph_row_area area;
17524 int start, end;
17525 {
17526 struct glyph *glyph, *last;
17527 int voffset, face_id;
17528
17529 xassert (s->first_glyph->type == STRETCH_GLYPH);
17530
17531 glyph = s->row->glyphs[s->area] + start;
17532 last = s->row->glyphs[s->area] + end;
17533 face_id = glyph->face_id;
17534 s->face = FACE_FROM_ID (s->f, face_id);
17535 s->font = s->face->font;
17536 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17537 s->width = glyph->pixel_width;
17538 voffset = glyph->voffset;
17539
17540 for (++glyph;
17541 (glyph < last
17542 && glyph->type == STRETCH_GLYPH
17543 && glyph->voffset == voffset
17544 && glyph->face_id == face_id);
17545 ++glyph)
17546 s->width += glyph->pixel_width;
17547
17548 /* Adjust base line for subscript/superscript text. */
17549 s->ybase += voffset;
17550
17551 /* The case that face->gc == 0 is handled when drawing the glyph
17552 string by calling PREPARE_FACE_FOR_DISPLAY. */
17553 xassert (s->face);
17554 return glyph - s->row->glyphs[s->area];
17555 }
17556
17557
17558 /* EXPORT for RIF:
17559 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17560 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17561 assumed to be zero. */
17562
17563 void
17564 x_get_glyph_overhangs (glyph, f, left, right)
17565 struct glyph *glyph;
17566 struct frame *f;
17567 int *left, *right;
17568 {
17569 *left = *right = 0;
17570
17571 if (glyph->type == CHAR_GLYPH)
17572 {
17573 XFontStruct *font;
17574 struct face *face;
17575 struct font_info *font_info;
17576 XChar2b char2b;
17577 XCharStruct *pcm;
17578
17579 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17580 font = face->font;
17581 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17582 if (font /* ++KFS: Should this be font_info ? */
17583 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17584 {
17585 if (pcm->rbearing > pcm->width)
17586 *right = pcm->rbearing - pcm->width;
17587 if (pcm->lbearing < 0)
17588 *left = -pcm->lbearing;
17589 }
17590 }
17591 }
17592
17593
17594 /* Return the index of the first glyph preceding glyph string S that
17595 is overwritten by S because of S's left overhang. Value is -1
17596 if no glyphs are overwritten. */
17597
17598 static int
17599 left_overwritten (s)
17600 struct glyph_string *s;
17601 {
17602 int k;
17603
17604 if (s->left_overhang)
17605 {
17606 int x = 0, i;
17607 struct glyph *glyphs = s->row->glyphs[s->area];
17608 int first = s->first_glyph - glyphs;
17609
17610 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17611 x -= glyphs[i].pixel_width;
17612
17613 k = i + 1;
17614 }
17615 else
17616 k = -1;
17617
17618 return k;
17619 }
17620
17621
17622 /* Return the index of the first glyph preceding glyph string S that
17623 is overwriting S because of its right overhang. Value is -1 if no
17624 glyph in front of S overwrites S. */
17625
17626 static int
17627 left_overwriting (s)
17628 struct glyph_string *s;
17629 {
17630 int i, k, x;
17631 struct glyph *glyphs = s->row->glyphs[s->area];
17632 int first = s->first_glyph - glyphs;
17633
17634 k = -1;
17635 x = 0;
17636 for (i = first - 1; i >= 0; --i)
17637 {
17638 int left, right;
17639 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17640 if (x + right > 0)
17641 k = i;
17642 x -= glyphs[i].pixel_width;
17643 }
17644
17645 return k;
17646 }
17647
17648
17649 /* Return the index of the last glyph following glyph string S that is
17650 not overwritten by S because of S's right overhang. Value is -1 if
17651 no such glyph is found. */
17652
17653 static int
17654 right_overwritten (s)
17655 struct glyph_string *s;
17656 {
17657 int k = -1;
17658
17659 if (s->right_overhang)
17660 {
17661 int x = 0, i;
17662 struct glyph *glyphs = s->row->glyphs[s->area];
17663 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17664 int end = s->row->used[s->area];
17665
17666 for (i = first; i < end && s->right_overhang > x; ++i)
17667 x += glyphs[i].pixel_width;
17668
17669 k = i;
17670 }
17671
17672 return k;
17673 }
17674
17675
17676 /* Return the index of the last glyph following glyph string S that
17677 overwrites S because of its left overhang. Value is negative
17678 if no such glyph is found. */
17679
17680 static int
17681 right_overwriting (s)
17682 struct glyph_string *s;
17683 {
17684 int i, k, x;
17685 int end = s->row->used[s->area];
17686 struct glyph *glyphs = s->row->glyphs[s->area];
17687 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17688
17689 k = -1;
17690 x = 0;
17691 for (i = first; i < end; ++i)
17692 {
17693 int left, right;
17694 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17695 if (x - left < 0)
17696 k = i;
17697 x += glyphs[i].pixel_width;
17698 }
17699
17700 return k;
17701 }
17702
17703
17704 /* Get face and two-byte form of character C in face FACE_ID on frame
17705 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17706 means we want to display multibyte text. DISPLAY_P non-zero means
17707 make sure that X resources for the face returned are allocated.
17708 Value is a pointer to a realized face that is ready for display if
17709 DISPLAY_P is non-zero. */
17710
17711 static INLINE struct face *
17712 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17713 struct frame *f;
17714 int c, face_id;
17715 XChar2b *char2b;
17716 int multibyte_p, display_p;
17717 {
17718 struct face *face = FACE_FROM_ID (f, face_id);
17719
17720 if (!multibyte_p)
17721 {
17722 /* Unibyte case. We don't have to encode, but we have to make
17723 sure to use a face suitable for unibyte. */
17724 STORE_XCHAR2B (char2b, 0, c);
17725 face_id = FACE_FOR_CHAR (f, face, c);
17726 face = FACE_FROM_ID (f, face_id);
17727 }
17728 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17729 {
17730 /* Case of ASCII in a face known to fit ASCII. */
17731 STORE_XCHAR2B (char2b, 0, c);
17732 }
17733 else
17734 {
17735 int c1, c2, charset;
17736
17737 /* Split characters into bytes. If c2 is -1 afterwards, C is
17738 really a one-byte character so that byte1 is zero. */
17739 SPLIT_CHAR (c, charset, c1, c2);
17740 if (c2 > 0)
17741 STORE_XCHAR2B (char2b, c1, c2);
17742 else
17743 STORE_XCHAR2B (char2b, 0, c1);
17744
17745 /* Maybe encode the character in *CHAR2B. */
17746 if (face->font != NULL)
17747 {
17748 struct font_info *font_info
17749 = FONT_INFO_FROM_ID (f, face->font_info_id);
17750 if (font_info)
17751 rif->encode_char (c, char2b, font_info, 0);
17752 }
17753 }
17754
17755 /* Make sure X resources of the face are allocated. */
17756 #ifdef HAVE_X_WINDOWS
17757 if (display_p)
17758 #endif
17759 {
17760 xassert (face != NULL);
17761 PREPARE_FACE_FOR_DISPLAY (f, face);
17762 }
17763
17764 return face;
17765 }
17766
17767
17768 /* Set background width of glyph string S. START is the index of the
17769 first glyph following S. LAST_X is the right-most x-position + 1
17770 in the drawing area. */
17771
17772 static INLINE void
17773 set_glyph_string_background_width (s, start, last_x)
17774 struct glyph_string *s;
17775 int start;
17776 int last_x;
17777 {
17778 /* If the face of this glyph string has to be drawn to the end of
17779 the drawing area, set S->extends_to_end_of_line_p. */
17780 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17781
17782 if (start == s->row->used[s->area]
17783 && s->area == TEXT_AREA
17784 && ((s->hl == DRAW_NORMAL_TEXT
17785 && (s->row->fill_line_p
17786 || s->face->background != default_face->background
17787 || s->face->stipple != default_face->stipple
17788 || s->row->mouse_face_p))
17789 || s->hl == DRAW_MOUSE_FACE
17790 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17791 && s->row->fill_line_p)))
17792 s->extends_to_end_of_line_p = 1;
17793
17794 /* If S extends its face to the end of the line, set its
17795 background_width to the distance to the right edge of the drawing
17796 area. */
17797 if (s->extends_to_end_of_line_p)
17798 s->background_width = last_x - s->x + 1;
17799 else
17800 s->background_width = s->width;
17801 }
17802
17803
17804 /* Compute overhangs and x-positions for glyph string S and its
17805 predecessors, or successors. X is the starting x-position for S.
17806 BACKWARD_P non-zero means process predecessors. */
17807
17808 static void
17809 compute_overhangs_and_x (s, x, backward_p)
17810 struct glyph_string *s;
17811 int x;
17812 int backward_p;
17813 {
17814 if (backward_p)
17815 {
17816 while (s)
17817 {
17818 if (rif->compute_glyph_string_overhangs)
17819 rif->compute_glyph_string_overhangs (s);
17820 x -= s->width;
17821 s->x = x;
17822 s = s->prev;
17823 }
17824 }
17825 else
17826 {
17827 while (s)
17828 {
17829 if (rif->compute_glyph_string_overhangs)
17830 rif->compute_glyph_string_overhangs (s);
17831 s->x = x;
17832 x += s->width;
17833 s = s->next;
17834 }
17835 }
17836 }
17837
17838
17839
17840 /* The following macros are only called from draw_glyphs below.
17841 They reference the following parameters of that function directly:
17842 `w', `row', `area', and `overlap_p'
17843 as well as the following local variables:
17844 `s', `f', and `hdc' (in W32) */
17845
17846 #ifdef HAVE_NTGUI
17847 /* On W32, silently add local `hdc' variable to argument list of
17848 init_glyph_string. */
17849 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17850 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17851 #else
17852 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17853 init_glyph_string (s, char2b, w, row, area, start, hl)
17854 #endif
17855
17856 /* Add a glyph string for a stretch glyph to the list of strings
17857 between HEAD and TAIL. START is the index of the stretch glyph in
17858 row area AREA of glyph row ROW. END is the index of the last glyph
17859 in that glyph row area. X is the current output position assigned
17860 to the new glyph string constructed. HL overrides that face of the
17861 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17862 is the right-most x-position of the drawing area. */
17863
17864 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17865 and below -- keep them on one line. */
17866 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17867 do \
17868 { \
17869 s = (struct glyph_string *) alloca (sizeof *s); \
17870 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17871 START = fill_stretch_glyph_string (s, row, area, START, END); \
17872 append_glyph_string (&HEAD, &TAIL, s); \
17873 s->x = (X); \
17874 } \
17875 while (0)
17876
17877
17878 /* Add a glyph string for an image glyph to the list of strings
17879 between HEAD and TAIL. START is the index of the image glyph in
17880 row area AREA of glyph row ROW. END is the index of the last glyph
17881 in that glyph row area. X is the current output position assigned
17882 to the new glyph string constructed. HL overrides that face of the
17883 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17884 is the right-most x-position of the drawing area. */
17885
17886 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17887 do \
17888 { \
17889 s = (struct glyph_string *) alloca (sizeof *s); \
17890 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17891 fill_image_glyph_string (s); \
17892 append_glyph_string (&HEAD, &TAIL, s); \
17893 ++START; \
17894 s->x = (X); \
17895 } \
17896 while (0)
17897
17898
17899 /* Add a glyph string for a sequence of character glyphs to the list
17900 of strings between HEAD and TAIL. START is the index of the first
17901 glyph in row area AREA of glyph row ROW that is part of the new
17902 glyph string. END is the index of the last glyph in that glyph row
17903 area. X is the current output position assigned to the new glyph
17904 string constructed. HL overrides that face of the glyph; e.g. it
17905 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17906 right-most x-position of the drawing area. */
17907
17908 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17909 do \
17910 { \
17911 int c, face_id; \
17912 XChar2b *char2b; \
17913 \
17914 c = (row)->glyphs[area][START].u.ch; \
17915 face_id = (row)->glyphs[area][START].face_id; \
17916 \
17917 s = (struct glyph_string *) alloca (sizeof *s); \
17918 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17919 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17920 append_glyph_string (&HEAD, &TAIL, s); \
17921 s->x = (X); \
17922 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17923 } \
17924 while (0)
17925
17926
17927 /* Add a glyph string for a composite sequence to the list of strings
17928 between HEAD and TAIL. START is the index of the first glyph in
17929 row area AREA of glyph row ROW that is part of the new glyph
17930 string. END is the index of the last glyph in that glyph row area.
17931 X is the current output position assigned to the new glyph string
17932 constructed. HL overrides that face of the glyph; e.g. it is
17933 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17934 x-position of the drawing area. */
17935
17936 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17937 do { \
17938 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17939 int face_id = (row)->glyphs[area][START].face_id; \
17940 struct face *base_face = FACE_FROM_ID (f, face_id); \
17941 struct composition *cmp = composition_table[cmp_id]; \
17942 int glyph_len = cmp->glyph_len; \
17943 XChar2b *char2b; \
17944 struct face **faces; \
17945 struct glyph_string *first_s = NULL; \
17946 int n; \
17947 \
17948 base_face = base_face->ascii_face; \
17949 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17950 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17951 /* At first, fill in `char2b' and `faces'. */ \
17952 for (n = 0; n < glyph_len; n++) \
17953 { \
17954 int c = COMPOSITION_GLYPH (cmp, n); \
17955 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17956 faces[n] = FACE_FROM_ID (f, this_face_id); \
17957 get_char_face_and_encoding (f, c, this_face_id, \
17958 char2b + n, 1, 1); \
17959 } \
17960 \
17961 /* Make glyph_strings for each glyph sequence that is drawable by \
17962 the same face, and append them to HEAD/TAIL. */ \
17963 for (n = 0; n < cmp->glyph_len;) \
17964 { \
17965 s = (struct glyph_string *) alloca (sizeof *s); \
17966 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17967 append_glyph_string (&(HEAD), &(TAIL), s); \
17968 s->cmp = cmp; \
17969 s->gidx = n; \
17970 s->x = (X); \
17971 \
17972 if (n == 0) \
17973 first_s = s; \
17974 \
17975 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17976 } \
17977 \
17978 ++START; \
17979 s = first_s; \
17980 } while (0)
17981
17982
17983 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17984 of AREA of glyph row ROW on window W between indices START and END.
17985 HL overrides the face for drawing glyph strings, e.g. it is
17986 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17987 x-positions of the drawing area.
17988
17989 This is an ugly monster macro construct because we must use alloca
17990 to allocate glyph strings (because draw_glyphs can be called
17991 asynchronously). */
17992
17993 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17994 do \
17995 { \
17996 HEAD = TAIL = NULL; \
17997 while (START < END) \
17998 { \
17999 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18000 switch (first_glyph->type) \
18001 { \
18002 case CHAR_GLYPH: \
18003 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18004 HL, X, LAST_X); \
18005 break; \
18006 \
18007 case COMPOSITE_GLYPH: \
18008 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18009 HL, X, LAST_X); \
18010 break; \
18011 \
18012 case STRETCH_GLYPH: \
18013 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18014 HL, X, LAST_X); \
18015 break; \
18016 \
18017 case IMAGE_GLYPH: \
18018 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18019 HL, X, LAST_X); \
18020 break; \
18021 \
18022 default: \
18023 abort (); \
18024 } \
18025 \
18026 set_glyph_string_background_width (s, START, LAST_X); \
18027 (X) += s->width; \
18028 } \
18029 } \
18030 while (0)
18031
18032
18033 /* Draw glyphs between START and END in AREA of ROW on window W,
18034 starting at x-position X. X is relative to AREA in W. HL is a
18035 face-override with the following meaning:
18036
18037 DRAW_NORMAL_TEXT draw normally
18038 DRAW_CURSOR draw in cursor face
18039 DRAW_MOUSE_FACE draw in mouse face.
18040 DRAW_INVERSE_VIDEO draw in mode line face
18041 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18042 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18043
18044 If OVERLAPS_P is non-zero, draw only the foreground of characters
18045 and clip to the physical height of ROW.
18046
18047 Value is the x-position reached, relative to AREA of W. */
18048
18049 static int
18050 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18051 struct window *w;
18052 int x;
18053 struct glyph_row *row;
18054 enum glyph_row_area area;
18055 int start, end;
18056 enum draw_glyphs_face hl;
18057 int overlaps_p;
18058 {
18059 struct glyph_string *head, *tail;
18060 struct glyph_string *s;
18061 int last_x, area_width;
18062 int x_reached;
18063 int i, j;
18064 struct frame *f = XFRAME (WINDOW_FRAME (w));
18065 DECLARE_HDC (hdc);
18066
18067 ALLOCATE_HDC (hdc, f);
18068
18069 /* Let's rather be paranoid than getting a SEGV. */
18070 end = min (end, row->used[area]);
18071 start = max (0, start);
18072 start = min (end, start);
18073
18074 /* Translate X to frame coordinates. Set last_x to the right
18075 end of the drawing area. */
18076 if (row->full_width_p)
18077 {
18078 /* X is relative to the left edge of W, without scroll bars
18079 or fringes. */
18080 x += WINDOW_LEFT_EDGE_X (w);
18081 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18082 }
18083 else
18084 {
18085 int area_left = window_box_left (w, area);
18086 x += area_left;
18087 area_width = window_box_width (w, area);
18088 last_x = area_left + area_width;
18089 }
18090
18091 /* Build a doubly-linked list of glyph_string structures between
18092 head and tail from what we have to draw. Note that the macro
18093 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18094 the reason we use a separate variable `i'. */
18095 i = start;
18096 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18097 if (tail)
18098 x_reached = tail->x + tail->background_width;
18099 else
18100 x_reached = x;
18101
18102 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18103 the row, redraw some glyphs in front or following the glyph
18104 strings built above. */
18105 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18106 {
18107 int dummy_x = 0;
18108 struct glyph_string *h, *t;
18109
18110 /* Compute overhangs for all glyph strings. */
18111 if (rif->compute_glyph_string_overhangs)
18112 for (s = head; s; s = s->next)
18113 rif->compute_glyph_string_overhangs (s);
18114
18115 /* Prepend glyph strings for glyphs in front of the first glyph
18116 string that are overwritten because of the first glyph
18117 string's left overhang. The background of all strings
18118 prepended must be drawn because the first glyph string
18119 draws over it. */
18120 i = left_overwritten (head);
18121 if (i >= 0)
18122 {
18123 j = i;
18124 BUILD_GLYPH_STRINGS (j, start, h, t,
18125 DRAW_NORMAL_TEXT, dummy_x, last_x);
18126 start = i;
18127 compute_overhangs_and_x (t, head->x, 1);
18128 prepend_glyph_string_lists (&head, &tail, h, t);
18129 }
18130
18131 /* Prepend glyph strings for glyphs in front of the first glyph
18132 string that overwrite that glyph string because of their
18133 right overhang. For these strings, only the foreground must
18134 be drawn, because it draws over the glyph string at `head'.
18135 The background must not be drawn because this would overwrite
18136 right overhangs of preceding glyphs for which no glyph
18137 strings exist. */
18138 i = left_overwriting (head);
18139 if (i >= 0)
18140 {
18141 BUILD_GLYPH_STRINGS (i, start, h, t,
18142 DRAW_NORMAL_TEXT, dummy_x, last_x);
18143 for (s = h; s; s = s->next)
18144 s->background_filled_p = 1;
18145 compute_overhangs_and_x (t, head->x, 1);
18146 prepend_glyph_string_lists (&head, &tail, h, t);
18147 }
18148
18149 /* Append glyphs strings for glyphs following the last glyph
18150 string tail that are overwritten by tail. The background of
18151 these strings has to be drawn because tail's foreground draws
18152 over it. */
18153 i = right_overwritten (tail);
18154 if (i >= 0)
18155 {
18156 BUILD_GLYPH_STRINGS (end, i, h, t,
18157 DRAW_NORMAL_TEXT, x, last_x);
18158 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18159 append_glyph_string_lists (&head, &tail, h, t);
18160 }
18161
18162 /* Append glyph strings for glyphs following the last glyph
18163 string tail that overwrite tail. The foreground of such
18164 glyphs has to be drawn because it writes into the background
18165 of tail. The background must not be drawn because it could
18166 paint over the foreground of following glyphs. */
18167 i = right_overwriting (tail);
18168 if (i >= 0)
18169 {
18170 BUILD_GLYPH_STRINGS (end, i, h, t,
18171 DRAW_NORMAL_TEXT, x, last_x);
18172 for (s = h; s; s = s->next)
18173 s->background_filled_p = 1;
18174 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18175 append_glyph_string_lists (&head, &tail, h, t);
18176 }
18177 }
18178
18179 /* Draw all strings. */
18180 for (s = head; s; s = s->next)
18181 rif->draw_glyph_string (s);
18182
18183 if (area == TEXT_AREA
18184 && !row->full_width_p
18185 /* When drawing overlapping rows, only the glyph strings'
18186 foreground is drawn, which doesn't erase a cursor
18187 completely. */
18188 && !overlaps_p)
18189 {
18190 int x0 = head ? head->x : x;
18191 int x1 = tail ? tail->x + tail->background_width : x;
18192
18193 int text_left = window_box_left (w, TEXT_AREA);
18194 x0 -= text_left;
18195 x1 -= text_left;
18196
18197 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18198 row->y, MATRIX_ROW_BOTTOM_Y (row));
18199 }
18200
18201 /* Value is the x-position up to which drawn, relative to AREA of W.
18202 This doesn't include parts drawn because of overhangs. */
18203 if (row->full_width_p)
18204 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18205 else
18206 x_reached -= window_box_left (w, area);
18207
18208 RELEASE_HDC (hdc, f);
18209
18210 return x_reached;
18211 }
18212
18213
18214 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18215 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18216
18217 static INLINE void
18218 append_glyph (it)
18219 struct it *it;
18220 {
18221 struct glyph *glyph;
18222 enum glyph_row_area area = it->area;
18223
18224 xassert (it->glyph_row);
18225 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18226
18227 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18228 if (glyph < it->glyph_row->glyphs[area + 1])
18229 {
18230 glyph->charpos = CHARPOS (it->position);
18231 glyph->object = it->object;
18232 glyph->pixel_width = it->pixel_width;
18233 glyph->ascent = it->ascent;
18234 glyph->descent = it->descent;
18235 glyph->voffset = it->voffset;
18236 glyph->type = CHAR_GLYPH;
18237 glyph->multibyte_p = it->multibyte_p;
18238 glyph->left_box_line_p = it->start_of_box_run_p;
18239 glyph->right_box_line_p = it->end_of_box_run_p;
18240 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18241 || it->phys_descent > it->descent);
18242 glyph->padding_p = 0;
18243 glyph->glyph_not_available_p = it->glyph_not_available_p;
18244 glyph->face_id = it->face_id;
18245 glyph->u.ch = it->char_to_display;
18246 glyph->slice = null_glyph_slice;
18247 glyph->font_type = FONT_TYPE_UNKNOWN;
18248 ++it->glyph_row->used[area];
18249 }
18250 else if (!fonts_changed_p)
18251 {
18252 it->w->ncols_scale_factor++;
18253 fonts_changed_p = 1;
18254 }
18255 }
18256
18257 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18258 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18259
18260 static INLINE void
18261 append_composite_glyph (it)
18262 struct it *it;
18263 {
18264 struct glyph *glyph;
18265 enum glyph_row_area area = it->area;
18266
18267 xassert (it->glyph_row);
18268
18269 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18270 if (glyph < it->glyph_row->glyphs[area + 1])
18271 {
18272 glyph->charpos = CHARPOS (it->position);
18273 glyph->object = it->object;
18274 glyph->pixel_width = it->pixel_width;
18275 glyph->ascent = it->ascent;
18276 glyph->descent = it->descent;
18277 glyph->voffset = it->voffset;
18278 glyph->type = COMPOSITE_GLYPH;
18279 glyph->multibyte_p = it->multibyte_p;
18280 glyph->left_box_line_p = it->start_of_box_run_p;
18281 glyph->right_box_line_p = it->end_of_box_run_p;
18282 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18283 || it->phys_descent > it->descent);
18284 glyph->padding_p = 0;
18285 glyph->glyph_not_available_p = 0;
18286 glyph->face_id = it->face_id;
18287 glyph->u.cmp_id = it->cmp_id;
18288 glyph->slice = null_glyph_slice;
18289 glyph->font_type = FONT_TYPE_UNKNOWN;
18290 ++it->glyph_row->used[area];
18291 }
18292 else if (!fonts_changed_p)
18293 {
18294 it->w->ncols_scale_factor++;
18295 fonts_changed_p = 1;
18296 }
18297 }
18298
18299
18300 /* Change IT->ascent and IT->height according to the setting of
18301 IT->voffset. */
18302
18303 static INLINE void
18304 take_vertical_position_into_account (it)
18305 struct it *it;
18306 {
18307 if (it->voffset)
18308 {
18309 if (it->voffset < 0)
18310 /* Increase the ascent so that we can display the text higher
18311 in the line. */
18312 it->ascent -= it->voffset;
18313 else
18314 /* Increase the descent so that we can display the text lower
18315 in the line. */
18316 it->descent += it->voffset;
18317 }
18318 }
18319
18320
18321 /* Produce glyphs/get display metrics for the image IT is loaded with.
18322 See the description of struct display_iterator in dispextern.h for
18323 an overview of struct display_iterator. */
18324
18325 static void
18326 produce_image_glyph (it)
18327 struct it *it;
18328 {
18329 struct image *img;
18330 struct face *face;
18331 int face_ascent, glyph_ascent;
18332 struct glyph_slice slice;
18333
18334 xassert (it->what == IT_IMAGE);
18335
18336 face = FACE_FROM_ID (it->f, it->face_id);
18337 xassert (face);
18338 /* Make sure X resources of the face is loaded. */
18339 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18340
18341 if (it->image_id < 0)
18342 {
18343 /* Fringe bitmap. */
18344 it->ascent = it->phys_ascent = 0;
18345 it->descent = it->phys_descent = 0;
18346 it->pixel_width = 0;
18347 it->nglyphs = 0;
18348 return;
18349 }
18350
18351 img = IMAGE_FROM_ID (it->f, it->image_id);
18352 xassert (img);
18353 /* Make sure X resources of the image is loaded. */
18354 prepare_image_for_display (it->f, img);
18355
18356 slice.x = slice.y = 0;
18357 slice.width = img->width;
18358 slice.height = img->height;
18359
18360 if (INTEGERP (it->slice.x))
18361 slice.x = XINT (it->slice.x);
18362 else if (FLOATP (it->slice.x))
18363 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18364
18365 if (INTEGERP (it->slice.y))
18366 slice.y = XINT (it->slice.y);
18367 else if (FLOATP (it->slice.y))
18368 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18369
18370 if (INTEGERP (it->slice.width))
18371 slice.width = XINT (it->slice.width);
18372 else if (FLOATP (it->slice.width))
18373 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18374
18375 if (INTEGERP (it->slice.height))
18376 slice.height = XINT (it->slice.height);
18377 else if (FLOATP (it->slice.height))
18378 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18379
18380 if (slice.x >= img->width)
18381 slice.x = img->width;
18382 if (slice.y >= img->height)
18383 slice.y = img->height;
18384 if (slice.x + slice.width >= img->width)
18385 slice.width = img->width - slice.x;
18386 if (slice.y + slice.height > img->height)
18387 slice.height = img->height - slice.y;
18388
18389 if (slice.width == 0 || slice.height == 0)
18390 return;
18391
18392 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18393
18394 it->descent = slice.height - glyph_ascent;
18395 if (slice.y == 0)
18396 it->descent += img->vmargin;
18397 if (slice.y + slice.height == img->height)
18398 it->descent += img->vmargin;
18399 it->phys_descent = it->descent;
18400
18401 it->pixel_width = slice.width;
18402 if (slice.x == 0)
18403 it->pixel_width += img->hmargin;
18404 if (slice.x + slice.width == img->width)
18405 it->pixel_width += img->hmargin;
18406
18407 /* It's quite possible for images to have an ascent greater than
18408 their height, so don't get confused in that case. */
18409 if (it->descent < 0)
18410 it->descent = 0;
18411
18412 #if 0 /* this breaks image tiling */
18413 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18414 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18415 if (face_ascent > it->ascent)
18416 it->ascent = it->phys_ascent = face_ascent;
18417 #endif
18418
18419 it->nglyphs = 1;
18420
18421 if (face->box != FACE_NO_BOX)
18422 {
18423 if (face->box_line_width > 0)
18424 {
18425 if (slice.y == 0)
18426 it->ascent += face->box_line_width;
18427 if (slice.y + slice.height == img->height)
18428 it->descent += face->box_line_width;
18429 }
18430
18431 if (it->start_of_box_run_p && slice.x == 0)
18432 it->pixel_width += abs (face->box_line_width);
18433 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18434 it->pixel_width += abs (face->box_line_width);
18435 }
18436
18437 take_vertical_position_into_account (it);
18438
18439 if (it->glyph_row)
18440 {
18441 struct glyph *glyph;
18442 enum glyph_row_area area = it->area;
18443
18444 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18445 if (glyph < it->glyph_row->glyphs[area + 1])
18446 {
18447 glyph->charpos = CHARPOS (it->position);
18448 glyph->object = it->object;
18449 glyph->pixel_width = it->pixel_width;
18450 glyph->ascent = glyph_ascent;
18451 glyph->descent = it->descent;
18452 glyph->voffset = it->voffset;
18453 glyph->type = IMAGE_GLYPH;
18454 glyph->multibyte_p = it->multibyte_p;
18455 glyph->left_box_line_p = it->start_of_box_run_p;
18456 glyph->right_box_line_p = it->end_of_box_run_p;
18457 glyph->overlaps_vertically_p = 0;
18458 glyph->padding_p = 0;
18459 glyph->glyph_not_available_p = 0;
18460 glyph->face_id = it->face_id;
18461 glyph->u.img_id = img->id;
18462 glyph->slice = slice;
18463 glyph->font_type = FONT_TYPE_UNKNOWN;
18464 ++it->glyph_row->used[area];
18465 }
18466 else if (!fonts_changed_p)
18467 {
18468 it->w->ncols_scale_factor++;
18469 fonts_changed_p = 1;
18470 }
18471 }
18472 }
18473
18474
18475 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18476 of the glyph, WIDTH and HEIGHT are the width and height of the
18477 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18478
18479 static void
18480 append_stretch_glyph (it, object, width, height, ascent)
18481 struct it *it;
18482 Lisp_Object object;
18483 int width, height;
18484 int ascent;
18485 {
18486 struct glyph *glyph;
18487 enum glyph_row_area area = it->area;
18488
18489 xassert (ascent >= 0 && ascent <= height);
18490
18491 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18492 if (glyph < it->glyph_row->glyphs[area + 1])
18493 {
18494 glyph->charpos = CHARPOS (it->position);
18495 glyph->object = object;
18496 glyph->pixel_width = width;
18497 glyph->ascent = ascent;
18498 glyph->descent = height - ascent;
18499 glyph->voffset = it->voffset;
18500 glyph->type = STRETCH_GLYPH;
18501 glyph->multibyte_p = it->multibyte_p;
18502 glyph->left_box_line_p = it->start_of_box_run_p;
18503 glyph->right_box_line_p = it->end_of_box_run_p;
18504 glyph->overlaps_vertically_p = 0;
18505 glyph->padding_p = 0;
18506 glyph->glyph_not_available_p = 0;
18507 glyph->face_id = it->face_id;
18508 glyph->u.stretch.ascent = ascent;
18509 glyph->u.stretch.height = height;
18510 glyph->slice = null_glyph_slice;
18511 glyph->font_type = FONT_TYPE_UNKNOWN;
18512 ++it->glyph_row->used[area];
18513 }
18514 else if (!fonts_changed_p)
18515 {
18516 it->w->ncols_scale_factor++;
18517 fonts_changed_p = 1;
18518 }
18519 }
18520
18521
18522 /* Produce a stretch glyph for iterator IT. IT->object is the value
18523 of the glyph property displayed. The value must be a list
18524 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18525 being recognized:
18526
18527 1. `:width WIDTH' specifies that the space should be WIDTH *
18528 canonical char width wide. WIDTH may be an integer or floating
18529 point number.
18530
18531 2. `:relative-width FACTOR' specifies that the width of the stretch
18532 should be computed from the width of the first character having the
18533 `glyph' property, and should be FACTOR times that width.
18534
18535 3. `:align-to HPOS' specifies that the space should be wide enough
18536 to reach HPOS, a value in canonical character units.
18537
18538 Exactly one of the above pairs must be present.
18539
18540 4. `:height HEIGHT' specifies that the height of the stretch produced
18541 should be HEIGHT, measured in canonical character units.
18542
18543 5. `:relative-height FACTOR' specifies that the height of the
18544 stretch should be FACTOR times the height of the characters having
18545 the glyph property.
18546
18547 Either none or exactly one of 4 or 5 must be present.
18548
18549 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18550 of the stretch should be used for the ascent of the stretch.
18551 ASCENT must be in the range 0 <= ASCENT <= 100. */
18552
18553 static void
18554 produce_stretch_glyph (it)
18555 struct it *it;
18556 {
18557 /* (space :width WIDTH :height HEIGHT ...) */
18558 Lisp_Object prop, plist;
18559 int width = 0, height = 0, align_to = -1;
18560 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18561 int ascent = 0;
18562 double tem;
18563 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18564 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18565
18566 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18567
18568 /* List should start with `space'. */
18569 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18570 plist = XCDR (it->object);
18571
18572 /* Compute the width of the stretch. */
18573 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18574 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18575 {
18576 /* Absolute width `:width WIDTH' specified and valid. */
18577 zero_width_ok_p = 1;
18578 width = (int)tem;
18579 }
18580 else if (prop = Fplist_get (plist, QCrelative_width),
18581 NUMVAL (prop) > 0)
18582 {
18583 /* Relative width `:relative-width FACTOR' specified and valid.
18584 Compute the width of the characters having the `glyph'
18585 property. */
18586 struct it it2;
18587 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18588
18589 it2 = *it;
18590 if (it->multibyte_p)
18591 {
18592 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18593 - IT_BYTEPOS (*it));
18594 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18595 }
18596 else
18597 it2.c = *p, it2.len = 1;
18598
18599 it2.glyph_row = NULL;
18600 it2.what = IT_CHARACTER;
18601 x_produce_glyphs (&it2);
18602 width = NUMVAL (prop) * it2.pixel_width;
18603 }
18604 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18605 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18606 {
18607 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18608 align_to = (align_to < 0
18609 ? 0
18610 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18611 else if (align_to < 0)
18612 align_to = window_box_left_offset (it->w, TEXT_AREA);
18613 width = max (0, (int)tem + align_to - it->current_x);
18614 zero_width_ok_p = 1;
18615 }
18616 else
18617 /* Nothing specified -> width defaults to canonical char width. */
18618 width = FRAME_COLUMN_WIDTH (it->f);
18619
18620 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18621 width = 1;
18622
18623 /* Compute height. */
18624 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18625 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18626 {
18627 height = (int)tem;
18628 zero_height_ok_p = 1;
18629 }
18630 else if (prop = Fplist_get (plist, QCrelative_height),
18631 NUMVAL (prop) > 0)
18632 height = FONT_HEIGHT (font) * NUMVAL (prop);
18633 else
18634 height = FONT_HEIGHT (font);
18635
18636 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18637 height = 1;
18638
18639 /* Compute percentage of height used for ascent. If
18640 `:ascent ASCENT' is present and valid, use that. Otherwise,
18641 derive the ascent from the font in use. */
18642 if (prop = Fplist_get (plist, QCascent),
18643 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18644 ascent = height * NUMVAL (prop) / 100.0;
18645 else if (!NILP (prop)
18646 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18647 ascent = min (max (0, (int)tem), height);
18648 else
18649 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18650
18651 if (width > 0 && height > 0 && it->glyph_row)
18652 {
18653 Lisp_Object object = it->stack[it->sp - 1].string;
18654 if (!STRINGP (object))
18655 object = it->w->buffer;
18656 append_stretch_glyph (it, object, width, height, ascent);
18657 }
18658
18659 it->pixel_width = width;
18660 it->ascent = it->phys_ascent = ascent;
18661 it->descent = it->phys_descent = height - it->ascent;
18662 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18663
18664 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18665 {
18666 if (face->box_line_width > 0)
18667 {
18668 it->ascent += face->box_line_width;
18669 it->descent += face->box_line_width;
18670 }
18671
18672 if (it->start_of_box_run_p)
18673 it->pixel_width += abs (face->box_line_width);
18674 if (it->end_of_box_run_p)
18675 it->pixel_width += abs (face->box_line_width);
18676 }
18677
18678 take_vertical_position_into_account (it);
18679 }
18680
18681 /* Calculate line-height and line-spacing properties.
18682 An integer value specifies explicit pixel value.
18683 A float value specifies relative value to current face height.
18684 A cons (float . face-name) specifies relative value to
18685 height of specified face font.
18686
18687 Returns height in pixels, or nil. */
18688
18689 static Lisp_Object
18690 calc_line_height_property (it, prop, font, boff, total)
18691 struct it *it;
18692 Lisp_Object prop;
18693 XFontStruct *font;
18694 int boff, *total;
18695 {
18696 Lisp_Object position, val;
18697 Lisp_Object face_name = Qnil;
18698 int ascent, descent, height, override;
18699
18700 if (STRINGP (it->object))
18701 position = make_number (IT_STRING_CHARPOS (*it));
18702 else if (BUFFERP (it->object))
18703 position = make_number (IT_CHARPOS (*it));
18704 else
18705 return Qnil;
18706
18707 val = Fget_char_property (position, prop, it->object);
18708
18709 if (NILP (val))
18710 return val;
18711
18712 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18713 {
18714 *total = 1;
18715 val = XCDR (val);
18716 }
18717
18718 if (INTEGERP (val))
18719 return val;
18720
18721 if (CONSP (val))
18722 {
18723 face_name = XCDR (val);
18724 val = XCAR (val);
18725 }
18726 else if (SYMBOLP (val))
18727 {
18728 face_name = val;
18729 val = Qnil;
18730 }
18731
18732 override = EQ (prop, Qline_height);
18733
18734 if (NILP (face_name))
18735 {
18736 font = FRAME_FONT (it->f);
18737 boff = FRAME_BASELINE_OFFSET (it->f);
18738 }
18739 else if (EQ (face_name, Qt))
18740 {
18741 override = 0;
18742 }
18743 else
18744 {
18745 int face_id;
18746 struct face *face;
18747 struct font_info *font_info;
18748
18749 face_id = lookup_named_face (it->f, face_name, ' ');
18750 if (face_id < 0)
18751 return make_number (-1);
18752
18753 face = FACE_FROM_ID (it->f, face_id);
18754 font = face->font;
18755 if (font == NULL)
18756 return make_number (-1);
18757
18758 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18759 boff = font_info->baseline_offset;
18760 if (font_info->vertical_centering)
18761 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18762 }
18763
18764 ascent = FONT_BASE (font) + boff;
18765 descent = FONT_DESCENT (font) - boff;
18766
18767 if (override)
18768 {
18769 it->override_ascent = ascent;
18770 it->override_descent = descent;
18771 it->override_boff = boff;
18772 }
18773
18774 height = ascent + descent;
18775 if (FLOATP (val))
18776 height = (int)(XFLOAT_DATA (val) * height);
18777 else if (INTEGERP (val))
18778 height *= XINT (val);
18779
18780 return make_number (height);
18781 }
18782
18783
18784 /* RIF:
18785 Produce glyphs/get display metrics for the display element IT is
18786 loaded with. See the description of struct display_iterator in
18787 dispextern.h for an overview of struct display_iterator. */
18788
18789 void
18790 x_produce_glyphs (it)
18791 struct it *it;
18792 {
18793 int extra_line_spacing = it->extra_line_spacing;
18794
18795 it->glyph_not_available_p = 0;
18796
18797 if (it->what == IT_CHARACTER)
18798 {
18799 XChar2b char2b;
18800 XFontStruct *font;
18801 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18802 XCharStruct *pcm;
18803 int font_not_found_p;
18804 struct font_info *font_info;
18805 int boff; /* baseline offset */
18806 /* We may change it->multibyte_p upon unibyte<->multibyte
18807 conversion. So, save the current value now and restore it
18808 later.
18809
18810 Note: It seems that we don't have to record multibyte_p in
18811 struct glyph because the character code itself tells if or
18812 not the character is multibyte. Thus, in the future, we must
18813 consider eliminating the field `multibyte_p' in the struct
18814 glyph. */
18815 int saved_multibyte_p = it->multibyte_p;
18816
18817 /* Maybe translate single-byte characters to multibyte, or the
18818 other way. */
18819 it->char_to_display = it->c;
18820 if (!ASCII_BYTE_P (it->c))
18821 {
18822 if (unibyte_display_via_language_environment
18823 && SINGLE_BYTE_CHAR_P (it->c)
18824 && (it->c >= 0240
18825 || !NILP (Vnonascii_translation_table)))
18826 {
18827 it->char_to_display = unibyte_char_to_multibyte (it->c);
18828 it->multibyte_p = 1;
18829 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18830 face = FACE_FROM_ID (it->f, it->face_id);
18831 }
18832 else if (!SINGLE_BYTE_CHAR_P (it->c)
18833 && !it->multibyte_p)
18834 {
18835 it->multibyte_p = 1;
18836 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18837 face = FACE_FROM_ID (it->f, it->face_id);
18838 }
18839 }
18840
18841 /* Get font to use. Encode IT->char_to_display. */
18842 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18843 &char2b, it->multibyte_p, 0);
18844 font = face->font;
18845
18846 /* When no suitable font found, use the default font. */
18847 font_not_found_p = font == NULL;
18848 if (font_not_found_p)
18849 {
18850 font = FRAME_FONT (it->f);
18851 boff = FRAME_BASELINE_OFFSET (it->f);
18852 font_info = NULL;
18853 }
18854 else
18855 {
18856 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18857 boff = font_info->baseline_offset;
18858 if (font_info->vertical_centering)
18859 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18860 }
18861
18862 if (it->char_to_display >= ' '
18863 && (!it->multibyte_p || it->char_to_display < 128))
18864 {
18865 /* Either unibyte or ASCII. */
18866 int stretched_p;
18867
18868 it->nglyphs = 1;
18869
18870 pcm = rif->per_char_metric (font, &char2b,
18871 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18872
18873 if (it->override_ascent >= 0)
18874 {
18875 it->ascent = it->override_ascent;
18876 it->descent = it->override_descent;
18877 boff = it->override_boff;
18878 }
18879 else
18880 {
18881 it->ascent = FONT_BASE (font) + boff;
18882 it->descent = FONT_DESCENT (font) - boff;
18883 }
18884
18885 if (pcm)
18886 {
18887 it->phys_ascent = pcm->ascent + boff;
18888 it->phys_descent = pcm->descent - boff;
18889 it->pixel_width = pcm->width;
18890 }
18891 else
18892 {
18893 it->glyph_not_available_p = 1;
18894 it->phys_ascent = it->ascent;
18895 it->phys_descent = it->descent;
18896 it->pixel_width = FONT_WIDTH (font);
18897 }
18898
18899 if (it->constrain_row_ascent_descent_p)
18900 {
18901 if (it->descent > it->max_descent)
18902 {
18903 it->ascent += it->descent - it->max_descent;
18904 it->descent = it->max_descent;
18905 }
18906 if (it->ascent > it->max_ascent)
18907 {
18908 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18909 it->ascent = it->max_ascent;
18910 }
18911 it->phys_ascent = min (it->phys_ascent, it->ascent);
18912 it->phys_descent = min (it->phys_descent, it->descent);
18913 extra_line_spacing = 0;
18914 }
18915
18916 /* If this is a space inside a region of text with
18917 `space-width' property, change its width. */
18918 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18919 if (stretched_p)
18920 it->pixel_width *= XFLOATINT (it->space_width);
18921
18922 /* If face has a box, add the box thickness to the character
18923 height. If character has a box line to the left and/or
18924 right, add the box line width to the character's width. */
18925 if (face->box != FACE_NO_BOX)
18926 {
18927 int thick = face->box_line_width;
18928
18929 if (thick > 0)
18930 {
18931 it->ascent += thick;
18932 it->descent += thick;
18933 }
18934 else
18935 thick = -thick;
18936
18937 if (it->start_of_box_run_p)
18938 it->pixel_width += thick;
18939 if (it->end_of_box_run_p)
18940 it->pixel_width += thick;
18941 }
18942
18943 /* If face has an overline, add the height of the overline
18944 (1 pixel) and a 1 pixel margin to the character height. */
18945 if (face->overline_p)
18946 it->ascent += 2;
18947
18948 if (it->constrain_row_ascent_descent_p)
18949 {
18950 if (it->ascent > it->max_ascent)
18951 it->ascent = it->max_ascent;
18952 if (it->descent > it->max_descent)
18953 it->descent = it->max_descent;
18954 }
18955
18956 take_vertical_position_into_account (it);
18957
18958 /* If we have to actually produce glyphs, do it. */
18959 if (it->glyph_row)
18960 {
18961 if (stretched_p)
18962 {
18963 /* Translate a space with a `space-width' property
18964 into a stretch glyph. */
18965 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18966 / FONT_HEIGHT (font));
18967 append_stretch_glyph (it, it->object, it->pixel_width,
18968 it->ascent + it->descent, ascent);
18969 }
18970 else
18971 append_glyph (it);
18972
18973 /* If characters with lbearing or rbearing are displayed
18974 in this line, record that fact in a flag of the
18975 glyph row. This is used to optimize X output code. */
18976 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18977 it->glyph_row->contains_overlapping_glyphs_p = 1;
18978 }
18979 }
18980 else if (it->char_to_display == '\n')
18981 {
18982 /* A newline has no width but we need the height of the line.
18983 But if previous part of the line set a height, don't
18984 increase that height */
18985
18986 Lisp_Object height;
18987
18988 it->override_ascent = -1;
18989 it->pixel_width = 0;
18990 it->nglyphs = 0;
18991
18992 height = calc_line_height_property(it, Qline_height, font, boff, 0);
18993
18994 if (it->override_ascent >= 0)
18995 {
18996 it->ascent = it->override_ascent;
18997 it->descent = it->override_descent;
18998 boff = it->override_boff;
18999 }
19000 else
19001 {
19002 it->ascent = FONT_BASE (font) + boff;
19003 it->descent = FONT_DESCENT (font) - boff;
19004 }
19005
19006 if (EQ (height, make_number(0)))
19007 {
19008 if (it->descent > it->max_descent)
19009 {
19010 it->ascent += it->descent - it->max_descent;
19011 it->descent = it->max_descent;
19012 }
19013 if (it->ascent > it->max_ascent)
19014 {
19015 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19016 it->ascent = it->max_ascent;
19017 }
19018 it->phys_ascent = min (it->phys_ascent, it->ascent);
19019 it->phys_descent = min (it->phys_descent, it->descent);
19020 it->constrain_row_ascent_descent_p = 1;
19021 extra_line_spacing = 0;
19022 }
19023 else
19024 {
19025 Lisp_Object spacing;
19026 int total = 0;
19027
19028 it->phys_ascent = it->ascent;
19029 it->phys_descent = it->descent;
19030
19031 if ((it->max_ascent > 0 || it->max_descent > 0)
19032 && face->box != FACE_NO_BOX
19033 && face->box_line_width > 0)
19034 {
19035 it->ascent += face->box_line_width;
19036 it->descent += face->box_line_width;
19037 }
19038 if (!NILP (height)
19039 && XINT (height) > it->ascent + it->descent)
19040 it->ascent = XINT (height) - it->descent;
19041
19042 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
19043 if (INTEGERP (spacing))
19044 {
19045 extra_line_spacing = XINT (spacing);
19046 if (total)
19047 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19048 }
19049 }
19050 }
19051 else if (it->char_to_display == '\t')
19052 {
19053 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19054 int x = it->current_x + it->continuation_lines_width;
19055 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19056
19057 /* If the distance from the current position to the next tab
19058 stop is less than a canonical character width, use the
19059 tab stop after that. */
19060 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19061 next_tab_x += tab_width;
19062
19063 it->pixel_width = next_tab_x - x;
19064 it->nglyphs = 1;
19065 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19066 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19067
19068 if (it->glyph_row)
19069 {
19070 append_stretch_glyph (it, it->object, it->pixel_width,
19071 it->ascent + it->descent, it->ascent);
19072 }
19073 }
19074 else
19075 {
19076 /* A multi-byte character. Assume that the display width of the
19077 character is the width of the character multiplied by the
19078 width of the font. */
19079
19080 /* If we found a font, this font should give us the right
19081 metrics. If we didn't find a font, use the frame's
19082 default font and calculate the width of the character
19083 from the charset width; this is what old redisplay code
19084 did. */
19085
19086 pcm = rif->per_char_metric (font, &char2b,
19087 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19088
19089 if (font_not_found_p || !pcm)
19090 {
19091 int charset = CHAR_CHARSET (it->char_to_display);
19092
19093 it->glyph_not_available_p = 1;
19094 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19095 * CHARSET_WIDTH (charset));
19096 it->phys_ascent = FONT_BASE (font) + boff;
19097 it->phys_descent = FONT_DESCENT (font) - boff;
19098 }
19099 else
19100 {
19101 it->pixel_width = pcm->width;
19102 it->phys_ascent = pcm->ascent + boff;
19103 it->phys_descent = pcm->descent - boff;
19104 if (it->glyph_row
19105 && (pcm->lbearing < 0
19106 || pcm->rbearing > pcm->width))
19107 it->glyph_row->contains_overlapping_glyphs_p = 1;
19108 }
19109 it->nglyphs = 1;
19110 it->ascent = FONT_BASE (font) + boff;
19111 it->descent = FONT_DESCENT (font) - boff;
19112 if (face->box != FACE_NO_BOX)
19113 {
19114 int thick = face->box_line_width;
19115
19116 if (thick > 0)
19117 {
19118 it->ascent += thick;
19119 it->descent += thick;
19120 }
19121 else
19122 thick = - thick;
19123
19124 if (it->start_of_box_run_p)
19125 it->pixel_width += thick;
19126 if (it->end_of_box_run_p)
19127 it->pixel_width += thick;
19128 }
19129
19130 /* If face has an overline, add the height of the overline
19131 (1 pixel) and a 1 pixel margin to the character height. */
19132 if (face->overline_p)
19133 it->ascent += 2;
19134
19135 take_vertical_position_into_account (it);
19136
19137 if (it->glyph_row)
19138 append_glyph (it);
19139 }
19140 it->multibyte_p = saved_multibyte_p;
19141 }
19142 else if (it->what == IT_COMPOSITION)
19143 {
19144 /* Note: A composition is represented as one glyph in the
19145 glyph matrix. There are no padding glyphs. */
19146 XChar2b char2b;
19147 XFontStruct *font;
19148 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19149 XCharStruct *pcm;
19150 int font_not_found_p;
19151 struct font_info *font_info;
19152 int boff; /* baseline offset */
19153 struct composition *cmp = composition_table[it->cmp_id];
19154
19155 /* Maybe translate single-byte characters to multibyte. */
19156 it->char_to_display = it->c;
19157 if (unibyte_display_via_language_environment
19158 && SINGLE_BYTE_CHAR_P (it->c)
19159 && (it->c >= 0240
19160 || (it->c >= 0200
19161 && !NILP (Vnonascii_translation_table))))
19162 {
19163 it->char_to_display = unibyte_char_to_multibyte (it->c);
19164 }
19165
19166 /* Get face and font to use. Encode IT->char_to_display. */
19167 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19168 face = FACE_FROM_ID (it->f, it->face_id);
19169 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19170 &char2b, it->multibyte_p, 0);
19171 font = face->font;
19172
19173 /* When no suitable font found, use the default font. */
19174 font_not_found_p = font == NULL;
19175 if (font_not_found_p)
19176 {
19177 font = FRAME_FONT (it->f);
19178 boff = FRAME_BASELINE_OFFSET (it->f);
19179 font_info = NULL;
19180 }
19181 else
19182 {
19183 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19184 boff = font_info->baseline_offset;
19185 if (font_info->vertical_centering)
19186 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19187 }
19188
19189 /* There are no padding glyphs, so there is only one glyph to
19190 produce for the composition. Important is that pixel_width,
19191 ascent and descent are the values of what is drawn by
19192 draw_glyphs (i.e. the values of the overall glyphs composed). */
19193 it->nglyphs = 1;
19194
19195 /* If we have not yet calculated pixel size data of glyphs of
19196 the composition for the current face font, calculate them
19197 now. Theoretically, we have to check all fonts for the
19198 glyphs, but that requires much time and memory space. So,
19199 here we check only the font of the first glyph. This leads
19200 to incorrect display very rarely, and C-l (recenter) can
19201 correct the display anyway. */
19202 if (cmp->font != (void *) font)
19203 {
19204 /* Ascent and descent of the font of the first character of
19205 this composition (adjusted by baseline offset). Ascent
19206 and descent of overall glyphs should not be less than
19207 them respectively. */
19208 int font_ascent = FONT_BASE (font) + boff;
19209 int font_descent = FONT_DESCENT (font) - boff;
19210 /* Bounding box of the overall glyphs. */
19211 int leftmost, rightmost, lowest, highest;
19212 int i, width, ascent, descent;
19213
19214 cmp->font = (void *) font;
19215
19216 /* Initialize the bounding box. */
19217 if (font_info
19218 && (pcm = rif->per_char_metric (font, &char2b,
19219 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19220 {
19221 width = pcm->width;
19222 ascent = pcm->ascent;
19223 descent = pcm->descent;
19224 }
19225 else
19226 {
19227 width = FONT_WIDTH (font);
19228 ascent = FONT_BASE (font);
19229 descent = FONT_DESCENT (font);
19230 }
19231
19232 rightmost = width;
19233 lowest = - descent + boff;
19234 highest = ascent + boff;
19235 leftmost = 0;
19236
19237 if (font_info
19238 && font_info->default_ascent
19239 && CHAR_TABLE_P (Vuse_default_ascent)
19240 && !NILP (Faref (Vuse_default_ascent,
19241 make_number (it->char_to_display))))
19242 highest = font_info->default_ascent + boff;
19243
19244 /* Draw the first glyph at the normal position. It may be
19245 shifted to right later if some other glyphs are drawn at
19246 the left. */
19247 cmp->offsets[0] = 0;
19248 cmp->offsets[1] = boff;
19249
19250 /* Set cmp->offsets for the remaining glyphs. */
19251 for (i = 1; i < cmp->glyph_len; i++)
19252 {
19253 int left, right, btm, top;
19254 int ch = COMPOSITION_GLYPH (cmp, i);
19255 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19256
19257 face = FACE_FROM_ID (it->f, face_id);
19258 get_char_face_and_encoding (it->f, ch, face->id,
19259 &char2b, it->multibyte_p, 0);
19260 font = face->font;
19261 if (font == NULL)
19262 {
19263 font = FRAME_FONT (it->f);
19264 boff = FRAME_BASELINE_OFFSET (it->f);
19265 font_info = NULL;
19266 }
19267 else
19268 {
19269 font_info
19270 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19271 boff = font_info->baseline_offset;
19272 if (font_info->vertical_centering)
19273 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19274 }
19275
19276 if (font_info
19277 && (pcm = rif->per_char_metric (font, &char2b,
19278 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19279 {
19280 width = pcm->width;
19281 ascent = pcm->ascent;
19282 descent = pcm->descent;
19283 }
19284 else
19285 {
19286 width = FONT_WIDTH (font);
19287 ascent = 1;
19288 descent = 0;
19289 }
19290
19291 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19292 {
19293 /* Relative composition with or without
19294 alternate chars. */
19295 left = (leftmost + rightmost - width) / 2;
19296 btm = - descent + boff;
19297 if (font_info && font_info->relative_compose
19298 && (! CHAR_TABLE_P (Vignore_relative_composition)
19299 || NILP (Faref (Vignore_relative_composition,
19300 make_number (ch)))))
19301 {
19302
19303 if (- descent >= font_info->relative_compose)
19304 /* One extra pixel between two glyphs. */
19305 btm = highest + 1;
19306 else if (ascent <= 0)
19307 /* One extra pixel between two glyphs. */
19308 btm = lowest - 1 - ascent - descent;
19309 }
19310 }
19311 else
19312 {
19313 /* A composition rule is specified by an integer
19314 value that encodes global and new reference
19315 points (GREF and NREF). GREF and NREF are
19316 specified by numbers as below:
19317
19318 0---1---2 -- ascent
19319 | |
19320 | |
19321 | |
19322 9--10--11 -- center
19323 | |
19324 ---3---4---5--- baseline
19325 | |
19326 6---7---8 -- descent
19327 */
19328 int rule = COMPOSITION_RULE (cmp, i);
19329 int gref, nref, grefx, grefy, nrefx, nrefy;
19330
19331 COMPOSITION_DECODE_RULE (rule, gref, nref);
19332 grefx = gref % 3, nrefx = nref % 3;
19333 grefy = gref / 3, nrefy = nref / 3;
19334
19335 left = (leftmost
19336 + grefx * (rightmost - leftmost) / 2
19337 - nrefx * width / 2);
19338 btm = ((grefy == 0 ? highest
19339 : grefy == 1 ? 0
19340 : grefy == 2 ? lowest
19341 : (highest + lowest) / 2)
19342 - (nrefy == 0 ? ascent + descent
19343 : nrefy == 1 ? descent - boff
19344 : nrefy == 2 ? 0
19345 : (ascent + descent) / 2));
19346 }
19347
19348 cmp->offsets[i * 2] = left;
19349 cmp->offsets[i * 2 + 1] = btm + descent;
19350
19351 /* Update the bounding box of the overall glyphs. */
19352 right = left + width;
19353 top = btm + descent + ascent;
19354 if (left < leftmost)
19355 leftmost = left;
19356 if (right > rightmost)
19357 rightmost = right;
19358 if (top > highest)
19359 highest = top;
19360 if (btm < lowest)
19361 lowest = btm;
19362 }
19363
19364 /* If there are glyphs whose x-offsets are negative,
19365 shift all glyphs to the right and make all x-offsets
19366 non-negative. */
19367 if (leftmost < 0)
19368 {
19369 for (i = 0; i < cmp->glyph_len; i++)
19370 cmp->offsets[i * 2] -= leftmost;
19371 rightmost -= leftmost;
19372 }
19373
19374 cmp->pixel_width = rightmost;
19375 cmp->ascent = highest;
19376 cmp->descent = - lowest;
19377 if (cmp->ascent < font_ascent)
19378 cmp->ascent = font_ascent;
19379 if (cmp->descent < font_descent)
19380 cmp->descent = font_descent;
19381 }
19382
19383 it->pixel_width = cmp->pixel_width;
19384 it->ascent = it->phys_ascent = cmp->ascent;
19385 it->descent = it->phys_descent = cmp->descent;
19386
19387 if (face->box != FACE_NO_BOX)
19388 {
19389 int thick = face->box_line_width;
19390
19391 if (thick > 0)
19392 {
19393 it->ascent += thick;
19394 it->descent += thick;
19395 }
19396 else
19397 thick = - thick;
19398
19399 if (it->start_of_box_run_p)
19400 it->pixel_width += thick;
19401 if (it->end_of_box_run_p)
19402 it->pixel_width += thick;
19403 }
19404
19405 /* If face has an overline, add the height of the overline
19406 (1 pixel) and a 1 pixel margin to the character height. */
19407 if (face->overline_p)
19408 it->ascent += 2;
19409
19410 take_vertical_position_into_account (it);
19411
19412 if (it->glyph_row)
19413 append_composite_glyph (it);
19414 }
19415 else if (it->what == IT_IMAGE)
19416 produce_image_glyph (it);
19417 else if (it->what == IT_STRETCH)
19418 produce_stretch_glyph (it);
19419
19420 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19421 because this isn't true for images with `:ascent 100'. */
19422 xassert (it->ascent >= 0 && it->descent >= 0);
19423 if (it->area == TEXT_AREA)
19424 it->current_x += it->pixel_width;
19425
19426 if (extra_line_spacing > 0)
19427 it->descent += extra_line_spacing;
19428
19429 it->max_ascent = max (it->max_ascent, it->ascent);
19430 it->max_descent = max (it->max_descent, it->descent);
19431 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19432 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19433 }
19434
19435 /* EXPORT for RIF:
19436 Output LEN glyphs starting at START at the nominal cursor position.
19437 Advance the nominal cursor over the text. The global variable
19438 updated_window contains the window being updated, updated_row is
19439 the glyph row being updated, and updated_area is the area of that
19440 row being updated. */
19441
19442 void
19443 x_write_glyphs (start, len)
19444 struct glyph *start;
19445 int len;
19446 {
19447 int x, hpos;
19448
19449 xassert (updated_window && updated_row);
19450 BLOCK_INPUT;
19451
19452 /* Write glyphs. */
19453
19454 hpos = start - updated_row->glyphs[updated_area];
19455 x = draw_glyphs (updated_window, output_cursor.x,
19456 updated_row, updated_area,
19457 hpos, hpos + len,
19458 DRAW_NORMAL_TEXT, 0);
19459
19460 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19461 if (updated_area == TEXT_AREA
19462 && updated_window->phys_cursor_on_p
19463 && updated_window->phys_cursor.vpos == output_cursor.vpos
19464 && updated_window->phys_cursor.hpos >= hpos
19465 && updated_window->phys_cursor.hpos < hpos + len)
19466 updated_window->phys_cursor_on_p = 0;
19467
19468 UNBLOCK_INPUT;
19469
19470 /* Advance the output cursor. */
19471 output_cursor.hpos += len;
19472 output_cursor.x = x;
19473 }
19474
19475
19476 /* EXPORT for RIF:
19477 Insert LEN glyphs from START at the nominal cursor position. */
19478
19479 void
19480 x_insert_glyphs (start, len)
19481 struct glyph *start;
19482 int len;
19483 {
19484 struct frame *f;
19485 struct window *w;
19486 int line_height, shift_by_width, shifted_region_width;
19487 struct glyph_row *row;
19488 struct glyph *glyph;
19489 int frame_x, frame_y, hpos;
19490
19491 xassert (updated_window && updated_row);
19492 BLOCK_INPUT;
19493 w = updated_window;
19494 f = XFRAME (WINDOW_FRAME (w));
19495
19496 /* Get the height of the line we are in. */
19497 row = updated_row;
19498 line_height = row->height;
19499
19500 /* Get the width of the glyphs to insert. */
19501 shift_by_width = 0;
19502 for (glyph = start; glyph < start + len; ++glyph)
19503 shift_by_width += glyph->pixel_width;
19504
19505 /* Get the width of the region to shift right. */
19506 shifted_region_width = (window_box_width (w, updated_area)
19507 - output_cursor.x
19508 - shift_by_width);
19509
19510 /* Shift right. */
19511 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19512 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19513
19514 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19515 line_height, shift_by_width);
19516
19517 /* Write the glyphs. */
19518 hpos = start - row->glyphs[updated_area];
19519 draw_glyphs (w, output_cursor.x, row, updated_area,
19520 hpos, hpos + len,
19521 DRAW_NORMAL_TEXT, 0);
19522
19523 /* Advance the output cursor. */
19524 output_cursor.hpos += len;
19525 output_cursor.x += shift_by_width;
19526 UNBLOCK_INPUT;
19527 }
19528
19529
19530 /* EXPORT for RIF:
19531 Erase the current text line from the nominal cursor position
19532 (inclusive) to pixel column TO_X (exclusive). The idea is that
19533 everything from TO_X onward is already erased.
19534
19535 TO_X is a pixel position relative to updated_area of
19536 updated_window. TO_X == -1 means clear to the end of this area. */
19537
19538 void
19539 x_clear_end_of_line (to_x)
19540 int to_x;
19541 {
19542 struct frame *f;
19543 struct window *w = updated_window;
19544 int max_x, min_y, max_y;
19545 int from_x, from_y, to_y;
19546
19547 xassert (updated_window && updated_row);
19548 f = XFRAME (w->frame);
19549
19550 if (updated_row->full_width_p)
19551 max_x = WINDOW_TOTAL_WIDTH (w);
19552 else
19553 max_x = window_box_width (w, updated_area);
19554 max_y = window_text_bottom_y (w);
19555
19556 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19557 of window. For TO_X > 0, truncate to end of drawing area. */
19558 if (to_x == 0)
19559 return;
19560 else if (to_x < 0)
19561 to_x = max_x;
19562 else
19563 to_x = min (to_x, max_x);
19564
19565 to_y = min (max_y, output_cursor.y + updated_row->height);
19566
19567 /* Notice if the cursor will be cleared by this operation. */
19568 if (!updated_row->full_width_p)
19569 notice_overwritten_cursor (w, updated_area,
19570 output_cursor.x, -1,
19571 updated_row->y,
19572 MATRIX_ROW_BOTTOM_Y (updated_row));
19573
19574 from_x = output_cursor.x;
19575
19576 /* Translate to frame coordinates. */
19577 if (updated_row->full_width_p)
19578 {
19579 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19580 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19581 }
19582 else
19583 {
19584 int area_left = window_box_left (w, updated_area);
19585 from_x += area_left;
19586 to_x += area_left;
19587 }
19588
19589 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19590 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19591 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19592
19593 /* Prevent inadvertently clearing to end of the X window. */
19594 if (to_x > from_x && to_y > from_y)
19595 {
19596 BLOCK_INPUT;
19597 rif->clear_frame_area (f, from_x, from_y,
19598 to_x - from_x, to_y - from_y);
19599 UNBLOCK_INPUT;
19600 }
19601 }
19602
19603 #endif /* HAVE_WINDOW_SYSTEM */
19604
19605
19606 \f
19607 /***********************************************************************
19608 Cursor types
19609 ***********************************************************************/
19610
19611 /* Value is the internal representation of the specified cursor type
19612 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19613 of the bar cursor. */
19614
19615 static enum text_cursor_kinds
19616 get_specified_cursor_type (arg, width)
19617 Lisp_Object arg;
19618 int *width;
19619 {
19620 enum text_cursor_kinds type;
19621
19622 if (NILP (arg))
19623 return NO_CURSOR;
19624
19625 if (EQ (arg, Qbox))
19626 return FILLED_BOX_CURSOR;
19627
19628 if (EQ (arg, Qhollow))
19629 return HOLLOW_BOX_CURSOR;
19630
19631 if (EQ (arg, Qbar))
19632 {
19633 *width = 2;
19634 return BAR_CURSOR;
19635 }
19636
19637 if (CONSP (arg)
19638 && EQ (XCAR (arg), Qbar)
19639 && INTEGERP (XCDR (arg))
19640 && XINT (XCDR (arg)) >= 0)
19641 {
19642 *width = XINT (XCDR (arg));
19643 return BAR_CURSOR;
19644 }
19645
19646 if (EQ (arg, Qhbar))
19647 {
19648 *width = 2;
19649 return HBAR_CURSOR;
19650 }
19651
19652 if (CONSP (arg)
19653 && EQ (XCAR (arg), Qhbar)
19654 && INTEGERP (XCDR (arg))
19655 && XINT (XCDR (arg)) >= 0)
19656 {
19657 *width = XINT (XCDR (arg));
19658 return HBAR_CURSOR;
19659 }
19660
19661 /* Treat anything unknown as "hollow box cursor".
19662 It was bad to signal an error; people have trouble fixing
19663 .Xdefaults with Emacs, when it has something bad in it. */
19664 type = HOLLOW_BOX_CURSOR;
19665
19666 return type;
19667 }
19668
19669 /* Set the default cursor types for specified frame. */
19670 void
19671 set_frame_cursor_types (f, arg)
19672 struct frame *f;
19673 Lisp_Object arg;
19674 {
19675 int width;
19676 Lisp_Object tem;
19677
19678 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19679 FRAME_CURSOR_WIDTH (f) = width;
19680
19681 /* By default, set up the blink-off state depending on the on-state. */
19682
19683 tem = Fassoc (arg, Vblink_cursor_alist);
19684 if (!NILP (tem))
19685 {
19686 FRAME_BLINK_OFF_CURSOR (f)
19687 = get_specified_cursor_type (XCDR (tem), &width);
19688 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19689 }
19690 else
19691 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19692 }
19693
19694
19695 /* Return the cursor we want to be displayed in window W. Return
19696 width of bar/hbar cursor through WIDTH arg. Return with
19697 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19698 (i.e. if the `system caret' should track this cursor).
19699
19700 In a mini-buffer window, we want the cursor only to appear if we
19701 are reading input from this window. For the selected window, we
19702 want the cursor type given by the frame parameter or buffer local
19703 setting of cursor-type. If explicitly marked off, draw no cursor.
19704 In all other cases, we want a hollow box cursor. */
19705
19706 static enum text_cursor_kinds
19707 get_window_cursor_type (w, glyph, width, active_cursor)
19708 struct window *w;
19709 struct glyph *glyph;
19710 int *width;
19711 int *active_cursor;
19712 {
19713 struct frame *f = XFRAME (w->frame);
19714 struct buffer *b = XBUFFER (w->buffer);
19715 int cursor_type = DEFAULT_CURSOR;
19716 Lisp_Object alt_cursor;
19717 int non_selected = 0;
19718
19719 *active_cursor = 1;
19720
19721 /* Echo area */
19722 if (cursor_in_echo_area
19723 && FRAME_HAS_MINIBUF_P (f)
19724 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19725 {
19726 if (w == XWINDOW (echo_area_window))
19727 {
19728 *width = FRAME_CURSOR_WIDTH (f);
19729 return FRAME_DESIRED_CURSOR (f);
19730 }
19731
19732 *active_cursor = 0;
19733 non_selected = 1;
19734 }
19735
19736 /* Nonselected window or nonselected frame. */
19737 else if (w != XWINDOW (f->selected_window)
19738 #ifdef HAVE_WINDOW_SYSTEM
19739 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19740 #endif
19741 )
19742 {
19743 *active_cursor = 0;
19744
19745 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19746 return NO_CURSOR;
19747
19748 non_selected = 1;
19749 }
19750
19751 /* Never display a cursor in a window in which cursor-type is nil. */
19752 if (NILP (b->cursor_type))
19753 return NO_CURSOR;
19754
19755 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19756 if (non_selected)
19757 {
19758 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19759 return get_specified_cursor_type (alt_cursor, width);
19760 }
19761
19762 /* Get the normal cursor type for this window. */
19763 if (EQ (b->cursor_type, Qt))
19764 {
19765 cursor_type = FRAME_DESIRED_CURSOR (f);
19766 *width = FRAME_CURSOR_WIDTH (f);
19767 }
19768 else
19769 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19770
19771 /* Use normal cursor if not blinked off. */
19772 if (!w->cursor_off_p)
19773 {
19774 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19775 if (cursor_type == FILLED_BOX_CURSOR)
19776 cursor_type = HOLLOW_BOX_CURSOR;
19777 }
19778 return cursor_type;
19779 }
19780
19781 /* Cursor is blinked off, so determine how to "toggle" it. */
19782
19783 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19784 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19785 return get_specified_cursor_type (XCDR (alt_cursor), width);
19786
19787 /* Then see if frame has specified a specific blink off cursor type. */
19788 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19789 {
19790 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19791 return FRAME_BLINK_OFF_CURSOR (f);
19792 }
19793
19794 #if 0
19795 /* Some people liked having a permanently visible blinking cursor,
19796 while others had very strong opinions against it. So it was
19797 decided to remove it. KFS 2003-09-03 */
19798
19799 /* Finally perform built-in cursor blinking:
19800 filled box <-> hollow box
19801 wide [h]bar <-> narrow [h]bar
19802 narrow [h]bar <-> no cursor
19803 other type <-> no cursor */
19804
19805 if (cursor_type == FILLED_BOX_CURSOR)
19806 return HOLLOW_BOX_CURSOR;
19807
19808 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19809 {
19810 *width = 1;
19811 return cursor_type;
19812 }
19813 #endif
19814
19815 return NO_CURSOR;
19816 }
19817
19818
19819 #ifdef HAVE_WINDOW_SYSTEM
19820
19821 /* Notice when the text cursor of window W has been completely
19822 overwritten by a drawing operation that outputs glyphs in AREA
19823 starting at X0 and ending at X1 in the line starting at Y0 and
19824 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19825 the rest of the line after X0 has been written. Y coordinates
19826 are window-relative. */
19827
19828 static void
19829 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19830 struct window *w;
19831 enum glyph_row_area area;
19832 int x0, y0, x1, y1;
19833 {
19834 int cx0, cx1, cy0, cy1;
19835 struct glyph_row *row;
19836
19837 if (!w->phys_cursor_on_p)
19838 return;
19839 if (area != TEXT_AREA)
19840 return;
19841
19842 row = w->current_matrix->rows + w->phys_cursor.vpos;
19843 if (!row->displays_text_p)
19844 return;
19845
19846 if (row->cursor_in_fringe_p)
19847 {
19848 row->cursor_in_fringe_p = 0;
19849 draw_fringe_bitmap (w, row, 0);
19850 w->phys_cursor_on_p = 0;
19851 return;
19852 }
19853
19854 cx0 = w->phys_cursor.x;
19855 cx1 = cx0 + w->phys_cursor_width;
19856 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19857 return;
19858
19859 /* The cursor image will be completely removed from the
19860 screen if the output area intersects the cursor area in
19861 y-direction. When we draw in [y0 y1[, and some part of
19862 the cursor is at y < y0, that part must have been drawn
19863 before. When scrolling, the cursor is erased before
19864 actually scrolling, so we don't come here. When not
19865 scrolling, the rows above the old cursor row must have
19866 changed, and in this case these rows must have written
19867 over the cursor image.
19868
19869 Likewise if part of the cursor is below y1, with the
19870 exception of the cursor being in the first blank row at
19871 the buffer and window end because update_text_area
19872 doesn't draw that row. (Except when it does, but
19873 that's handled in update_text_area.) */
19874
19875 cy0 = w->phys_cursor.y;
19876 cy1 = cy0 + w->phys_cursor_height;
19877 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19878 return;
19879
19880 w->phys_cursor_on_p = 0;
19881 }
19882
19883 #endif /* HAVE_WINDOW_SYSTEM */
19884
19885 \f
19886 /************************************************************************
19887 Mouse Face
19888 ************************************************************************/
19889
19890 #ifdef HAVE_WINDOW_SYSTEM
19891
19892 /* EXPORT for RIF:
19893 Fix the display of area AREA of overlapping row ROW in window W. */
19894
19895 void
19896 x_fix_overlapping_area (w, row, area)
19897 struct window *w;
19898 struct glyph_row *row;
19899 enum glyph_row_area area;
19900 {
19901 int i, x;
19902
19903 BLOCK_INPUT;
19904
19905 x = 0;
19906 for (i = 0; i < row->used[area];)
19907 {
19908 if (row->glyphs[area][i].overlaps_vertically_p)
19909 {
19910 int start = i, start_x = x;
19911
19912 do
19913 {
19914 x += row->glyphs[area][i].pixel_width;
19915 ++i;
19916 }
19917 while (i < row->used[area]
19918 && row->glyphs[area][i].overlaps_vertically_p);
19919
19920 draw_glyphs (w, start_x, row, area,
19921 start, i,
19922 DRAW_NORMAL_TEXT, 1);
19923 }
19924 else
19925 {
19926 x += row->glyphs[area][i].pixel_width;
19927 ++i;
19928 }
19929 }
19930
19931 UNBLOCK_INPUT;
19932 }
19933
19934
19935 /* EXPORT:
19936 Draw the cursor glyph of window W in glyph row ROW. See the
19937 comment of draw_glyphs for the meaning of HL. */
19938
19939 void
19940 draw_phys_cursor_glyph (w, row, hl)
19941 struct window *w;
19942 struct glyph_row *row;
19943 enum draw_glyphs_face hl;
19944 {
19945 /* If cursor hpos is out of bounds, don't draw garbage. This can
19946 happen in mini-buffer windows when switching between echo area
19947 glyphs and mini-buffer. */
19948 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19949 {
19950 int on_p = w->phys_cursor_on_p;
19951 int x1;
19952 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19953 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19954 hl, 0);
19955 w->phys_cursor_on_p = on_p;
19956
19957 if (hl == DRAW_CURSOR)
19958 w->phys_cursor_width = x1 - w->phys_cursor.x;
19959 /* When we erase the cursor, and ROW is overlapped by other
19960 rows, make sure that these overlapping parts of other rows
19961 are redrawn. */
19962 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19963 {
19964 if (row > w->current_matrix->rows
19965 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19966 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19967
19968 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19969 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19970 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19971 }
19972 }
19973 }
19974
19975
19976 /* EXPORT:
19977 Erase the image of a cursor of window W from the screen. */
19978
19979 void
19980 erase_phys_cursor (w)
19981 struct window *w;
19982 {
19983 struct frame *f = XFRAME (w->frame);
19984 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19985 int hpos = w->phys_cursor.hpos;
19986 int vpos = w->phys_cursor.vpos;
19987 int mouse_face_here_p = 0;
19988 struct glyph_matrix *active_glyphs = w->current_matrix;
19989 struct glyph_row *cursor_row;
19990 struct glyph *cursor_glyph;
19991 enum draw_glyphs_face hl;
19992
19993 /* No cursor displayed or row invalidated => nothing to do on the
19994 screen. */
19995 if (w->phys_cursor_type == NO_CURSOR)
19996 goto mark_cursor_off;
19997
19998 /* VPOS >= active_glyphs->nrows means that window has been resized.
19999 Don't bother to erase the cursor. */
20000 if (vpos >= active_glyphs->nrows)
20001 goto mark_cursor_off;
20002
20003 /* If row containing cursor is marked invalid, there is nothing we
20004 can do. */
20005 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20006 if (!cursor_row->enabled_p)
20007 goto mark_cursor_off;
20008
20009 /* If row is completely invisible, don't attempt to delete a cursor which
20010 isn't there. This can happen if cursor is at top of a window, and
20011 we switch to a buffer with a header line in that window. */
20012 if (cursor_row->visible_height <= 0)
20013 goto mark_cursor_off;
20014
20015 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20016 if (cursor_row->cursor_in_fringe_p)
20017 {
20018 cursor_row->cursor_in_fringe_p = 0;
20019 draw_fringe_bitmap (w, cursor_row, 0);
20020 goto mark_cursor_off;
20021 }
20022
20023 /* This can happen when the new row is shorter than the old one.
20024 In this case, either draw_glyphs or clear_end_of_line
20025 should have cleared the cursor. Note that we wouldn't be
20026 able to erase the cursor in this case because we don't have a
20027 cursor glyph at hand. */
20028 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20029 goto mark_cursor_off;
20030
20031 /* If the cursor is in the mouse face area, redisplay that when
20032 we clear the cursor. */
20033 if (! NILP (dpyinfo->mouse_face_window)
20034 && w == XWINDOW (dpyinfo->mouse_face_window)
20035 && (vpos > dpyinfo->mouse_face_beg_row
20036 || (vpos == dpyinfo->mouse_face_beg_row
20037 && hpos >= dpyinfo->mouse_face_beg_col))
20038 && (vpos < dpyinfo->mouse_face_end_row
20039 || (vpos == dpyinfo->mouse_face_end_row
20040 && hpos < dpyinfo->mouse_face_end_col))
20041 /* Don't redraw the cursor's spot in mouse face if it is at the
20042 end of a line (on a newline). The cursor appears there, but
20043 mouse highlighting does not. */
20044 && cursor_row->used[TEXT_AREA] > hpos)
20045 mouse_face_here_p = 1;
20046
20047 /* Maybe clear the display under the cursor. */
20048 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20049 {
20050 int x, y;
20051 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20052
20053 cursor_glyph = get_phys_cursor_glyph (w);
20054 if (cursor_glyph == NULL)
20055 goto mark_cursor_off;
20056
20057 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20058 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20059
20060 rif->clear_frame_area (f, x, y,
20061 cursor_glyph->pixel_width, cursor_row->visible_height);
20062 }
20063
20064 /* Erase the cursor by redrawing the character underneath it. */
20065 if (mouse_face_here_p)
20066 hl = DRAW_MOUSE_FACE;
20067 else
20068 hl = DRAW_NORMAL_TEXT;
20069 draw_phys_cursor_glyph (w, cursor_row, hl);
20070
20071 mark_cursor_off:
20072 w->phys_cursor_on_p = 0;
20073 w->phys_cursor_type = NO_CURSOR;
20074 }
20075
20076
20077 /* EXPORT:
20078 Display or clear cursor of window W. If ON is zero, clear the
20079 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20080 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20081
20082 void
20083 display_and_set_cursor (w, on, hpos, vpos, x, y)
20084 struct window *w;
20085 int on, hpos, vpos, x, y;
20086 {
20087 struct frame *f = XFRAME (w->frame);
20088 int new_cursor_type;
20089 int new_cursor_width;
20090 int active_cursor;
20091 struct glyph_row *glyph_row;
20092 struct glyph *glyph;
20093
20094 /* This is pointless on invisible frames, and dangerous on garbaged
20095 windows and frames; in the latter case, the frame or window may
20096 be in the midst of changing its size, and x and y may be off the
20097 window. */
20098 if (! FRAME_VISIBLE_P (f)
20099 || FRAME_GARBAGED_P (f)
20100 || vpos >= w->current_matrix->nrows
20101 || hpos >= w->current_matrix->matrix_w)
20102 return;
20103
20104 /* If cursor is off and we want it off, return quickly. */
20105 if (!on && !w->phys_cursor_on_p)
20106 return;
20107
20108 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20109 /* If cursor row is not enabled, we don't really know where to
20110 display the cursor. */
20111 if (!glyph_row->enabled_p)
20112 {
20113 w->phys_cursor_on_p = 0;
20114 return;
20115 }
20116
20117 glyph = NULL;
20118 if (!glyph_row->exact_window_width_line_p
20119 || hpos < glyph_row->used[TEXT_AREA])
20120 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20121
20122 xassert (interrupt_input_blocked);
20123
20124 /* Set new_cursor_type to the cursor we want to be displayed. */
20125 new_cursor_type = get_window_cursor_type (w, glyph,
20126 &new_cursor_width, &active_cursor);
20127
20128 /* If cursor is currently being shown and we don't want it to be or
20129 it is in the wrong place, or the cursor type is not what we want,
20130 erase it. */
20131 if (w->phys_cursor_on_p
20132 && (!on
20133 || w->phys_cursor.x != x
20134 || w->phys_cursor.y != y
20135 || new_cursor_type != w->phys_cursor_type
20136 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20137 && new_cursor_width != w->phys_cursor_width)))
20138 erase_phys_cursor (w);
20139
20140 /* Don't check phys_cursor_on_p here because that flag is only set
20141 to zero in some cases where we know that the cursor has been
20142 completely erased, to avoid the extra work of erasing the cursor
20143 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20144 still not be visible, or it has only been partly erased. */
20145 if (on)
20146 {
20147 w->phys_cursor_ascent = glyph_row->ascent;
20148 w->phys_cursor_height = glyph_row->height;
20149
20150 /* Set phys_cursor_.* before x_draw_.* is called because some
20151 of them may need the information. */
20152 w->phys_cursor.x = x;
20153 w->phys_cursor.y = glyph_row->y;
20154 w->phys_cursor.hpos = hpos;
20155 w->phys_cursor.vpos = vpos;
20156 }
20157
20158 rif->draw_window_cursor (w, glyph_row, x, y,
20159 new_cursor_type, new_cursor_width,
20160 on, active_cursor);
20161 }
20162
20163
20164 /* Switch the display of W's cursor on or off, according to the value
20165 of ON. */
20166
20167 static void
20168 update_window_cursor (w, on)
20169 struct window *w;
20170 int on;
20171 {
20172 /* Don't update cursor in windows whose frame is in the process
20173 of being deleted. */
20174 if (w->current_matrix)
20175 {
20176 BLOCK_INPUT;
20177 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20178 w->phys_cursor.x, w->phys_cursor.y);
20179 UNBLOCK_INPUT;
20180 }
20181 }
20182
20183
20184 /* Call update_window_cursor with parameter ON_P on all leaf windows
20185 in the window tree rooted at W. */
20186
20187 static void
20188 update_cursor_in_window_tree (w, on_p)
20189 struct window *w;
20190 int on_p;
20191 {
20192 while (w)
20193 {
20194 if (!NILP (w->hchild))
20195 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20196 else if (!NILP (w->vchild))
20197 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20198 else
20199 update_window_cursor (w, on_p);
20200
20201 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20202 }
20203 }
20204
20205
20206 /* EXPORT:
20207 Display the cursor on window W, or clear it, according to ON_P.
20208 Don't change the cursor's position. */
20209
20210 void
20211 x_update_cursor (f, on_p)
20212 struct frame *f;
20213 int on_p;
20214 {
20215 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20216 }
20217
20218
20219 /* EXPORT:
20220 Clear the cursor of window W to background color, and mark the
20221 cursor as not shown. This is used when the text where the cursor
20222 is is about to be rewritten. */
20223
20224 void
20225 x_clear_cursor (w)
20226 struct window *w;
20227 {
20228 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20229 update_window_cursor (w, 0);
20230 }
20231
20232
20233 /* EXPORT:
20234 Display the active region described by mouse_face_* according to DRAW. */
20235
20236 void
20237 show_mouse_face (dpyinfo, draw)
20238 Display_Info *dpyinfo;
20239 enum draw_glyphs_face draw;
20240 {
20241 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20242 struct frame *f = XFRAME (WINDOW_FRAME (w));
20243
20244 if (/* If window is in the process of being destroyed, don't bother
20245 to do anything. */
20246 w->current_matrix != NULL
20247 /* Don't update mouse highlight if hidden */
20248 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20249 /* Recognize when we are called to operate on rows that don't exist
20250 anymore. This can happen when a window is split. */
20251 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20252 {
20253 int phys_cursor_on_p = w->phys_cursor_on_p;
20254 struct glyph_row *row, *first, *last;
20255
20256 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20257 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20258
20259 for (row = first; row <= last && row->enabled_p; ++row)
20260 {
20261 int start_hpos, end_hpos, start_x;
20262
20263 /* For all but the first row, the highlight starts at column 0. */
20264 if (row == first)
20265 {
20266 start_hpos = dpyinfo->mouse_face_beg_col;
20267 start_x = dpyinfo->mouse_face_beg_x;
20268 }
20269 else
20270 {
20271 start_hpos = 0;
20272 start_x = 0;
20273 }
20274
20275 if (row == last)
20276 end_hpos = dpyinfo->mouse_face_end_col;
20277 else
20278 end_hpos = row->used[TEXT_AREA];
20279
20280 if (end_hpos > start_hpos)
20281 {
20282 draw_glyphs (w, start_x, row, TEXT_AREA,
20283 start_hpos, end_hpos,
20284 draw, 0);
20285
20286 row->mouse_face_p
20287 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20288 }
20289 }
20290
20291 /* When we've written over the cursor, arrange for it to
20292 be displayed again. */
20293 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20294 {
20295 BLOCK_INPUT;
20296 display_and_set_cursor (w, 1,
20297 w->phys_cursor.hpos, w->phys_cursor.vpos,
20298 w->phys_cursor.x, w->phys_cursor.y);
20299 UNBLOCK_INPUT;
20300 }
20301 }
20302
20303 /* Change the mouse cursor. */
20304 if (draw == DRAW_NORMAL_TEXT)
20305 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20306 else if (draw == DRAW_MOUSE_FACE)
20307 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20308 else
20309 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20310 }
20311
20312 /* EXPORT:
20313 Clear out the mouse-highlighted active region.
20314 Redraw it un-highlighted first. Value is non-zero if mouse
20315 face was actually drawn unhighlighted. */
20316
20317 int
20318 clear_mouse_face (dpyinfo)
20319 Display_Info *dpyinfo;
20320 {
20321 int cleared = 0;
20322
20323 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20324 {
20325 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20326 cleared = 1;
20327 }
20328
20329 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20330 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20331 dpyinfo->mouse_face_window = Qnil;
20332 dpyinfo->mouse_face_overlay = Qnil;
20333 return cleared;
20334 }
20335
20336
20337 /* EXPORT:
20338 Non-zero if physical cursor of window W is within mouse face. */
20339
20340 int
20341 cursor_in_mouse_face_p (w)
20342 struct window *w;
20343 {
20344 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20345 int in_mouse_face = 0;
20346
20347 if (WINDOWP (dpyinfo->mouse_face_window)
20348 && XWINDOW (dpyinfo->mouse_face_window) == w)
20349 {
20350 int hpos = w->phys_cursor.hpos;
20351 int vpos = w->phys_cursor.vpos;
20352
20353 if (vpos >= dpyinfo->mouse_face_beg_row
20354 && vpos <= dpyinfo->mouse_face_end_row
20355 && (vpos > dpyinfo->mouse_face_beg_row
20356 || hpos >= dpyinfo->mouse_face_beg_col)
20357 && (vpos < dpyinfo->mouse_face_end_row
20358 || hpos < dpyinfo->mouse_face_end_col
20359 || dpyinfo->mouse_face_past_end))
20360 in_mouse_face = 1;
20361 }
20362
20363 return in_mouse_face;
20364 }
20365
20366
20367
20368 \f
20369 /* Find the glyph matrix position of buffer position CHARPOS in window
20370 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20371 current glyphs must be up to date. If CHARPOS is above window
20372 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20373 of last line in W. In the row containing CHARPOS, stop before glyphs
20374 having STOP as object. */
20375
20376 #if 1 /* This is a version of fast_find_position that's more correct
20377 in the presence of hscrolling, for example. I didn't install
20378 it right away because the problem fixed is minor, it failed
20379 in 20.x as well, and I think it's too risky to install
20380 so near the release of 21.1. 2001-09-25 gerd. */
20381
20382 static int
20383 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20384 struct window *w;
20385 int charpos;
20386 int *hpos, *vpos, *x, *y;
20387 Lisp_Object stop;
20388 {
20389 struct glyph_row *row, *first;
20390 struct glyph *glyph, *end;
20391 int past_end = 0;
20392
20393 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20394 row = row_containing_pos (w, charpos, first, NULL, 0);
20395 if (row == NULL)
20396 {
20397 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20398 {
20399 *x = *y = *hpos = *vpos = 0;
20400 return 1;
20401 }
20402 else
20403 {
20404 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20405 past_end = 1;
20406 }
20407 }
20408
20409 *x = row->x;
20410 *y = row->y;
20411 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20412
20413 glyph = row->glyphs[TEXT_AREA];
20414 end = glyph + row->used[TEXT_AREA];
20415
20416 /* Skip over glyphs not having an object at the start of the row.
20417 These are special glyphs like truncation marks on terminal
20418 frames. */
20419 if (row->displays_text_p)
20420 while (glyph < end
20421 && INTEGERP (glyph->object)
20422 && !EQ (stop, glyph->object)
20423 && glyph->charpos < 0)
20424 {
20425 *x += glyph->pixel_width;
20426 ++glyph;
20427 }
20428
20429 while (glyph < end
20430 && !INTEGERP (glyph->object)
20431 && !EQ (stop, glyph->object)
20432 && (!BUFFERP (glyph->object)
20433 || glyph->charpos < charpos))
20434 {
20435 *x += glyph->pixel_width;
20436 ++glyph;
20437 }
20438
20439 *hpos = glyph - row->glyphs[TEXT_AREA];
20440 return !past_end;
20441 }
20442
20443 #else /* not 1 */
20444
20445 static int
20446 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20447 struct window *w;
20448 int pos;
20449 int *hpos, *vpos, *x, *y;
20450 Lisp_Object stop;
20451 {
20452 int i;
20453 int lastcol;
20454 int maybe_next_line_p = 0;
20455 int line_start_position;
20456 int yb = window_text_bottom_y (w);
20457 struct glyph_row *row, *best_row;
20458 int row_vpos, best_row_vpos;
20459 int current_x;
20460
20461 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20462 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20463
20464 while (row->y < yb)
20465 {
20466 if (row->used[TEXT_AREA])
20467 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20468 else
20469 line_start_position = 0;
20470
20471 if (line_start_position > pos)
20472 break;
20473 /* If the position sought is the end of the buffer,
20474 don't include the blank lines at the bottom of the window. */
20475 else if (line_start_position == pos
20476 && pos == BUF_ZV (XBUFFER (w->buffer)))
20477 {
20478 maybe_next_line_p = 1;
20479 break;
20480 }
20481 else if (line_start_position > 0)
20482 {
20483 best_row = row;
20484 best_row_vpos = row_vpos;
20485 }
20486
20487 if (row->y + row->height >= yb)
20488 break;
20489
20490 ++row;
20491 ++row_vpos;
20492 }
20493
20494 /* Find the right column within BEST_ROW. */
20495 lastcol = 0;
20496 current_x = best_row->x;
20497 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20498 {
20499 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20500 int charpos = glyph->charpos;
20501
20502 if (BUFFERP (glyph->object))
20503 {
20504 if (charpos == pos)
20505 {
20506 *hpos = i;
20507 *vpos = best_row_vpos;
20508 *x = current_x;
20509 *y = best_row->y;
20510 return 1;
20511 }
20512 else if (charpos > pos)
20513 break;
20514 }
20515 else if (EQ (glyph->object, stop))
20516 break;
20517
20518 if (charpos > 0)
20519 lastcol = i;
20520 current_x += glyph->pixel_width;
20521 }
20522
20523 /* If we're looking for the end of the buffer,
20524 and we didn't find it in the line we scanned,
20525 use the start of the following line. */
20526 if (maybe_next_line_p)
20527 {
20528 ++best_row;
20529 ++best_row_vpos;
20530 lastcol = 0;
20531 current_x = best_row->x;
20532 }
20533
20534 *vpos = best_row_vpos;
20535 *hpos = lastcol + 1;
20536 *x = current_x;
20537 *y = best_row->y;
20538 return 0;
20539 }
20540
20541 #endif /* not 1 */
20542
20543
20544 /* Find the position of the glyph for position POS in OBJECT in
20545 window W's current matrix, and return in *X, *Y the pixel
20546 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20547
20548 RIGHT_P non-zero means return the position of the right edge of the
20549 glyph, RIGHT_P zero means return the left edge position.
20550
20551 If no glyph for POS exists in the matrix, return the position of
20552 the glyph with the next smaller position that is in the matrix, if
20553 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20554 exists in the matrix, return the position of the glyph with the
20555 next larger position in OBJECT.
20556
20557 Value is non-zero if a glyph was found. */
20558
20559 static int
20560 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20561 struct window *w;
20562 int pos;
20563 Lisp_Object object;
20564 int *hpos, *vpos, *x, *y;
20565 int right_p;
20566 {
20567 int yb = window_text_bottom_y (w);
20568 struct glyph_row *r;
20569 struct glyph *best_glyph = NULL;
20570 struct glyph_row *best_row = NULL;
20571 int best_x = 0;
20572
20573 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20574 r->enabled_p && r->y < yb;
20575 ++r)
20576 {
20577 struct glyph *g = r->glyphs[TEXT_AREA];
20578 struct glyph *e = g + r->used[TEXT_AREA];
20579 int gx;
20580
20581 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20582 if (EQ (g->object, object))
20583 {
20584 if (g->charpos == pos)
20585 {
20586 best_glyph = g;
20587 best_x = gx;
20588 best_row = r;
20589 goto found;
20590 }
20591 else if (best_glyph == NULL
20592 || ((abs (g->charpos - pos)
20593 < abs (best_glyph->charpos - pos))
20594 && (right_p
20595 ? g->charpos < pos
20596 : g->charpos > pos)))
20597 {
20598 best_glyph = g;
20599 best_x = gx;
20600 best_row = r;
20601 }
20602 }
20603 }
20604
20605 found:
20606
20607 if (best_glyph)
20608 {
20609 *x = best_x;
20610 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20611
20612 if (right_p)
20613 {
20614 *x += best_glyph->pixel_width;
20615 ++*hpos;
20616 }
20617
20618 *y = best_row->y;
20619 *vpos = best_row - w->current_matrix->rows;
20620 }
20621
20622 return best_glyph != NULL;
20623 }
20624
20625
20626 /* See if position X, Y is within a hot-spot of an image. */
20627
20628 static int
20629 on_hot_spot_p (hot_spot, x, y)
20630 Lisp_Object hot_spot;
20631 int x, y;
20632 {
20633 if (!CONSP (hot_spot))
20634 return 0;
20635
20636 if (EQ (XCAR (hot_spot), Qrect))
20637 {
20638 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20639 Lisp_Object rect = XCDR (hot_spot);
20640 Lisp_Object tem;
20641 if (!CONSP (rect))
20642 return 0;
20643 if (!CONSP (XCAR (rect)))
20644 return 0;
20645 if (!CONSP (XCDR (rect)))
20646 return 0;
20647 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20648 return 0;
20649 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20650 return 0;
20651 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20652 return 0;
20653 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20654 return 0;
20655 return 1;
20656 }
20657 else if (EQ (XCAR (hot_spot), Qcircle))
20658 {
20659 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20660 Lisp_Object circ = XCDR (hot_spot);
20661 Lisp_Object lr, lx0, ly0;
20662 if (CONSP (circ)
20663 && CONSP (XCAR (circ))
20664 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20665 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20666 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20667 {
20668 double r = XFLOATINT (lr);
20669 double dx = XINT (lx0) - x;
20670 double dy = XINT (ly0) - y;
20671 return (dx * dx + dy * dy <= r * r);
20672 }
20673 }
20674 else if (EQ (XCAR (hot_spot), Qpoly))
20675 {
20676 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20677 if (VECTORP (XCDR (hot_spot)))
20678 {
20679 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20680 Lisp_Object *poly = v->contents;
20681 int n = v->size;
20682 int i;
20683 int inside = 0;
20684 Lisp_Object lx, ly;
20685 int x0, y0;
20686
20687 /* Need an even number of coordinates, and at least 3 edges. */
20688 if (n < 6 || n & 1)
20689 return 0;
20690
20691 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20692 If count is odd, we are inside polygon. Pixels on edges
20693 may or may not be included depending on actual geometry of the
20694 polygon. */
20695 if ((lx = poly[n-2], !INTEGERP (lx))
20696 || (ly = poly[n-1], !INTEGERP (lx)))
20697 return 0;
20698 x0 = XINT (lx), y0 = XINT (ly);
20699 for (i = 0; i < n; i += 2)
20700 {
20701 int x1 = x0, y1 = y0;
20702 if ((lx = poly[i], !INTEGERP (lx))
20703 || (ly = poly[i+1], !INTEGERP (ly)))
20704 return 0;
20705 x0 = XINT (lx), y0 = XINT (ly);
20706
20707 /* Does this segment cross the X line? */
20708 if (x0 >= x)
20709 {
20710 if (x1 >= x)
20711 continue;
20712 }
20713 else if (x1 < x)
20714 continue;
20715 if (y > y0 && y > y1)
20716 continue;
20717 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20718 inside = !inside;
20719 }
20720 return inside;
20721 }
20722 }
20723 /* If we don't understand the format, pretend we're not in the hot-spot. */
20724 return 0;
20725 }
20726
20727 Lisp_Object
20728 find_hot_spot (map, x, y)
20729 Lisp_Object map;
20730 int x, y;
20731 {
20732 while (CONSP (map))
20733 {
20734 if (CONSP (XCAR (map))
20735 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20736 return XCAR (map);
20737 map = XCDR (map);
20738 }
20739
20740 return Qnil;
20741 }
20742
20743 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20744 3, 3, 0,
20745 doc: /* Lookup in image map MAP coordinates X and Y.
20746 An image map is an alist where each element has the format (AREA ID PLIST).
20747 An AREA is specified as either a rectangle, a circle, or a polygon:
20748 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20749 pixel coordinates of the upper left and bottom right corners.
20750 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20751 and the radius of the circle; r may be a float or integer.
20752 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20753 vector describes one corner in the polygon.
20754 Returns the alist element for the first matching AREA in MAP. */)
20755 (map, x, y)
20756 Lisp_Object map;
20757 Lisp_Object x, y;
20758 {
20759 if (NILP (map))
20760 return Qnil;
20761
20762 CHECK_NUMBER (x);
20763 CHECK_NUMBER (y);
20764
20765 return find_hot_spot (map, XINT (x), XINT (y));
20766 }
20767
20768
20769 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20770 static void
20771 define_frame_cursor1 (f, cursor, pointer)
20772 struct frame *f;
20773 Cursor cursor;
20774 Lisp_Object pointer;
20775 {
20776 /* Do not change cursor shape while dragging mouse. */
20777 if (!NILP (do_mouse_tracking))
20778 return;
20779
20780 if (!NILP (pointer))
20781 {
20782 if (EQ (pointer, Qarrow))
20783 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20784 else if (EQ (pointer, Qhand))
20785 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20786 else if (EQ (pointer, Qtext))
20787 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20788 else if (EQ (pointer, intern ("hdrag")))
20789 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20790 #ifdef HAVE_X_WINDOWS
20791 else if (EQ (pointer, intern ("vdrag")))
20792 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20793 #endif
20794 else if (EQ (pointer, intern ("hourglass")))
20795 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20796 else if (EQ (pointer, Qmodeline))
20797 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20798 else
20799 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20800 }
20801
20802 if (cursor != No_Cursor)
20803 rif->define_frame_cursor (f, cursor);
20804 }
20805
20806 /* Take proper action when mouse has moved to the mode or header line
20807 or marginal area AREA of window W, x-position X and y-position Y.
20808 X is relative to the start of the text display area of W, so the
20809 width of bitmap areas and scroll bars must be subtracted to get a
20810 position relative to the start of the mode line. */
20811
20812 static void
20813 note_mode_line_or_margin_highlight (w, x, y, area)
20814 struct window *w;
20815 int x, y;
20816 enum window_part area;
20817 {
20818 struct frame *f = XFRAME (w->frame);
20819 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20820 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20821 Lisp_Object pointer = Qnil;
20822 int charpos, dx, dy, width, height;
20823 Lisp_Object string, object = Qnil;
20824 Lisp_Object pos, help;
20825
20826 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20827 string = mode_line_string (w, area, &x, &y, &charpos,
20828 &object, &dx, &dy, &width, &height);
20829 else
20830 {
20831 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20832 string = marginal_area_string (w, area, &x, &y, &charpos,
20833 &object, &dx, &dy, &width, &height);
20834 }
20835
20836 help = Qnil;
20837
20838 if (IMAGEP (object))
20839 {
20840 Lisp_Object image_map, hotspot;
20841 if ((image_map = Fplist_get (XCDR (object), QCmap),
20842 !NILP (image_map))
20843 && (hotspot = find_hot_spot (image_map, dx, dy),
20844 CONSP (hotspot))
20845 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20846 {
20847 Lisp_Object area_id, plist;
20848
20849 area_id = XCAR (hotspot);
20850 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20851 If so, we could look for mouse-enter, mouse-leave
20852 properties in PLIST (and do something...). */
20853 if ((plist = XCDR (hotspot), CONSP (plist)))
20854 {
20855 pointer = Fplist_get (plist, Qpointer);
20856 if (NILP (pointer))
20857 pointer = Qhand;
20858 help = Fplist_get (plist, Qhelp_echo);
20859 if (!NILP (help))
20860 {
20861 help_echo_string = help;
20862 /* Is this correct? ++kfs */
20863 XSETWINDOW (help_echo_window, w);
20864 help_echo_object = w->buffer;
20865 help_echo_pos = charpos;
20866 }
20867 }
20868 if (NILP (pointer))
20869 pointer = Fplist_get (XCDR (object), QCpointer);
20870 }
20871 }
20872
20873 if (STRINGP (string))
20874 {
20875 pos = make_number (charpos);
20876 /* If we're on a string with `help-echo' text property, arrange
20877 for the help to be displayed. This is done by setting the
20878 global variable help_echo_string to the help string. */
20879 help = Fget_text_property (pos, Qhelp_echo, string);
20880 if (!NILP (help))
20881 {
20882 help_echo_string = help;
20883 XSETWINDOW (help_echo_window, w);
20884 help_echo_object = string;
20885 help_echo_pos = charpos;
20886 }
20887
20888 if (NILP (pointer))
20889 pointer = Fget_text_property (pos, Qpointer, string);
20890
20891 /* Change the mouse pointer according to what is under X/Y. */
20892 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20893 {
20894 Lisp_Object map;
20895 map = Fget_text_property (pos, Qlocal_map, string);
20896 if (!KEYMAPP (map))
20897 map = Fget_text_property (pos, Qkeymap, string);
20898 if (!KEYMAPP (map))
20899 cursor = dpyinfo->vertical_scroll_bar_cursor;
20900 }
20901 }
20902
20903 define_frame_cursor1 (f, cursor, pointer);
20904 }
20905
20906
20907 /* EXPORT:
20908 Take proper action when the mouse has moved to position X, Y on
20909 frame F as regards highlighting characters that have mouse-face
20910 properties. Also de-highlighting chars where the mouse was before.
20911 X and Y can be negative or out of range. */
20912
20913 void
20914 note_mouse_highlight (f, x, y)
20915 struct frame *f;
20916 int x, y;
20917 {
20918 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20919 enum window_part part;
20920 Lisp_Object window;
20921 struct window *w;
20922 Cursor cursor = No_Cursor;
20923 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20924 struct buffer *b;
20925
20926 /* When a menu is active, don't highlight because this looks odd. */
20927 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20928 if (popup_activated ())
20929 return;
20930 #endif
20931
20932 if (NILP (Vmouse_highlight)
20933 || !f->glyphs_initialized_p)
20934 return;
20935
20936 dpyinfo->mouse_face_mouse_x = x;
20937 dpyinfo->mouse_face_mouse_y = y;
20938 dpyinfo->mouse_face_mouse_frame = f;
20939
20940 if (dpyinfo->mouse_face_defer)
20941 return;
20942
20943 if (gc_in_progress)
20944 {
20945 dpyinfo->mouse_face_deferred_gc = 1;
20946 return;
20947 }
20948
20949 /* Which window is that in? */
20950 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20951
20952 /* If we were displaying active text in another window, clear that. */
20953 if (! EQ (window, dpyinfo->mouse_face_window))
20954 clear_mouse_face (dpyinfo);
20955
20956 /* Not on a window -> return. */
20957 if (!WINDOWP (window))
20958 return;
20959
20960 /* Reset help_echo_string. It will get recomputed below. */
20961 help_echo_string = Qnil;
20962
20963 /* Convert to window-relative pixel coordinates. */
20964 w = XWINDOW (window);
20965 frame_to_window_pixel_xy (w, &x, &y);
20966
20967 /* Handle tool-bar window differently since it doesn't display a
20968 buffer. */
20969 if (EQ (window, f->tool_bar_window))
20970 {
20971 note_tool_bar_highlight (f, x, y);
20972 return;
20973 }
20974
20975 /* Mouse is on the mode, header line or margin? */
20976 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20977 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20978 {
20979 note_mode_line_or_margin_highlight (w, x, y, part);
20980 return;
20981 }
20982
20983 if (part == ON_VERTICAL_BORDER)
20984 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20985 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
20986 || part == ON_SCROLL_BAR)
20987 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20988 else
20989 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20990
20991 /* Are we in a window whose display is up to date?
20992 And verify the buffer's text has not changed. */
20993 b = XBUFFER (w->buffer);
20994 if (part == ON_TEXT
20995 && EQ (w->window_end_valid, w->buffer)
20996 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20997 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20998 {
20999 int hpos, vpos, pos, i, dx, dy, area;
21000 struct glyph *glyph;
21001 Lisp_Object object;
21002 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21003 Lisp_Object *overlay_vec = NULL;
21004 int noverlays;
21005 struct buffer *obuf;
21006 int obegv, ozv, same_region;
21007
21008 /* Find the glyph under X/Y. */
21009 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21010
21011 /* Look for :pointer property on image. */
21012 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21013 {
21014 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21015 if (img != NULL && IMAGEP (img->spec))
21016 {
21017 Lisp_Object image_map, hotspot;
21018 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21019 !NILP (image_map))
21020 && (hotspot = find_hot_spot (image_map,
21021 glyph->slice.x + dx,
21022 glyph->slice.y + dy),
21023 CONSP (hotspot))
21024 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21025 {
21026 Lisp_Object area_id, plist;
21027
21028 area_id = XCAR (hotspot);
21029 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21030 If so, we could look for mouse-enter, mouse-leave
21031 properties in PLIST (and do something...). */
21032 if ((plist = XCDR (hotspot), CONSP (plist)))
21033 {
21034 pointer = Fplist_get (plist, Qpointer);
21035 if (NILP (pointer))
21036 pointer = Qhand;
21037 help_echo_string = Fplist_get (plist, Qhelp_echo);
21038 if (!NILP (help_echo_string))
21039 {
21040 help_echo_window = window;
21041 help_echo_object = glyph->object;
21042 help_echo_pos = glyph->charpos;
21043 }
21044 }
21045 }
21046 if (NILP (pointer))
21047 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21048 }
21049 }
21050
21051 /* Clear mouse face if X/Y not over text. */
21052 if (glyph == NULL
21053 || area != TEXT_AREA
21054 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21055 {
21056 if (clear_mouse_face (dpyinfo))
21057 cursor = No_Cursor;
21058 if (NILP (pointer))
21059 {
21060 if (area != TEXT_AREA)
21061 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21062 else
21063 pointer = Vvoid_text_area_pointer;
21064 }
21065 goto set_cursor;
21066 }
21067
21068 pos = glyph->charpos;
21069 object = glyph->object;
21070 if (!STRINGP (object) && !BUFFERP (object))
21071 goto set_cursor;
21072
21073 /* If we get an out-of-range value, return now; avoid an error. */
21074 if (BUFFERP (object) && pos > BUF_Z (b))
21075 goto set_cursor;
21076
21077 /* Make the window's buffer temporarily current for
21078 overlays_at and compute_char_face. */
21079 obuf = current_buffer;
21080 current_buffer = b;
21081 obegv = BEGV;
21082 ozv = ZV;
21083 BEGV = BEG;
21084 ZV = Z;
21085
21086 /* Is this char mouse-active or does it have help-echo? */
21087 position = make_number (pos);
21088
21089 if (BUFFERP (object))
21090 {
21091 /* Put all the overlays we want in a vector in overlay_vec. */
21092 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21093 /* Sort overlays into increasing priority order. */
21094 noverlays = sort_overlays (overlay_vec, noverlays, w);
21095 }
21096 else
21097 noverlays = 0;
21098
21099 same_region = (EQ (window, dpyinfo->mouse_face_window)
21100 && vpos >= dpyinfo->mouse_face_beg_row
21101 && vpos <= dpyinfo->mouse_face_end_row
21102 && (vpos > dpyinfo->mouse_face_beg_row
21103 || hpos >= dpyinfo->mouse_face_beg_col)
21104 && (vpos < dpyinfo->mouse_face_end_row
21105 || hpos < dpyinfo->mouse_face_end_col
21106 || dpyinfo->mouse_face_past_end));
21107
21108 if (same_region)
21109 cursor = No_Cursor;
21110
21111 /* Check mouse-face highlighting. */
21112 if (! same_region
21113 /* If there exists an overlay with mouse-face overlapping
21114 the one we are currently highlighting, we have to
21115 check if we enter the overlapping overlay, and then
21116 highlight only that. */
21117 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21118 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21119 {
21120 /* Find the highest priority overlay that has a mouse-face
21121 property. */
21122 overlay = Qnil;
21123 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21124 {
21125 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21126 if (!NILP (mouse_face))
21127 overlay = overlay_vec[i];
21128 }
21129
21130 /* If we're actually highlighting the same overlay as
21131 before, there's no need to do that again. */
21132 if (!NILP (overlay)
21133 && EQ (overlay, dpyinfo->mouse_face_overlay))
21134 goto check_help_echo;
21135
21136 dpyinfo->mouse_face_overlay = overlay;
21137
21138 /* Clear the display of the old active region, if any. */
21139 if (clear_mouse_face (dpyinfo))
21140 cursor = No_Cursor;
21141
21142 /* If no overlay applies, get a text property. */
21143 if (NILP (overlay))
21144 mouse_face = Fget_text_property (position, Qmouse_face, object);
21145
21146 /* Handle the overlay case. */
21147 if (!NILP (overlay))
21148 {
21149 /* Find the range of text around this char that
21150 should be active. */
21151 Lisp_Object before, after;
21152 int ignore;
21153
21154 before = Foverlay_start (overlay);
21155 after = Foverlay_end (overlay);
21156 /* Record this as the current active region. */
21157 fast_find_position (w, XFASTINT (before),
21158 &dpyinfo->mouse_face_beg_col,
21159 &dpyinfo->mouse_face_beg_row,
21160 &dpyinfo->mouse_face_beg_x,
21161 &dpyinfo->mouse_face_beg_y, Qnil);
21162
21163 dpyinfo->mouse_face_past_end
21164 = !fast_find_position (w, XFASTINT (after),
21165 &dpyinfo->mouse_face_end_col,
21166 &dpyinfo->mouse_face_end_row,
21167 &dpyinfo->mouse_face_end_x,
21168 &dpyinfo->mouse_face_end_y, Qnil);
21169 dpyinfo->mouse_face_window = window;
21170
21171 dpyinfo->mouse_face_face_id
21172 = face_at_buffer_position (w, pos, 0, 0,
21173 &ignore, pos + 1,
21174 !dpyinfo->mouse_face_hidden);
21175
21176 /* Display it as active. */
21177 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21178 cursor = No_Cursor;
21179 }
21180 /* Handle the text property case. */
21181 else if (!NILP (mouse_face) && BUFFERP (object))
21182 {
21183 /* Find the range of text around this char that
21184 should be active. */
21185 Lisp_Object before, after, beginning, end;
21186 int ignore;
21187
21188 beginning = Fmarker_position (w->start);
21189 end = make_number (BUF_Z (XBUFFER (object))
21190 - XFASTINT (w->window_end_pos));
21191 before
21192 = Fprevious_single_property_change (make_number (pos + 1),
21193 Qmouse_face,
21194 object, beginning);
21195 after
21196 = Fnext_single_property_change (position, Qmouse_face,
21197 object, end);
21198
21199 /* Record this as the current active region. */
21200 fast_find_position (w, XFASTINT (before),
21201 &dpyinfo->mouse_face_beg_col,
21202 &dpyinfo->mouse_face_beg_row,
21203 &dpyinfo->mouse_face_beg_x,
21204 &dpyinfo->mouse_face_beg_y, Qnil);
21205 dpyinfo->mouse_face_past_end
21206 = !fast_find_position (w, XFASTINT (after),
21207 &dpyinfo->mouse_face_end_col,
21208 &dpyinfo->mouse_face_end_row,
21209 &dpyinfo->mouse_face_end_x,
21210 &dpyinfo->mouse_face_end_y, Qnil);
21211 dpyinfo->mouse_face_window = window;
21212
21213 if (BUFFERP (object))
21214 dpyinfo->mouse_face_face_id
21215 = face_at_buffer_position (w, pos, 0, 0,
21216 &ignore, pos + 1,
21217 !dpyinfo->mouse_face_hidden);
21218
21219 /* Display it as active. */
21220 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21221 cursor = No_Cursor;
21222 }
21223 else if (!NILP (mouse_face) && STRINGP (object))
21224 {
21225 Lisp_Object b, e;
21226 int ignore;
21227
21228 b = Fprevious_single_property_change (make_number (pos + 1),
21229 Qmouse_face,
21230 object, Qnil);
21231 e = Fnext_single_property_change (position, Qmouse_face,
21232 object, Qnil);
21233 if (NILP (b))
21234 b = make_number (0);
21235 if (NILP (e))
21236 e = make_number (SCHARS (object) - 1);
21237 fast_find_string_pos (w, XINT (b), object,
21238 &dpyinfo->mouse_face_beg_col,
21239 &dpyinfo->mouse_face_beg_row,
21240 &dpyinfo->mouse_face_beg_x,
21241 &dpyinfo->mouse_face_beg_y, 0);
21242 fast_find_string_pos (w, XINT (e), object,
21243 &dpyinfo->mouse_face_end_col,
21244 &dpyinfo->mouse_face_end_row,
21245 &dpyinfo->mouse_face_end_x,
21246 &dpyinfo->mouse_face_end_y, 1);
21247 dpyinfo->mouse_face_past_end = 0;
21248 dpyinfo->mouse_face_window = window;
21249 dpyinfo->mouse_face_face_id
21250 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21251 glyph->face_id, 1);
21252 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21253 cursor = No_Cursor;
21254 }
21255 else if (STRINGP (object) && NILP (mouse_face))
21256 {
21257 /* A string which doesn't have mouse-face, but
21258 the text ``under'' it might have. */
21259 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21260 int start = MATRIX_ROW_START_CHARPOS (r);
21261
21262 pos = string_buffer_position (w, object, start);
21263 if (pos > 0)
21264 mouse_face = get_char_property_and_overlay (make_number (pos),
21265 Qmouse_face,
21266 w->buffer,
21267 &overlay);
21268 if (!NILP (mouse_face) && !NILP (overlay))
21269 {
21270 Lisp_Object before = Foverlay_start (overlay);
21271 Lisp_Object after = Foverlay_end (overlay);
21272 int ignore;
21273
21274 /* Note that we might not be able to find position
21275 BEFORE in the glyph matrix if the overlay is
21276 entirely covered by a `display' property. In
21277 this case, we overshoot. So let's stop in
21278 the glyph matrix before glyphs for OBJECT. */
21279 fast_find_position (w, XFASTINT (before),
21280 &dpyinfo->mouse_face_beg_col,
21281 &dpyinfo->mouse_face_beg_row,
21282 &dpyinfo->mouse_face_beg_x,
21283 &dpyinfo->mouse_face_beg_y,
21284 object);
21285
21286 dpyinfo->mouse_face_past_end
21287 = !fast_find_position (w, XFASTINT (after),
21288 &dpyinfo->mouse_face_end_col,
21289 &dpyinfo->mouse_face_end_row,
21290 &dpyinfo->mouse_face_end_x,
21291 &dpyinfo->mouse_face_end_y,
21292 Qnil);
21293 dpyinfo->mouse_face_window = window;
21294 dpyinfo->mouse_face_face_id
21295 = face_at_buffer_position (w, pos, 0, 0,
21296 &ignore, pos + 1,
21297 !dpyinfo->mouse_face_hidden);
21298
21299 /* Display it as active. */
21300 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21301 cursor = No_Cursor;
21302 }
21303 }
21304 }
21305
21306 check_help_echo:
21307
21308 /* Look for a `help-echo' property. */
21309 if (NILP (help_echo_string)) {
21310 Lisp_Object help, overlay;
21311
21312 /* Check overlays first. */
21313 help = overlay = Qnil;
21314 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21315 {
21316 overlay = overlay_vec[i];
21317 help = Foverlay_get (overlay, Qhelp_echo);
21318 }
21319
21320 if (!NILP (help))
21321 {
21322 help_echo_string = help;
21323 help_echo_window = window;
21324 help_echo_object = overlay;
21325 help_echo_pos = pos;
21326 }
21327 else
21328 {
21329 Lisp_Object object = glyph->object;
21330 int charpos = glyph->charpos;
21331
21332 /* Try text properties. */
21333 if (STRINGP (object)
21334 && charpos >= 0
21335 && charpos < SCHARS (object))
21336 {
21337 help = Fget_text_property (make_number (charpos),
21338 Qhelp_echo, object);
21339 if (NILP (help))
21340 {
21341 /* If the string itself doesn't specify a help-echo,
21342 see if the buffer text ``under'' it does. */
21343 struct glyph_row *r
21344 = MATRIX_ROW (w->current_matrix, vpos);
21345 int start = MATRIX_ROW_START_CHARPOS (r);
21346 int pos = string_buffer_position (w, object, start);
21347 if (pos > 0)
21348 {
21349 help = Fget_char_property (make_number (pos),
21350 Qhelp_echo, w->buffer);
21351 if (!NILP (help))
21352 {
21353 charpos = pos;
21354 object = w->buffer;
21355 }
21356 }
21357 }
21358 }
21359 else if (BUFFERP (object)
21360 && charpos >= BEGV
21361 && charpos < ZV)
21362 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21363 object);
21364
21365 if (!NILP (help))
21366 {
21367 help_echo_string = help;
21368 help_echo_window = window;
21369 help_echo_object = object;
21370 help_echo_pos = charpos;
21371 }
21372 }
21373 }
21374
21375 /* Look for a `pointer' property. */
21376 if (NILP (pointer))
21377 {
21378 /* Check overlays first. */
21379 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21380 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21381
21382 if (NILP (pointer))
21383 {
21384 Lisp_Object object = glyph->object;
21385 int charpos = glyph->charpos;
21386
21387 /* Try text properties. */
21388 if (STRINGP (object)
21389 && charpos >= 0
21390 && charpos < SCHARS (object))
21391 {
21392 pointer = Fget_text_property (make_number (charpos),
21393 Qpointer, object);
21394 if (NILP (pointer))
21395 {
21396 /* If the string itself doesn't specify a pointer,
21397 see if the buffer text ``under'' it does. */
21398 struct glyph_row *r
21399 = MATRIX_ROW (w->current_matrix, vpos);
21400 int start = MATRIX_ROW_START_CHARPOS (r);
21401 int pos = string_buffer_position (w, object, start);
21402 if (pos > 0)
21403 pointer = Fget_char_property (make_number (pos),
21404 Qpointer, w->buffer);
21405 }
21406 }
21407 else if (BUFFERP (object)
21408 && charpos >= BEGV
21409 && charpos < ZV)
21410 pointer = Fget_text_property (make_number (charpos),
21411 Qpointer, object);
21412 }
21413 }
21414
21415 BEGV = obegv;
21416 ZV = ozv;
21417 current_buffer = obuf;
21418 }
21419
21420 set_cursor:
21421
21422 define_frame_cursor1 (f, cursor, pointer);
21423 }
21424
21425
21426 /* EXPORT for RIF:
21427 Clear any mouse-face on window W. This function is part of the
21428 redisplay interface, and is called from try_window_id and similar
21429 functions to ensure the mouse-highlight is off. */
21430
21431 void
21432 x_clear_window_mouse_face (w)
21433 struct window *w;
21434 {
21435 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21436 Lisp_Object window;
21437
21438 BLOCK_INPUT;
21439 XSETWINDOW (window, w);
21440 if (EQ (window, dpyinfo->mouse_face_window))
21441 clear_mouse_face (dpyinfo);
21442 UNBLOCK_INPUT;
21443 }
21444
21445
21446 /* EXPORT:
21447 Just discard the mouse face information for frame F, if any.
21448 This is used when the size of F is changed. */
21449
21450 void
21451 cancel_mouse_face (f)
21452 struct frame *f;
21453 {
21454 Lisp_Object window;
21455 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21456
21457 window = dpyinfo->mouse_face_window;
21458 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21459 {
21460 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21461 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21462 dpyinfo->mouse_face_window = Qnil;
21463 }
21464 }
21465
21466
21467 #endif /* HAVE_WINDOW_SYSTEM */
21468
21469 \f
21470 /***********************************************************************
21471 Exposure Events
21472 ***********************************************************************/
21473
21474 #ifdef HAVE_WINDOW_SYSTEM
21475
21476 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21477 which intersects rectangle R. R is in window-relative coordinates. */
21478
21479 static void
21480 expose_area (w, row, r, area)
21481 struct window *w;
21482 struct glyph_row *row;
21483 XRectangle *r;
21484 enum glyph_row_area area;
21485 {
21486 struct glyph *first = row->glyphs[area];
21487 struct glyph *end = row->glyphs[area] + row->used[area];
21488 struct glyph *last;
21489 int first_x, start_x, x;
21490
21491 if (area == TEXT_AREA && row->fill_line_p)
21492 /* If row extends face to end of line write the whole line. */
21493 draw_glyphs (w, 0, row, area,
21494 0, row->used[area],
21495 DRAW_NORMAL_TEXT, 0);
21496 else
21497 {
21498 /* Set START_X to the window-relative start position for drawing glyphs of
21499 AREA. The first glyph of the text area can be partially visible.
21500 The first glyphs of other areas cannot. */
21501 start_x = window_box_left_offset (w, area);
21502 x = start_x;
21503 if (area == TEXT_AREA)
21504 x += row->x;
21505
21506 /* Find the first glyph that must be redrawn. */
21507 while (first < end
21508 && x + first->pixel_width < r->x)
21509 {
21510 x += first->pixel_width;
21511 ++first;
21512 }
21513
21514 /* Find the last one. */
21515 last = first;
21516 first_x = x;
21517 while (last < end
21518 && x < r->x + r->width)
21519 {
21520 x += last->pixel_width;
21521 ++last;
21522 }
21523
21524 /* Repaint. */
21525 if (last > first)
21526 draw_glyphs (w, first_x - start_x, row, area,
21527 first - row->glyphs[area], last - row->glyphs[area],
21528 DRAW_NORMAL_TEXT, 0);
21529 }
21530 }
21531
21532
21533 /* Redraw the parts of the glyph row ROW on window W intersecting
21534 rectangle R. R is in window-relative coordinates. Value is
21535 non-zero if mouse-face was overwritten. */
21536
21537 static int
21538 expose_line (w, row, r)
21539 struct window *w;
21540 struct glyph_row *row;
21541 XRectangle *r;
21542 {
21543 xassert (row->enabled_p);
21544
21545 if (row->mode_line_p || w->pseudo_window_p)
21546 draw_glyphs (w, 0, row, TEXT_AREA,
21547 0, row->used[TEXT_AREA],
21548 DRAW_NORMAL_TEXT, 0);
21549 else
21550 {
21551 if (row->used[LEFT_MARGIN_AREA])
21552 expose_area (w, row, r, LEFT_MARGIN_AREA);
21553 if (row->used[TEXT_AREA])
21554 expose_area (w, row, r, TEXT_AREA);
21555 if (row->used[RIGHT_MARGIN_AREA])
21556 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21557 draw_row_fringe_bitmaps (w, row);
21558 }
21559
21560 return row->mouse_face_p;
21561 }
21562
21563
21564 /* Redraw those parts of glyphs rows during expose event handling that
21565 overlap other rows. Redrawing of an exposed line writes over parts
21566 of lines overlapping that exposed line; this function fixes that.
21567
21568 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21569 row in W's current matrix that is exposed and overlaps other rows.
21570 LAST_OVERLAPPING_ROW is the last such row. */
21571
21572 static void
21573 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21574 struct window *w;
21575 struct glyph_row *first_overlapping_row;
21576 struct glyph_row *last_overlapping_row;
21577 {
21578 struct glyph_row *row;
21579
21580 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21581 if (row->overlapping_p)
21582 {
21583 xassert (row->enabled_p && !row->mode_line_p);
21584
21585 if (row->used[LEFT_MARGIN_AREA])
21586 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21587
21588 if (row->used[TEXT_AREA])
21589 x_fix_overlapping_area (w, row, TEXT_AREA);
21590
21591 if (row->used[RIGHT_MARGIN_AREA])
21592 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21593 }
21594 }
21595
21596
21597 /* Return non-zero if W's cursor intersects rectangle R. */
21598
21599 static int
21600 phys_cursor_in_rect_p (w, r)
21601 struct window *w;
21602 XRectangle *r;
21603 {
21604 XRectangle cr, result;
21605 struct glyph *cursor_glyph;
21606
21607 cursor_glyph = get_phys_cursor_glyph (w);
21608 if (cursor_glyph)
21609 {
21610 /* r is relative to W's box, but w->phys_cursor.x is relative
21611 to left edge of W's TEXT area. Adjust it. */
21612 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21613 cr.y = w->phys_cursor.y;
21614 cr.width = cursor_glyph->pixel_width;
21615 cr.height = w->phys_cursor_height;
21616 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21617 I assume the effect is the same -- and this is portable. */
21618 return x_intersect_rectangles (&cr, r, &result);
21619 }
21620 else
21621 return 0;
21622 }
21623
21624
21625 /* EXPORT:
21626 Draw a vertical window border to the right of window W if W doesn't
21627 have vertical scroll bars. */
21628
21629 void
21630 x_draw_vertical_border (w)
21631 struct window *w;
21632 {
21633 /* We could do better, if we knew what type of scroll-bar the adjacent
21634 windows (on either side) have... But we don't :-(
21635 However, I think this works ok. ++KFS 2003-04-25 */
21636
21637 /* Redraw borders between horizontally adjacent windows. Don't
21638 do it for frames with vertical scroll bars because either the
21639 right scroll bar of a window, or the left scroll bar of its
21640 neighbor will suffice as a border. */
21641 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
21642 return;
21643
21644 if (!WINDOW_RIGHTMOST_P (w)
21645 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21646 {
21647 int x0, x1, y0, y1;
21648
21649 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21650 y1 -= 1;
21651
21652 rif->draw_vertical_window_border (w, x1, y0, y1);
21653 }
21654 else if (!WINDOW_LEFTMOST_P (w)
21655 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21656 {
21657 int x0, x1, y0, y1;
21658
21659 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21660 y1 -= 1;
21661
21662 rif->draw_vertical_window_border (w, x0, y0, y1);
21663 }
21664 }
21665
21666
21667 /* Redraw the part of window W intersection rectangle FR. Pixel
21668 coordinates in FR are frame-relative. Call this function with
21669 input blocked. Value is non-zero if the exposure overwrites
21670 mouse-face. */
21671
21672 static int
21673 expose_window (w, fr)
21674 struct window *w;
21675 XRectangle *fr;
21676 {
21677 struct frame *f = XFRAME (w->frame);
21678 XRectangle wr, r;
21679 int mouse_face_overwritten_p = 0;
21680
21681 /* If window is not yet fully initialized, do nothing. This can
21682 happen when toolkit scroll bars are used and a window is split.
21683 Reconfiguring the scroll bar will generate an expose for a newly
21684 created window. */
21685 if (w->current_matrix == NULL)
21686 return 0;
21687
21688 /* When we're currently updating the window, display and current
21689 matrix usually don't agree. Arrange for a thorough display
21690 later. */
21691 if (w == updated_window)
21692 {
21693 SET_FRAME_GARBAGED (f);
21694 return 0;
21695 }
21696
21697 /* Frame-relative pixel rectangle of W. */
21698 wr.x = WINDOW_LEFT_EDGE_X (w);
21699 wr.y = WINDOW_TOP_EDGE_Y (w);
21700 wr.width = WINDOW_TOTAL_WIDTH (w);
21701 wr.height = WINDOW_TOTAL_HEIGHT (w);
21702
21703 if (x_intersect_rectangles (fr, &wr, &r))
21704 {
21705 int yb = window_text_bottom_y (w);
21706 struct glyph_row *row;
21707 int cursor_cleared_p;
21708 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21709
21710 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21711 r.x, r.y, r.width, r.height));
21712
21713 /* Convert to window coordinates. */
21714 r.x -= WINDOW_LEFT_EDGE_X (w);
21715 r.y -= WINDOW_TOP_EDGE_Y (w);
21716
21717 /* Turn off the cursor. */
21718 if (!w->pseudo_window_p
21719 && phys_cursor_in_rect_p (w, &r))
21720 {
21721 x_clear_cursor (w);
21722 cursor_cleared_p = 1;
21723 }
21724 else
21725 cursor_cleared_p = 0;
21726
21727 /* Update lines intersecting rectangle R. */
21728 first_overlapping_row = last_overlapping_row = NULL;
21729 for (row = w->current_matrix->rows;
21730 row->enabled_p;
21731 ++row)
21732 {
21733 int y0 = row->y;
21734 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21735
21736 if ((y0 >= r.y && y0 < r.y + r.height)
21737 || (y1 > r.y && y1 < r.y + r.height)
21738 || (r.y >= y0 && r.y < y1)
21739 || (r.y + r.height > y0 && r.y + r.height < y1))
21740 {
21741 if (row->overlapping_p)
21742 {
21743 if (first_overlapping_row == NULL)
21744 first_overlapping_row = row;
21745 last_overlapping_row = row;
21746 }
21747
21748 if (expose_line (w, row, &r))
21749 mouse_face_overwritten_p = 1;
21750 }
21751
21752 if (y1 >= yb)
21753 break;
21754 }
21755
21756 /* Display the mode line if there is one. */
21757 if (WINDOW_WANTS_MODELINE_P (w)
21758 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21759 row->enabled_p)
21760 && row->y < r.y + r.height)
21761 {
21762 if (expose_line (w, row, &r))
21763 mouse_face_overwritten_p = 1;
21764 }
21765
21766 if (!w->pseudo_window_p)
21767 {
21768 /* Fix the display of overlapping rows. */
21769 if (first_overlapping_row)
21770 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21771
21772 /* Draw border between windows. */
21773 x_draw_vertical_border (w);
21774
21775 /* Turn the cursor on again. */
21776 if (cursor_cleared_p)
21777 update_window_cursor (w, 1);
21778 }
21779 }
21780
21781 #ifdef HAVE_CARBON
21782 /* Display scroll bar for this window. */
21783 if (!NILP (w->vertical_scroll_bar))
21784 {
21785 /* ++KFS:
21786 If this doesn't work here (maybe some header files are missing),
21787 make a function in macterm.c and call it to do the job! */
21788 ControlHandle ch
21789 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21790
21791 Draw1Control (ch);
21792 }
21793 #endif
21794
21795 return mouse_face_overwritten_p;
21796 }
21797
21798
21799
21800 /* Redraw (parts) of all windows in the window tree rooted at W that
21801 intersect R. R contains frame pixel coordinates. Value is
21802 non-zero if the exposure overwrites mouse-face. */
21803
21804 static int
21805 expose_window_tree (w, r)
21806 struct window *w;
21807 XRectangle *r;
21808 {
21809 struct frame *f = XFRAME (w->frame);
21810 int mouse_face_overwritten_p = 0;
21811
21812 while (w && !FRAME_GARBAGED_P (f))
21813 {
21814 if (!NILP (w->hchild))
21815 mouse_face_overwritten_p
21816 |= expose_window_tree (XWINDOW (w->hchild), r);
21817 else if (!NILP (w->vchild))
21818 mouse_face_overwritten_p
21819 |= expose_window_tree (XWINDOW (w->vchild), r);
21820 else
21821 mouse_face_overwritten_p |= expose_window (w, r);
21822
21823 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21824 }
21825
21826 return mouse_face_overwritten_p;
21827 }
21828
21829
21830 /* EXPORT:
21831 Redisplay an exposed area of frame F. X and Y are the upper-left
21832 corner of the exposed rectangle. W and H are width and height of
21833 the exposed area. All are pixel values. W or H zero means redraw
21834 the entire frame. */
21835
21836 void
21837 expose_frame (f, x, y, w, h)
21838 struct frame *f;
21839 int x, y, w, h;
21840 {
21841 XRectangle r;
21842 int mouse_face_overwritten_p = 0;
21843
21844 TRACE ((stderr, "expose_frame "));
21845
21846 /* No need to redraw if frame will be redrawn soon. */
21847 if (FRAME_GARBAGED_P (f))
21848 {
21849 TRACE ((stderr, " garbaged\n"));
21850 return;
21851 }
21852
21853 #ifdef HAVE_CARBON
21854 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21855 or deactivated here, for unknown reasons, activated scroll bars
21856 are shown in deactivated frames in some instances. */
21857 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21858 activate_scroll_bars (f);
21859 else
21860 deactivate_scroll_bars (f);
21861 #endif
21862
21863 /* If basic faces haven't been realized yet, there is no point in
21864 trying to redraw anything. This can happen when we get an expose
21865 event while Emacs is starting, e.g. by moving another window. */
21866 if (FRAME_FACE_CACHE (f) == NULL
21867 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21868 {
21869 TRACE ((stderr, " no faces\n"));
21870 return;
21871 }
21872
21873 if (w == 0 || h == 0)
21874 {
21875 r.x = r.y = 0;
21876 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21877 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21878 }
21879 else
21880 {
21881 r.x = x;
21882 r.y = y;
21883 r.width = w;
21884 r.height = h;
21885 }
21886
21887 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21888 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21889
21890 if (WINDOWP (f->tool_bar_window))
21891 mouse_face_overwritten_p
21892 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21893
21894 #ifdef HAVE_X_WINDOWS
21895 #ifndef MSDOS
21896 #ifndef USE_X_TOOLKIT
21897 if (WINDOWP (f->menu_bar_window))
21898 mouse_face_overwritten_p
21899 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21900 #endif /* not USE_X_TOOLKIT */
21901 #endif
21902 #endif
21903
21904 /* Some window managers support a focus-follows-mouse style with
21905 delayed raising of frames. Imagine a partially obscured frame,
21906 and moving the mouse into partially obscured mouse-face on that
21907 frame. The visible part of the mouse-face will be highlighted,
21908 then the WM raises the obscured frame. With at least one WM, KDE
21909 2.1, Emacs is not getting any event for the raising of the frame
21910 (even tried with SubstructureRedirectMask), only Expose events.
21911 These expose events will draw text normally, i.e. not
21912 highlighted. Which means we must redo the highlight here.
21913 Subsume it under ``we love X''. --gerd 2001-08-15 */
21914 /* Included in Windows version because Windows most likely does not
21915 do the right thing if any third party tool offers
21916 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21917 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21918 {
21919 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21920 if (f == dpyinfo->mouse_face_mouse_frame)
21921 {
21922 int x = dpyinfo->mouse_face_mouse_x;
21923 int y = dpyinfo->mouse_face_mouse_y;
21924 clear_mouse_face (dpyinfo);
21925 note_mouse_highlight (f, x, y);
21926 }
21927 }
21928 }
21929
21930
21931 /* EXPORT:
21932 Determine the intersection of two rectangles R1 and R2. Return
21933 the intersection in *RESULT. Value is non-zero if RESULT is not
21934 empty. */
21935
21936 int
21937 x_intersect_rectangles (r1, r2, result)
21938 XRectangle *r1, *r2, *result;
21939 {
21940 XRectangle *left, *right;
21941 XRectangle *upper, *lower;
21942 int intersection_p = 0;
21943
21944 /* Rearrange so that R1 is the left-most rectangle. */
21945 if (r1->x < r2->x)
21946 left = r1, right = r2;
21947 else
21948 left = r2, right = r1;
21949
21950 /* X0 of the intersection is right.x0, if this is inside R1,
21951 otherwise there is no intersection. */
21952 if (right->x <= left->x + left->width)
21953 {
21954 result->x = right->x;
21955
21956 /* The right end of the intersection is the minimum of the
21957 the right ends of left and right. */
21958 result->width = (min (left->x + left->width, right->x + right->width)
21959 - result->x);
21960
21961 /* Same game for Y. */
21962 if (r1->y < r2->y)
21963 upper = r1, lower = r2;
21964 else
21965 upper = r2, lower = r1;
21966
21967 /* The upper end of the intersection is lower.y0, if this is inside
21968 of upper. Otherwise, there is no intersection. */
21969 if (lower->y <= upper->y + upper->height)
21970 {
21971 result->y = lower->y;
21972
21973 /* The lower end of the intersection is the minimum of the lower
21974 ends of upper and lower. */
21975 result->height = (min (lower->y + lower->height,
21976 upper->y + upper->height)
21977 - result->y);
21978 intersection_p = 1;
21979 }
21980 }
21981
21982 return intersection_p;
21983 }
21984
21985 #endif /* HAVE_WINDOW_SYSTEM */
21986
21987 \f
21988 /***********************************************************************
21989 Initialization
21990 ***********************************************************************/
21991
21992 void
21993 syms_of_xdisp ()
21994 {
21995 Vwith_echo_area_save_vector = Qnil;
21996 staticpro (&Vwith_echo_area_save_vector);
21997
21998 Vmessage_stack = Qnil;
21999 staticpro (&Vmessage_stack);
22000
22001 Qinhibit_redisplay = intern ("inhibit-redisplay");
22002 staticpro (&Qinhibit_redisplay);
22003
22004 message_dolog_marker1 = Fmake_marker ();
22005 staticpro (&message_dolog_marker1);
22006 message_dolog_marker2 = Fmake_marker ();
22007 staticpro (&message_dolog_marker2);
22008 message_dolog_marker3 = Fmake_marker ();
22009 staticpro (&message_dolog_marker3);
22010
22011 #if GLYPH_DEBUG
22012 defsubr (&Sdump_frame_glyph_matrix);
22013 defsubr (&Sdump_glyph_matrix);
22014 defsubr (&Sdump_glyph_row);
22015 defsubr (&Sdump_tool_bar_row);
22016 defsubr (&Strace_redisplay);
22017 defsubr (&Strace_to_stderr);
22018 #endif
22019 #ifdef HAVE_WINDOW_SYSTEM
22020 defsubr (&Stool_bar_lines_needed);
22021 defsubr (&Slookup_image_map);
22022 #endif
22023 defsubr (&Sformat_mode_line);
22024
22025 staticpro (&Qmenu_bar_update_hook);
22026 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22027
22028 staticpro (&Qoverriding_terminal_local_map);
22029 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22030
22031 staticpro (&Qoverriding_local_map);
22032 Qoverriding_local_map = intern ("overriding-local-map");
22033
22034 staticpro (&Qwindow_scroll_functions);
22035 Qwindow_scroll_functions = intern ("window-scroll-functions");
22036
22037 staticpro (&Qredisplay_end_trigger_functions);
22038 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22039
22040 staticpro (&Qinhibit_point_motion_hooks);
22041 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22042
22043 QCdata = intern (":data");
22044 staticpro (&QCdata);
22045 Qdisplay = intern ("display");
22046 staticpro (&Qdisplay);
22047 Qspace_width = intern ("space-width");
22048 staticpro (&Qspace_width);
22049 Qraise = intern ("raise");
22050 staticpro (&Qraise);
22051 Qslice = intern ("slice");
22052 staticpro (&Qslice);
22053 Qspace = intern ("space");
22054 staticpro (&Qspace);
22055 Qmargin = intern ("margin");
22056 staticpro (&Qmargin);
22057 Qpointer = intern ("pointer");
22058 staticpro (&Qpointer);
22059 Qleft_margin = intern ("left-margin");
22060 staticpro (&Qleft_margin);
22061 Qright_margin = intern ("right-margin");
22062 staticpro (&Qright_margin);
22063 Qcenter = intern ("center");
22064 staticpro (&Qcenter);
22065 Qline_height = intern ("line-height");
22066 staticpro (&Qline_height);
22067 Qtotal = intern ("total");
22068 staticpro (&Qtotal);
22069 QCalign_to = intern (":align-to");
22070 staticpro (&QCalign_to);
22071 QCrelative_width = intern (":relative-width");
22072 staticpro (&QCrelative_width);
22073 QCrelative_height = intern (":relative-height");
22074 staticpro (&QCrelative_height);
22075 QCeval = intern (":eval");
22076 staticpro (&QCeval);
22077 QCpropertize = intern (":propertize");
22078 staticpro (&QCpropertize);
22079 QCfile = intern (":file");
22080 staticpro (&QCfile);
22081 Qfontified = intern ("fontified");
22082 staticpro (&Qfontified);
22083 Qfontification_functions = intern ("fontification-functions");
22084 staticpro (&Qfontification_functions);
22085 Qtrailing_whitespace = intern ("trailing-whitespace");
22086 staticpro (&Qtrailing_whitespace);
22087 Qimage = intern ("image");
22088 staticpro (&Qimage);
22089 QCmap = intern (":map");
22090 staticpro (&QCmap);
22091 QCpointer = intern (":pointer");
22092 staticpro (&QCpointer);
22093 Qrect = intern ("rect");
22094 staticpro (&Qrect);
22095 Qcircle = intern ("circle");
22096 staticpro (&Qcircle);
22097 Qpoly = intern ("poly");
22098 staticpro (&Qpoly);
22099 Qmessage_truncate_lines = intern ("message-truncate-lines");
22100 staticpro (&Qmessage_truncate_lines);
22101 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22102 staticpro (&Qcursor_in_non_selected_windows);
22103 Qgrow_only = intern ("grow-only");
22104 staticpro (&Qgrow_only);
22105 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22106 staticpro (&Qinhibit_menubar_update);
22107 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22108 staticpro (&Qinhibit_eval_during_redisplay);
22109 Qposition = intern ("position");
22110 staticpro (&Qposition);
22111 Qbuffer_position = intern ("buffer-position");
22112 staticpro (&Qbuffer_position);
22113 Qobject = intern ("object");
22114 staticpro (&Qobject);
22115 Qbar = intern ("bar");
22116 staticpro (&Qbar);
22117 Qhbar = intern ("hbar");
22118 staticpro (&Qhbar);
22119 Qbox = intern ("box");
22120 staticpro (&Qbox);
22121 Qhollow = intern ("hollow");
22122 staticpro (&Qhollow);
22123 Qhand = intern ("hand");
22124 staticpro (&Qhand);
22125 Qarrow = intern ("arrow");
22126 staticpro (&Qarrow);
22127 Qtext = intern ("text");
22128 staticpro (&Qtext);
22129 Qrisky_local_variable = intern ("risky-local-variable");
22130 staticpro (&Qrisky_local_variable);
22131 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22132 staticpro (&Qinhibit_free_realized_faces);
22133
22134 list_of_error = Fcons (Fcons (intern ("error"),
22135 Fcons (intern ("void-variable"), Qnil)),
22136 Qnil);
22137 staticpro (&list_of_error);
22138
22139 Qlast_arrow_position = intern ("last-arrow-position");
22140 staticpro (&Qlast_arrow_position);
22141 Qlast_arrow_string = intern ("last-arrow-string");
22142 staticpro (&Qlast_arrow_string);
22143
22144 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22145 staticpro (&Qoverlay_arrow_string);
22146 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22147 staticpro (&Qoverlay_arrow_bitmap);
22148
22149 echo_buffer[0] = echo_buffer[1] = Qnil;
22150 staticpro (&echo_buffer[0]);
22151 staticpro (&echo_buffer[1]);
22152
22153 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22154 staticpro (&echo_area_buffer[0]);
22155 staticpro (&echo_area_buffer[1]);
22156
22157 Vmessages_buffer_name = build_string ("*Messages*");
22158 staticpro (&Vmessages_buffer_name);
22159
22160 mode_line_proptrans_alist = Qnil;
22161 staticpro (&mode_line_proptrans_alist);
22162
22163 mode_line_string_list = Qnil;
22164 staticpro (&mode_line_string_list);
22165
22166 help_echo_string = Qnil;
22167 staticpro (&help_echo_string);
22168 help_echo_object = Qnil;
22169 staticpro (&help_echo_object);
22170 help_echo_window = Qnil;
22171 staticpro (&help_echo_window);
22172 previous_help_echo_string = Qnil;
22173 staticpro (&previous_help_echo_string);
22174 help_echo_pos = -1;
22175
22176 #ifdef HAVE_WINDOW_SYSTEM
22177 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22178 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22179 For example, if a block cursor is over a tab, it will be drawn as
22180 wide as that tab on the display. */);
22181 x_stretch_cursor_p = 0;
22182 #endif
22183
22184 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22185 doc: /* *Non-nil means highlight trailing whitespace.
22186 The face used for trailing whitespace is `trailing-whitespace'. */);
22187 Vshow_trailing_whitespace = Qnil;
22188
22189 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22190 doc: /* *The pointer shape to show in void text areas.
22191 Nil means to show the text pointer. Other options are `arrow', `text',
22192 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22193 Vvoid_text_area_pointer = Qarrow;
22194
22195 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22196 doc: /* Non-nil means don't actually do any redisplay.
22197 This is used for internal purposes. */);
22198 Vinhibit_redisplay = Qnil;
22199
22200 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22201 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22202 Vglobal_mode_string = Qnil;
22203
22204 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22205 doc: /* Marker for where to display an arrow on top of the buffer text.
22206 This must be the beginning of a line in order to work.
22207 See also `overlay-arrow-string'. */);
22208 Voverlay_arrow_position = Qnil;
22209
22210 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22211 doc: /* String to display as an arrow in non-window frames.
22212 See also `overlay-arrow-position'. */);
22213 Voverlay_arrow_string = Qnil;
22214
22215 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22216 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22217 The symbols on this list are examined during redisplay to determine
22218 where to display overlay arrows. */);
22219 Voverlay_arrow_variable_list
22220 = Fcons (intern ("overlay-arrow-position"), Qnil);
22221
22222 DEFVAR_INT ("scroll-step", &scroll_step,
22223 doc: /* *The number of lines to try scrolling a window by when point moves out.
22224 If that fails to bring point back on frame, point is centered instead.
22225 If this is zero, point is always centered after it moves off frame.
22226 If you want scrolling to always be a line at a time, you should set
22227 `scroll-conservatively' to a large value rather than set this to 1. */);
22228
22229 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22230 doc: /* *Scroll up to this many lines, to bring point back on screen.
22231 A value of zero means to scroll the text to center point vertically
22232 in the window. */);
22233 scroll_conservatively = 0;
22234
22235 DEFVAR_INT ("scroll-margin", &scroll_margin,
22236 doc: /* *Number of lines of margin at the top and bottom of a window.
22237 Recenter the window whenever point gets within this many lines
22238 of the top or bottom of the window. */);
22239 scroll_margin = 0;
22240
22241 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22242 doc: /* Pixels per inch on current display.
22243 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22244 Vdisplay_pixels_per_inch = make_float (72.0);
22245
22246 #if GLYPH_DEBUG
22247 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22248 #endif
22249
22250 DEFVAR_BOOL ("truncate-partial-width-windows",
22251 &truncate_partial_width_windows,
22252 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22253 truncate_partial_width_windows = 1;
22254
22255 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22256 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22257 Any other value means to use the appropriate face, `mode-line',
22258 `header-line', or `menu' respectively. */);
22259 mode_line_inverse_video = 1;
22260
22261 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22262 doc: /* *Maximum buffer size for which line number should be displayed.
22263 If the buffer is bigger than this, the line number does not appear
22264 in the mode line. A value of nil means no limit. */);
22265 Vline_number_display_limit = Qnil;
22266
22267 DEFVAR_INT ("line-number-display-limit-width",
22268 &line_number_display_limit_width,
22269 doc: /* *Maximum line width (in characters) for line number display.
22270 If the average length of the lines near point is bigger than this, then the
22271 line number may be omitted from the mode line. */);
22272 line_number_display_limit_width = 200;
22273
22274 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22275 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22276 highlight_nonselected_windows = 0;
22277
22278 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22279 doc: /* Non-nil if more than one frame is visible on this display.
22280 Minibuffer-only frames don't count, but iconified frames do.
22281 This variable is not guaranteed to be accurate except while processing
22282 `frame-title-format' and `icon-title-format'. */);
22283
22284 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22285 doc: /* Template for displaying the title bar of visible frames.
22286 \(Assuming the window manager supports this feature.)
22287 This variable has the same structure as `mode-line-format' (which see),
22288 and is used only on frames for which no explicit name has been set
22289 \(see `modify-frame-parameters'). */);
22290
22291 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22292 doc: /* Template for displaying the title bar of an iconified frame.
22293 \(Assuming the window manager supports this feature.)
22294 This variable has the same structure as `mode-line-format' (which see),
22295 and is used only on frames for which no explicit name has been set
22296 \(see `modify-frame-parameters'). */);
22297 Vicon_title_format
22298 = Vframe_title_format
22299 = Fcons (intern ("multiple-frames"),
22300 Fcons (build_string ("%b"),
22301 Fcons (Fcons (empty_string,
22302 Fcons (intern ("invocation-name"),
22303 Fcons (build_string ("@"),
22304 Fcons (intern ("system-name"),
22305 Qnil)))),
22306 Qnil)));
22307
22308 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22309 doc: /* Maximum number of lines to keep in the message log buffer.
22310 If nil, disable message logging. If t, log messages but don't truncate
22311 the buffer when it becomes large. */);
22312 Vmessage_log_max = make_number (50);
22313
22314 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22315 doc: /* Functions called before redisplay, if window sizes have changed.
22316 The value should be a list of functions that take one argument.
22317 Just before redisplay, for each frame, if any of its windows have changed
22318 size since the last redisplay, or have been split or deleted,
22319 all the functions in the list are called, with the frame as argument. */);
22320 Vwindow_size_change_functions = Qnil;
22321
22322 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22323 doc: /* List of functions to call before redisplaying a window with scrolling.
22324 Each function is called with two arguments, the window
22325 and its new display-start position. Note that the value of `window-end'
22326 is not valid when these functions are called. */);
22327 Vwindow_scroll_functions = Qnil;
22328
22329 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22330 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22331 mouse_autoselect_window = 0;
22332
22333 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22334 doc: /* *Non-nil means automatically resize tool-bars.
22335 This increases a tool-bar's height if not all tool-bar items are visible.
22336 It decreases a tool-bar's height when it would display blank lines
22337 otherwise. */);
22338 auto_resize_tool_bars_p = 1;
22339
22340 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22341 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22342 auto_raise_tool_bar_buttons_p = 1;
22343
22344 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22345 doc: /* *Margin around tool-bar buttons in pixels.
22346 If an integer, use that for both horizontal and vertical margins.
22347 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22348 HORZ specifying the horizontal margin, and VERT specifying the
22349 vertical margin. */);
22350 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22351
22352 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22353 doc: /* *Relief thickness of tool-bar buttons. */);
22354 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22355
22356 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22357 doc: /* List of functions to call to fontify regions of text.
22358 Each function is called with one argument POS. Functions must
22359 fontify a region starting at POS in the current buffer, and give
22360 fontified regions the property `fontified'. */);
22361 Vfontification_functions = Qnil;
22362 Fmake_variable_buffer_local (Qfontification_functions);
22363
22364 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22365 &unibyte_display_via_language_environment,
22366 doc: /* *Non-nil means display unibyte text according to language environment.
22367 Specifically this means that unibyte non-ASCII characters
22368 are displayed by converting them to the equivalent multibyte characters
22369 according to the current language environment. As a result, they are
22370 displayed according to the current fontset. */);
22371 unibyte_display_via_language_environment = 0;
22372
22373 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22374 doc: /* *Maximum height for resizing mini-windows.
22375 If a float, it specifies a fraction of the mini-window frame's height.
22376 If an integer, it specifies a number of lines. */);
22377 Vmax_mini_window_height = make_float (0.25);
22378
22379 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22380 doc: /* *How to resize mini-windows.
22381 A value of nil means don't automatically resize mini-windows.
22382 A value of t means resize them to fit the text displayed in them.
22383 A value of `grow-only', the default, means let mini-windows grow
22384 only, until their display becomes empty, at which point the windows
22385 go back to their normal size. */);
22386 Vresize_mini_windows = Qgrow_only;
22387
22388 DEFVAR_LISP ("cursor-in-non-selected-windows",
22389 &Vcursor_in_non_selected_windows,
22390 doc: /* *Cursor type to display in non-selected windows.
22391 t means to use hollow box cursor. See `cursor-type' for other values. */);
22392 Vcursor_in_non_selected_windows = Qt;
22393
22394 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22395 doc: /* Alist specifying how to blink the cursor off.
22396 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22397 `cursor-type' frame-parameter or variable equals ON-STATE,
22398 comparing using `equal', Emacs uses OFF-STATE to specify
22399 how to blink it off. */);
22400 Vblink_cursor_alist = Qnil;
22401
22402 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22403 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22404 automatic_hscrolling_p = 1;
22405
22406 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22407 doc: /* *How many columns away from the window edge point is allowed to get
22408 before automatic hscrolling will horizontally scroll the window. */);
22409 hscroll_margin = 5;
22410
22411 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22412 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22413 When point is less than `automatic-hscroll-margin' columns from the window
22414 edge, automatic hscrolling will scroll the window by the amount of columns
22415 determined by this variable. If its value is a positive integer, scroll that
22416 many columns. If it's a positive floating-point number, it specifies the
22417 fraction of the window's width to scroll. If it's nil or zero, point will be
22418 centered horizontally after the scroll. Any other value, including negative
22419 numbers, are treated as if the value were zero.
22420
22421 Automatic hscrolling always moves point outside the scroll margin, so if
22422 point was more than scroll step columns inside the margin, the window will
22423 scroll more than the value given by the scroll step.
22424
22425 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22426 and `scroll-right' overrides this variable's effect. */);
22427 Vhscroll_step = make_number (0);
22428
22429 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22430 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22431 Bind this around calls to `message' to let it take effect. */);
22432 message_truncate_lines = 0;
22433
22434 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22435 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22436 Can be used to update submenus whose contents should vary. */);
22437 Vmenu_bar_update_hook = Qnil;
22438
22439 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22440 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22441 inhibit_menubar_update = 0;
22442
22443 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22444 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22445 inhibit_eval_during_redisplay = 0;
22446
22447 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22448 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22449 inhibit_free_realized_faces = 0;
22450
22451 #if GLYPH_DEBUG
22452 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22453 doc: /* Inhibit try_window_id display optimization. */);
22454 inhibit_try_window_id = 0;
22455
22456 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22457 doc: /* Inhibit try_window_reusing display optimization. */);
22458 inhibit_try_window_reusing = 0;
22459
22460 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22461 doc: /* Inhibit try_cursor_movement display optimization. */);
22462 inhibit_try_cursor_movement = 0;
22463 #endif /* GLYPH_DEBUG */
22464 }
22465
22466
22467 /* Initialize this module when Emacs starts. */
22468
22469 void
22470 init_xdisp ()
22471 {
22472 Lisp_Object root_window;
22473 struct window *mini_w;
22474
22475 current_header_line_height = current_mode_line_height = -1;
22476
22477 CHARPOS (this_line_start_pos) = 0;
22478
22479 mini_w = XWINDOW (minibuf_window);
22480 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22481
22482 if (!noninteractive)
22483 {
22484 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22485 int i;
22486
22487 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22488 set_window_height (root_window,
22489 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22490 0);
22491 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22492 set_window_height (minibuf_window, 1, 0);
22493
22494 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22495 mini_w->total_cols = make_number (FRAME_COLS (f));
22496
22497 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22498 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22499 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22500
22501 /* The default ellipsis glyphs `...'. */
22502 for (i = 0; i < 3; ++i)
22503 default_invis_vector[i] = make_number ('.');
22504 }
22505
22506 {
22507 /* Allocate the buffer for frame titles.
22508 Also used for `format-mode-line'. */
22509 int size = 100;
22510 frame_title_buf = (char *) xmalloc (size);
22511 frame_title_buf_end = frame_title_buf + size;
22512 frame_title_ptr = NULL;
22513 }
22514
22515 help_echo_showing_p = 0;
22516 }
22517
22518
22519 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22520 (do not change this comment) */