]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(BYTE_CODE_QUIT): Add missing AFTER_POTENTIAL_GC.
[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 int minibuffer_auto_raise;
219 extern Lisp_Object Vminibuffer_list;
220
221 extern Lisp_Object Qface;
222 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
223
224 extern Lisp_Object Voverriding_local_map;
225 extern Lisp_Object Voverriding_local_map_menu_flag;
226 extern Lisp_Object Qmenu_item;
227 extern Lisp_Object Qwhen;
228 extern Lisp_Object Qhelp_echo;
229
230 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
231 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
232 Lisp_Object Qredisplay_end_trigger_functions;
233 Lisp_Object Qinhibit_point_motion_hooks;
234 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
235 Lisp_Object Qfontified;
236 Lisp_Object Qgrow_only;
237 Lisp_Object Qinhibit_eval_during_redisplay;
238 Lisp_Object Qbuffer_position, Qposition, Qobject;
239
240 /* Cursor shapes */
241 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
242
243 /* Pointer shapes */
244 Lisp_Object Qarrow, Qhand, Qtext;
245
246 Lisp_Object Qrisky_local_variable;
247
248 /* Holds the list (error). */
249 Lisp_Object list_of_error;
250
251 /* Functions called to fontify regions of text. */
252
253 Lisp_Object Vfontification_functions;
254 Lisp_Object Qfontification_functions;
255
256 /* Non-zero means automatically select any window when the mouse
257 cursor moves into it. */
258 int mouse_autoselect_window;
259
260 /* Non-zero means draw tool bar buttons raised when the mouse moves
261 over them. */
262
263 int auto_raise_tool_bar_buttons_p;
264
265 /* Margin around tool bar buttons in pixels. */
266
267 Lisp_Object Vtool_bar_button_margin;
268
269 /* Thickness of shadow to draw around tool bar buttons. */
270
271 EMACS_INT tool_bar_button_relief;
272
273 /* Non-zero means automatically resize tool-bars so that all tool-bar
274 items are visible, and no blank lines remain. */
275
276 int auto_resize_tool_bars_p;
277
278 /* Non-zero means draw block and hollow cursor as wide as the glyph
279 under it. For example, if a block cursor is over a tab, it will be
280 drawn as wide as that tab on the display. */
281
282 int x_stretch_cursor_p;
283
284 /* Non-nil means don't actually do any redisplay. */
285
286 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
287
288 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
289
290 int inhibit_eval_during_redisplay;
291
292 /* Names of text properties relevant for redisplay. */
293
294 Lisp_Object Qdisplay;
295 extern Lisp_Object Qface, Qinvisible, Qwidth;
296
297 /* Symbols used in text property values. */
298
299 Lisp_Object Vdisplay_pixels_per_inch;
300 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
301 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
302 Lisp_Object Qslice;
303 Lisp_Object Qcenter;
304 Lisp_Object Qmargin, Qpointer;
305 Lisp_Object Qline_height, Qtotal;
306 extern Lisp_Object Qheight;
307 extern Lisp_Object QCwidth, QCheight, QCascent;
308 extern Lisp_Object Qscroll_bar;
309 extern Lisp_Object Qcursor;
310
311 /* Non-nil means highlight trailing whitespace. */
312
313 Lisp_Object Vshow_trailing_whitespace;
314
315 #ifdef HAVE_WINDOW_SYSTEM
316 extern Lisp_Object Voverflow_newline_into_fringe;
317
318 /* Test if overflow newline into fringe. Called with iterator IT
319 at or past right window margin, and with IT->current_x set. */
320
321 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
322 (!NILP (Voverflow_newline_into_fringe) \
323 && FRAME_WINDOW_P (it->f) \
324 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
325 && it->current_x == it->last_visible_x)
326
327 #endif /* HAVE_WINDOW_SYSTEM */
328
329 /* Non-nil means show the text cursor in void text areas
330 i.e. in blank areas after eol and eob. This used to be
331 the default in 21.3. */
332
333 Lisp_Object Vvoid_text_area_pointer;
334
335 /* Name of the face used to highlight trailing whitespace. */
336
337 Lisp_Object Qtrailing_whitespace;
338
339 /* The symbol `image' which is the car of the lists used to represent
340 images in Lisp. */
341
342 Lisp_Object Qimage;
343
344 /* The image map types. */
345 Lisp_Object QCmap, QCpointer;
346 Lisp_Object Qrect, Qcircle, Qpoly;
347
348 /* Non-zero means print newline to stdout before next mini-buffer
349 message. */
350
351 int noninteractive_need_newline;
352
353 /* Non-zero means print newline to message log before next message. */
354
355 static int message_log_need_newline;
356
357 /* Three markers that message_dolog uses.
358 It could allocate them itself, but that causes trouble
359 in handling memory-full errors. */
360 static Lisp_Object message_dolog_marker1;
361 static Lisp_Object message_dolog_marker2;
362 static Lisp_Object message_dolog_marker3;
363 \f
364 /* The buffer position of the first character appearing entirely or
365 partially on the line of the selected window which contains the
366 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
367 redisplay optimization in redisplay_internal. */
368
369 static struct text_pos this_line_start_pos;
370
371 /* Number of characters past the end of the line above, including the
372 terminating newline. */
373
374 static struct text_pos this_line_end_pos;
375
376 /* The vertical positions and the height of this line. */
377
378 static int this_line_vpos;
379 static int this_line_y;
380 static int this_line_pixel_height;
381
382 /* X position at which this display line starts. Usually zero;
383 negative if first character is partially visible. */
384
385 static int this_line_start_x;
386
387 /* Buffer that this_line_.* variables are referring to. */
388
389 static struct buffer *this_line_buffer;
390
391 /* Nonzero means truncate lines in all windows less wide than the
392 frame. */
393
394 int truncate_partial_width_windows;
395
396 /* A flag to control how to display unibyte 8-bit character. */
397
398 int unibyte_display_via_language_environment;
399
400 /* Nonzero means we have more than one non-mini-buffer-only frame.
401 Not guaranteed to be accurate except while parsing
402 frame-title-format. */
403
404 int multiple_frames;
405
406 Lisp_Object Vglobal_mode_string;
407
408
409 /* List of variables (symbols) which hold markers for overlay arrows.
410 The symbols on this list are examined during redisplay to determine
411 where to display overlay arrows. */
412
413 Lisp_Object Voverlay_arrow_variable_list;
414
415 /* Marker for where to display an arrow on top of the buffer text. */
416
417 Lisp_Object Voverlay_arrow_position;
418
419 /* String to display for the arrow. Only used on terminal frames. */
420
421 Lisp_Object Voverlay_arrow_string;
422
423 /* Values of those variables at last redisplay are stored as
424 properties on `overlay-arrow-position' symbol. However, if
425 Voverlay_arrow_position is a marker, last-arrow-position is its
426 numerical position. */
427
428 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
429
430 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
431 properties on a symbol in overlay-arrow-variable-list. */
432
433 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
434
435 /* Like mode-line-format, but for the title bar on a visible frame. */
436
437 Lisp_Object Vframe_title_format;
438
439 /* Like mode-line-format, but for the title bar on an iconified frame. */
440
441 Lisp_Object Vicon_title_format;
442
443 /* List of functions to call when a window's size changes. These
444 functions get one arg, a frame on which one or more windows' sizes
445 have changed. */
446
447 static Lisp_Object Vwindow_size_change_functions;
448
449 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
450
451 /* Nonzero if overlay arrow has been displayed once in this window. */
452
453 static int overlay_arrow_seen;
454
455 /* Nonzero means highlight the region even in nonselected windows. */
456
457 int highlight_nonselected_windows;
458
459 /* If cursor motion alone moves point off frame, try scrolling this
460 many lines up or down if that will bring it back. */
461
462 static EMACS_INT scroll_step;
463
464 /* Nonzero means scroll just far enough to bring point back on the
465 screen, when appropriate. */
466
467 static EMACS_INT scroll_conservatively;
468
469 /* Recenter the window whenever point gets within this many lines of
470 the top or bottom of the window. This value is translated into a
471 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
472 that there is really a fixed pixel height scroll margin. */
473
474 EMACS_INT scroll_margin;
475
476 /* Number of windows showing the buffer of the selected window (or
477 another buffer with the same base buffer). keyboard.c refers to
478 this. */
479
480 int buffer_shared;
481
482 /* Vector containing glyphs for an ellipsis `...'. */
483
484 static Lisp_Object default_invis_vector[3];
485
486 /* Zero means display the mode-line/header-line/menu-bar in the default face
487 (this slightly odd definition is for compatibility with previous versions
488 of emacs), non-zero means display them using their respective faces.
489
490 This variable is deprecated. */
491
492 int mode_line_inverse_video;
493
494 /* Prompt to display in front of the mini-buffer contents. */
495
496 Lisp_Object minibuf_prompt;
497
498 /* Width of current mini-buffer prompt. Only set after display_line
499 of the line that contains the prompt. */
500
501 int minibuf_prompt_width;
502
503 /* This is the window where the echo area message was displayed. It
504 is always a mini-buffer window, but it may not be the same window
505 currently active as a mini-buffer. */
506
507 Lisp_Object echo_area_window;
508
509 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
510 pushes the current message and the value of
511 message_enable_multibyte on the stack, the function restore_message
512 pops the stack and displays MESSAGE again. */
513
514 Lisp_Object Vmessage_stack;
515
516 /* Nonzero means multibyte characters were enabled when the echo area
517 message was specified. */
518
519 int message_enable_multibyte;
520
521 /* Nonzero if we should redraw the mode lines on the next redisplay. */
522
523 int update_mode_lines;
524
525 /* Nonzero if window sizes or contents have changed since last
526 redisplay that finished. */
527
528 int windows_or_buffers_changed;
529
530 /* Nonzero means a frame's cursor type has been changed. */
531
532 int cursor_type_changed;
533
534 /* Nonzero after display_mode_line if %l was used and it displayed a
535 line number. */
536
537 int line_number_displayed;
538
539 /* Maximum buffer size for which to display line numbers. */
540
541 Lisp_Object Vline_number_display_limit;
542
543 /* Line width to consider when repositioning for line number display. */
544
545 static EMACS_INT line_number_display_limit_width;
546
547 /* Number of lines to keep in the message log buffer. t means
548 infinite. nil means don't log at all. */
549
550 Lisp_Object Vmessage_log_max;
551
552 /* The name of the *Messages* buffer, a string. */
553
554 static Lisp_Object Vmessages_buffer_name;
555
556 /* Current, index 0, and last displayed echo area message. Either
557 buffers from echo_buffers, or nil to indicate no message. */
558
559 Lisp_Object echo_area_buffer[2];
560
561 /* The buffers referenced from echo_area_buffer. */
562
563 static Lisp_Object echo_buffer[2];
564
565 /* A vector saved used in with_area_buffer to reduce consing. */
566
567 static Lisp_Object Vwith_echo_area_save_vector;
568
569 /* Non-zero means display_echo_area should display the last echo area
570 message again. Set by redisplay_preserve_echo_area. */
571
572 static int display_last_displayed_message_p;
573
574 /* Nonzero if echo area is being used by print; zero if being used by
575 message. */
576
577 int message_buf_print;
578
579 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
580
581 Lisp_Object Qinhibit_menubar_update;
582 int inhibit_menubar_update;
583
584 /* Maximum height for resizing mini-windows. Either a float
585 specifying a fraction of the available height, or an integer
586 specifying a number of lines. */
587
588 Lisp_Object Vmax_mini_window_height;
589
590 /* Non-zero means messages should be displayed with truncated
591 lines instead of being continued. */
592
593 int message_truncate_lines;
594 Lisp_Object Qmessage_truncate_lines;
595
596 /* Set to 1 in clear_message to make redisplay_internal aware
597 of an emptied echo area. */
598
599 static int message_cleared_p;
600
601 /* Non-zero means we want a hollow cursor in windows that are not
602 selected. Zero means there's no cursor in such windows. */
603
604 Lisp_Object Vcursor_in_non_selected_windows;
605 Lisp_Object Qcursor_in_non_selected_windows;
606
607 /* How to blink the default frame cursor off. */
608 Lisp_Object Vblink_cursor_alist;
609
610 /* A scratch glyph row with contents used for generating truncation
611 glyphs. Also used in direct_output_for_insert. */
612
613 #define MAX_SCRATCH_GLYPHS 100
614 struct glyph_row scratch_glyph_row;
615 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
616
617 /* Ascent and height of the last line processed by move_it_to. */
618
619 static int last_max_ascent, last_height;
620
621 /* Non-zero if there's a help-echo in the echo area. */
622
623 int help_echo_showing_p;
624
625 /* If >= 0, computed, exact values of mode-line and header-line height
626 to use in the macros CURRENT_MODE_LINE_HEIGHT and
627 CURRENT_HEADER_LINE_HEIGHT. */
628
629 int current_mode_line_height, current_header_line_height;
630
631 /* The maximum distance to look ahead for text properties. Values
632 that are too small let us call compute_char_face and similar
633 functions too often which is expensive. Values that are too large
634 let us call compute_char_face and alike too often because we
635 might not be interested in text properties that far away. */
636
637 #define TEXT_PROP_DISTANCE_LIMIT 100
638
639 #if GLYPH_DEBUG
640
641 /* Variables to turn off display optimizations from Lisp. */
642
643 int inhibit_try_window_id, inhibit_try_window_reusing;
644 int inhibit_try_cursor_movement;
645
646 /* Non-zero means print traces of redisplay if compiled with
647 GLYPH_DEBUG != 0. */
648
649 int trace_redisplay_p;
650
651 #endif /* GLYPH_DEBUG */
652
653 #ifdef DEBUG_TRACE_MOVE
654 /* Non-zero means trace with TRACE_MOVE to stderr. */
655 int trace_move;
656
657 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
658 #else
659 #define TRACE_MOVE(x) (void) 0
660 #endif
661
662 /* Non-zero means automatically scroll windows horizontally to make
663 point visible. */
664
665 int automatic_hscrolling_p;
666
667 /* How close to the margin can point get before the window is scrolled
668 horizontally. */
669 EMACS_INT hscroll_margin;
670
671 /* How much to scroll horizontally when point is inside the above margin. */
672 Lisp_Object Vhscroll_step;
673
674 /* The variable `resize-mini-windows'. If nil, don't resize
675 mini-windows. If t, always resize them to fit the text they
676 display. If `grow-only', let mini-windows grow only until they
677 become empty. */
678
679 Lisp_Object Vresize_mini_windows;
680
681 /* Buffer being redisplayed -- for redisplay_window_error. */
682
683 struct buffer *displayed_buffer;
684
685 /* Value returned from text property handlers (see below). */
686
687 enum prop_handled
688 {
689 HANDLED_NORMALLY,
690 HANDLED_RECOMPUTE_PROPS,
691 HANDLED_OVERLAY_STRING_CONSUMED,
692 HANDLED_RETURN
693 };
694
695 /* A description of text properties that redisplay is interested
696 in. */
697
698 struct props
699 {
700 /* The name of the property. */
701 Lisp_Object *name;
702
703 /* A unique index for the property. */
704 enum prop_idx idx;
705
706 /* A handler function called to set up iterator IT from the property
707 at IT's current position. Value is used to steer handle_stop. */
708 enum prop_handled (*handler) P_ ((struct it *it));
709 };
710
711 static enum prop_handled handle_face_prop P_ ((struct it *));
712 static enum prop_handled handle_invisible_prop P_ ((struct it *));
713 static enum prop_handled handle_display_prop P_ ((struct it *));
714 static enum prop_handled handle_composition_prop P_ ((struct it *));
715 static enum prop_handled handle_overlay_change P_ ((struct it *));
716 static enum prop_handled handle_fontified_prop P_ ((struct it *));
717
718 /* Properties handled by iterators. */
719
720 static struct props it_props[] =
721 {
722 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
723 /* Handle `face' before `display' because some sub-properties of
724 `display' need to know the face. */
725 {&Qface, FACE_PROP_IDX, handle_face_prop},
726 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
727 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
728 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
729 {NULL, 0, NULL}
730 };
731
732 /* Value is the position described by X. If X is a marker, value is
733 the marker_position of X. Otherwise, value is X. */
734
735 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
736
737 /* Enumeration returned by some move_it_.* functions internally. */
738
739 enum move_it_result
740 {
741 /* Not used. Undefined value. */
742 MOVE_UNDEFINED,
743
744 /* Move ended at the requested buffer position or ZV. */
745 MOVE_POS_MATCH_OR_ZV,
746
747 /* Move ended at the requested X pixel position. */
748 MOVE_X_REACHED,
749
750 /* Move within a line ended at the end of a line that must be
751 continued. */
752 MOVE_LINE_CONTINUED,
753
754 /* Move within a line ended at the end of a line that would
755 be displayed truncated. */
756 MOVE_LINE_TRUNCATED,
757
758 /* Move within a line ended at a line end. */
759 MOVE_NEWLINE_OR_CR
760 };
761
762 /* This counter is used to clear the face cache every once in a while
763 in redisplay_internal. It is incremented for each redisplay.
764 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
765 cleared. */
766
767 #define CLEAR_FACE_CACHE_COUNT 500
768 static int clear_face_cache_count;
769
770 /* Record the previous terminal frame we displayed. */
771
772 static struct frame *previous_terminal_frame;
773
774 /* Non-zero while redisplay_internal is in progress. */
775
776 int redisplaying_p;
777
778 /* Non-zero means don't free realized faces. Bound while freeing
779 realized faces is dangerous because glyph matrices might still
780 reference them. */
781
782 int inhibit_free_realized_faces;
783 Lisp_Object Qinhibit_free_realized_faces;
784
785 /* If a string, XTread_socket generates an event to display that string.
786 (The display is done in read_char.) */
787
788 Lisp_Object help_echo_string;
789 Lisp_Object help_echo_window;
790 Lisp_Object help_echo_object;
791 int help_echo_pos;
792
793 /* Temporary variable for XTread_socket. */
794
795 Lisp_Object previous_help_echo_string;
796
797 /* Null glyph slice */
798
799 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
800
801 \f
802 /* Function prototypes. */
803
804 static void setup_for_ellipsis P_ ((struct it *));
805 static void mark_window_display_accurate_1 P_ ((struct window *, int));
806 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
807 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
808 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
809 static int redisplay_mode_lines P_ ((Lisp_Object, int));
810 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
811
812 #if 0
813 static int invisible_text_between_p P_ ((struct it *, int, int));
814 #endif
815
816 static int next_element_from_ellipsis P_ ((struct it *));
817 static void pint2str P_ ((char *, int, int));
818 static void pint2hrstr P_ ((char *, int, int));
819 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
820 struct text_pos));
821 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
822 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
823 static void store_frame_title_char P_ ((char));
824 static int store_frame_title P_ ((const unsigned char *, int, int));
825 static void x_consider_frame_title P_ ((Lisp_Object));
826 static void handle_stop P_ ((struct it *));
827 static int tool_bar_lines_needed P_ ((struct frame *));
828 static int single_display_prop_intangible_p P_ ((Lisp_Object));
829 static void ensure_echo_area_buffers P_ ((void));
830 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
831 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
832 static int with_echo_area_buffer P_ ((struct window *, int,
833 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
834 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
835 static void clear_garbaged_frames P_ ((void));
836 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
838 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
839 static int display_echo_area P_ ((struct window *));
840 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
841 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
842 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
843 static int string_char_and_length P_ ((const unsigned char *, int, int *));
844 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
845 struct text_pos));
846 static int compute_window_start_on_continuation_line P_ ((struct window *));
847 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
848 static void insert_left_trunc_glyphs P_ ((struct it *));
849 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
850 Lisp_Object));
851 static void extend_face_to_end_of_line P_ ((struct it *));
852 static int append_space_for_newline P_ ((struct it *, int));
853 static int make_cursor_line_fully_visible P_ ((struct window *, int));
854 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
855 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
856 static int trailing_whitespace_p P_ ((int));
857 static int message_log_check_duplicate P_ ((int, int, int, int));
858 static void push_it P_ ((struct it *));
859 static void pop_it P_ ((struct it *));
860 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
861 static void select_frame_for_redisplay P_ ((Lisp_Object));
862 static void redisplay_internal P_ ((int));
863 static int echo_area_display P_ ((int));
864 static void redisplay_windows P_ ((Lisp_Object));
865 static void redisplay_window P_ ((Lisp_Object, int));
866 static Lisp_Object redisplay_window_error ();
867 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
868 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
869 static void update_menu_bar P_ ((struct frame *, int));
870 static int try_window_reusing_current_matrix P_ ((struct window *));
871 static int try_window_id P_ ((struct window *));
872 static int display_line P_ ((struct it *));
873 static int display_mode_lines P_ ((struct window *));
874 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
875 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
876 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
877 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
878 static void display_menu_bar P_ ((struct window *));
879 static int display_count_lines P_ ((int, int, int, int, int *));
880 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
881 int, int, struct it *, int, int, int, int));
882 static void compute_line_metrics P_ ((struct it *));
883 static void run_redisplay_end_trigger_hook P_ ((struct it *));
884 static int get_overlay_strings P_ ((struct it *, int));
885 static void next_overlay_string P_ ((struct it *));
886 static void reseat P_ ((struct it *, struct text_pos, int));
887 static void reseat_1 P_ ((struct it *, struct text_pos, int));
888 static void back_to_previous_visible_line_start P_ ((struct it *));
889 static void reseat_at_previous_visible_line_start P_ ((struct it *));
890 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
891 static int next_element_from_display_vector P_ ((struct it *));
892 static int next_element_from_string P_ ((struct it *));
893 static int next_element_from_c_string P_ ((struct it *));
894 static int next_element_from_buffer P_ ((struct it *));
895 static int next_element_from_composition P_ ((struct it *));
896 static int next_element_from_image P_ ((struct it *));
897 static int next_element_from_stretch P_ ((struct it *));
898 static void load_overlay_strings P_ ((struct it *, int));
899 static int init_from_display_pos P_ ((struct it *, struct window *,
900 struct display_pos *));
901 static void reseat_to_string P_ ((struct it *, unsigned char *,
902 Lisp_Object, int, int, int, int));
903 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
904 int, int, int));
905 void move_it_vertically_backward P_ ((struct it *, int));
906 static void init_to_row_start P_ ((struct it *, struct window *,
907 struct glyph_row *));
908 static int init_to_row_end P_ ((struct it *, struct window *,
909 struct glyph_row *));
910 static void back_to_previous_line_start P_ ((struct it *));
911 static int forward_to_next_line_start P_ ((struct it *, int *));
912 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
913 Lisp_Object, int));
914 static struct text_pos string_pos P_ ((int, Lisp_Object));
915 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
916 static int number_of_chars P_ ((unsigned char *, int));
917 static void compute_stop_pos P_ ((struct it *));
918 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
919 Lisp_Object));
920 static int face_before_or_after_it_pos P_ ((struct it *, int));
921 static int next_overlay_change P_ ((int));
922 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
923 Lisp_Object, struct text_pos *,
924 int));
925 static int underlying_face_id P_ ((struct it *));
926 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
927 struct window *));
928
929 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
930 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
931
932 #ifdef HAVE_WINDOW_SYSTEM
933
934 static void update_tool_bar P_ ((struct frame *, int));
935 static void build_desired_tool_bar_string P_ ((struct frame *f));
936 static int redisplay_tool_bar P_ ((struct frame *));
937 static void display_tool_bar_line P_ ((struct it *));
938 static void notice_overwritten_cursor P_ ((struct window *,
939 enum glyph_row_area,
940 int, int, int, int));
941
942
943
944 #endif /* HAVE_WINDOW_SYSTEM */
945
946 \f
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
950
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
954
955 This is the height of W minus the height of a mode line, if any. */
956
957 INLINE int
958 window_text_bottom_y (w)
959 struct window *w;
960 {
961 int height = WINDOW_TOTAL_HEIGHT (w);
962
963 if (WINDOW_WANTS_MODELINE_P (w))
964 height -= CURRENT_MODE_LINE_HEIGHT (w);
965 return height;
966 }
967
968 /* Return the pixel width of display area AREA of window W. AREA < 0
969 means return the total width of W, not including fringes to
970 the left and right of the window. */
971
972 INLINE int
973 window_box_width (w, area)
974 struct window *w;
975 int area;
976 {
977 int cols = XFASTINT (w->total_cols);
978 int pixels = 0;
979
980 if (!w->pseudo_window_p)
981 {
982 cols -= WINDOW_SCROLL_BAR_COLS (w);
983
984 if (area == TEXT_AREA)
985 {
986 if (INTEGERP (w->left_margin_cols))
987 cols -= XFASTINT (w->left_margin_cols);
988 if (INTEGERP (w->right_margin_cols))
989 cols -= XFASTINT (w->right_margin_cols);
990 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
991 }
992 else if (area == LEFT_MARGIN_AREA)
993 {
994 cols = (INTEGERP (w->left_margin_cols)
995 ? XFASTINT (w->left_margin_cols) : 0);
996 pixels = 0;
997 }
998 else if (area == RIGHT_MARGIN_AREA)
999 {
1000 cols = (INTEGERP (w->right_margin_cols)
1001 ? XFASTINT (w->right_margin_cols) : 0);
1002 pixels = 0;
1003 }
1004 }
1005
1006 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1007 }
1008
1009
1010 /* Return the pixel height of the display area of window W, not
1011 including mode lines of W, if any. */
1012
1013 INLINE int
1014 window_box_height (w)
1015 struct window *w;
1016 {
1017 struct frame *f = XFRAME (w->frame);
1018 int height = WINDOW_TOTAL_HEIGHT (w);
1019
1020 xassert (height >= 0);
1021
1022 /* Note: the code below that determines the mode-line/header-line
1023 height is essentially the same as that contained in the macro
1024 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1025 the appropriate glyph row has its `mode_line_p' flag set,
1026 and if it doesn't, uses estimate_mode_line_height instead. */
1027
1028 if (WINDOW_WANTS_MODELINE_P (w))
1029 {
1030 struct glyph_row *ml_row
1031 = (w->current_matrix && w->current_matrix->rows
1032 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1033 : 0);
1034 if (ml_row && ml_row->mode_line_p)
1035 height -= ml_row->height;
1036 else
1037 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1038 }
1039
1040 if (WINDOW_WANTS_HEADER_LINE_P (w))
1041 {
1042 struct glyph_row *hl_row
1043 = (w->current_matrix && w->current_matrix->rows
1044 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1045 : 0);
1046 if (hl_row && hl_row->mode_line_p)
1047 height -= hl_row->height;
1048 else
1049 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1050 }
1051
1052 /* With a very small font and a mode-line that's taller than
1053 default, we might end up with a negative height. */
1054 return max (0, height);
1055 }
1056
1057 /* Return the window-relative coordinate of the left edge of display
1058 area AREA of window W. AREA < 0 means return the left edge of the
1059 whole window, to the right of the left fringe of W. */
1060
1061 INLINE int
1062 window_box_left_offset (w, area)
1063 struct window *w;
1064 int area;
1065 {
1066 int x;
1067
1068 if (w->pseudo_window_p)
1069 return 0;
1070
1071 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1072
1073 if (area == TEXT_AREA)
1074 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1075 + window_box_width (w, LEFT_MARGIN_AREA));
1076 else if (area == RIGHT_MARGIN_AREA)
1077 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1078 + window_box_width (w, LEFT_MARGIN_AREA)
1079 + window_box_width (w, TEXT_AREA)
1080 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1081 ? 0
1082 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1083 else if (area == LEFT_MARGIN_AREA
1084 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1085 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1086
1087 return x;
1088 }
1089
1090
1091 /* Return the window-relative coordinate of the right edge of display
1092 area AREA of window W. AREA < 0 means return the left edge of the
1093 whole window, to the left of the right fringe of W. */
1094
1095 INLINE int
1096 window_box_right_offset (w, area)
1097 struct window *w;
1098 int area;
1099 {
1100 return window_box_left_offset (w, area) + window_box_width (w, area);
1101 }
1102
1103 /* Return the frame-relative coordinate of the left edge of display
1104 area AREA of window W. AREA < 0 means return the left edge of the
1105 whole window, to the right of the left fringe of W. */
1106
1107 INLINE int
1108 window_box_left (w, area)
1109 struct window *w;
1110 int area;
1111 {
1112 struct frame *f = XFRAME (w->frame);
1113 int x;
1114
1115 if (w->pseudo_window_p)
1116 return FRAME_INTERNAL_BORDER_WIDTH (f);
1117
1118 x = (WINDOW_LEFT_EDGE_X (w)
1119 + window_box_left_offset (w, area));
1120
1121 return x;
1122 }
1123
1124
1125 /* Return the frame-relative coordinate of the right edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the left of the right fringe of W. */
1128
1129 INLINE int
1130 window_box_right (w, area)
1131 struct window *w;
1132 int area;
1133 {
1134 return window_box_left (w, area) + window_box_width (w, area);
1135 }
1136
1137 /* Get the bounding box of the display area AREA of window W, without
1138 mode lines, in frame-relative coordinates. AREA < 0 means the
1139 whole window, not including the left and right fringes of
1140 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1141 coordinates of the upper-left corner of the box. Return in
1142 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1143
1144 INLINE void
1145 window_box (w, area, box_x, box_y, box_width, box_height)
1146 struct window *w;
1147 int area;
1148 int *box_x, *box_y, *box_width, *box_height;
1149 {
1150 if (box_width)
1151 *box_width = window_box_width (w, area);
1152 if (box_height)
1153 *box_height = window_box_height (w);
1154 if (box_x)
1155 *box_x = window_box_left (w, area);
1156 if (box_y)
1157 {
1158 *box_y = WINDOW_TOP_EDGE_Y (w);
1159 if (WINDOW_WANTS_HEADER_LINE_P (w))
1160 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1161 }
1162 }
1163
1164
1165 /* Get the bounding box of the display area AREA of window W, without
1166 mode lines. AREA < 0 means the whole window, not including the
1167 left and right fringe of the window. Return in *TOP_LEFT_X
1168 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1169 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1170 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1171 box. */
1172
1173 INLINE void
1174 window_box_edges (w, area, top_left_x, top_left_y,
1175 bottom_right_x, bottom_right_y)
1176 struct window *w;
1177 int area;
1178 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1179 {
1180 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1181 bottom_right_y);
1182 *bottom_right_x += *top_left_x;
1183 *bottom_right_y += *top_left_y;
1184 }
1185
1186
1187 \f
1188 /***********************************************************************
1189 Utilities
1190 ***********************************************************************/
1191
1192 /* Return the bottom y-position of the line the iterator IT is in.
1193 This can modify IT's settings. */
1194
1195 int
1196 line_bottom_y (it)
1197 struct it *it;
1198 {
1199 int line_height = it->max_ascent + it->max_descent;
1200 int line_top_y = it->current_y;
1201
1202 if (line_height == 0)
1203 {
1204 if (last_height)
1205 line_height = last_height;
1206 else if (IT_CHARPOS (*it) < ZV)
1207 {
1208 move_it_by_lines (it, 1, 1);
1209 line_height = (it->max_ascent || it->max_descent
1210 ? it->max_ascent + it->max_descent
1211 : last_height);
1212 }
1213 else
1214 {
1215 struct glyph_row *row = it->glyph_row;
1216
1217 /* Use the default character height. */
1218 it->glyph_row = NULL;
1219 it->what = IT_CHARACTER;
1220 it->c = ' ';
1221 it->len = 1;
1222 PRODUCE_GLYPHS (it);
1223 line_height = it->ascent + it->descent;
1224 it->glyph_row = row;
1225 }
1226 }
1227
1228 return line_top_y + line_height;
1229 }
1230
1231
1232 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1233 1 if POS is visible and the line containing POS is fully visible.
1234 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1235 and header-lines heights. */
1236
1237 int
1238 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1239 struct window *w;
1240 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1241 {
1242 struct it it;
1243 struct text_pos top;
1244 int visible_p;
1245 struct buffer *old_buffer = NULL;
1246
1247 if (XBUFFER (w->buffer) != current_buffer)
1248 {
1249 old_buffer = current_buffer;
1250 set_buffer_internal_1 (XBUFFER (w->buffer));
1251 }
1252
1253 *fully = visible_p = 0;
1254 SET_TEXT_POS_FROM_MARKER (top, w->start);
1255
1256 /* Compute exact mode line heights, if requested. */
1257 if (exact_mode_line_heights_p)
1258 {
1259 if (WINDOW_WANTS_MODELINE_P (w))
1260 current_mode_line_height
1261 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1262 current_buffer->mode_line_format);
1263
1264 if (WINDOW_WANTS_HEADER_LINE_P (w))
1265 current_header_line_height
1266 = display_mode_line (w, HEADER_LINE_FACE_ID,
1267 current_buffer->header_line_format);
1268 }
1269
1270 start_display (&it, w, top);
1271 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1272 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1273
1274 /* Note that we may overshoot because of invisible text. */
1275 if (IT_CHARPOS (it) >= charpos)
1276 {
1277 int top_y = it.current_y;
1278 int bottom_y = line_bottom_y (&it);
1279 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1280
1281 if (top_y < window_top_y)
1282 visible_p = bottom_y > window_top_y;
1283 else if (top_y < it.last_visible_y)
1284 {
1285 visible_p = 1;
1286 *fully = bottom_y <= it.last_visible_y;
1287 }
1288 if (visible_p && x)
1289 {
1290 *x = it.current_x;
1291 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1292 }
1293 }
1294 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1295 {
1296 struct it it2;
1297
1298 it2 = it;
1299 move_it_by_lines (&it, 1, 0);
1300 if (charpos < IT_CHARPOS (it))
1301 {
1302 visible_p = 1;
1303 if (x)
1304 {
1305 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1306 *x = it2.current_x;
1307 *y = it2.current_y + it2.max_ascent - it2.ascent;
1308 }
1309 }
1310 }
1311
1312 if (old_buffer)
1313 set_buffer_internal_1 (old_buffer);
1314
1315 current_header_line_height = current_mode_line_height = -1;
1316
1317 return visible_p;
1318 }
1319
1320
1321 /* Return the next character from STR which is MAXLEN bytes long.
1322 Return in *LEN the length of the character. This is like
1323 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1324 we find one, we return a `?', but with the length of the invalid
1325 character. */
1326
1327 static INLINE int
1328 string_char_and_length (str, maxlen, len)
1329 const unsigned char *str;
1330 int maxlen, *len;
1331 {
1332 int c;
1333
1334 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1335 if (!CHAR_VALID_P (c, 1))
1336 /* We may not change the length here because other places in Emacs
1337 don't use this function, i.e. they silently accept invalid
1338 characters. */
1339 c = '?';
1340
1341 return c;
1342 }
1343
1344
1345
1346 /* Given a position POS containing a valid character and byte position
1347 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1348
1349 static struct text_pos
1350 string_pos_nchars_ahead (pos, string, nchars)
1351 struct text_pos pos;
1352 Lisp_Object string;
1353 int nchars;
1354 {
1355 xassert (STRINGP (string) && nchars >= 0);
1356
1357 if (STRING_MULTIBYTE (string))
1358 {
1359 int rest = SBYTES (string) - BYTEPOS (pos);
1360 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1361 int len;
1362
1363 while (nchars--)
1364 {
1365 string_char_and_length (p, rest, &len);
1366 p += len, rest -= len;
1367 xassert (rest >= 0);
1368 CHARPOS (pos) += 1;
1369 BYTEPOS (pos) += len;
1370 }
1371 }
1372 else
1373 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1374
1375 return pos;
1376 }
1377
1378
1379 /* Value is the text position, i.e. character and byte position,
1380 for character position CHARPOS in STRING. */
1381
1382 static INLINE struct text_pos
1383 string_pos (charpos, string)
1384 int charpos;
1385 Lisp_Object string;
1386 {
1387 struct text_pos pos;
1388 xassert (STRINGP (string));
1389 xassert (charpos >= 0);
1390 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1391 return pos;
1392 }
1393
1394
1395 /* Value is a text position, i.e. character and byte position, for
1396 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1397 means recognize multibyte characters. */
1398
1399 static struct text_pos
1400 c_string_pos (charpos, s, multibyte_p)
1401 int charpos;
1402 unsigned char *s;
1403 int multibyte_p;
1404 {
1405 struct text_pos pos;
1406
1407 xassert (s != NULL);
1408 xassert (charpos >= 0);
1409
1410 if (multibyte_p)
1411 {
1412 int rest = strlen (s), len;
1413
1414 SET_TEXT_POS (pos, 0, 0);
1415 while (charpos--)
1416 {
1417 string_char_and_length (s, rest, &len);
1418 s += len, rest -= len;
1419 xassert (rest >= 0);
1420 CHARPOS (pos) += 1;
1421 BYTEPOS (pos) += len;
1422 }
1423 }
1424 else
1425 SET_TEXT_POS (pos, charpos, charpos);
1426
1427 return pos;
1428 }
1429
1430
1431 /* Value is the number of characters in C string S. MULTIBYTE_P
1432 non-zero means recognize multibyte characters. */
1433
1434 static int
1435 number_of_chars (s, multibyte_p)
1436 unsigned char *s;
1437 int multibyte_p;
1438 {
1439 int nchars;
1440
1441 if (multibyte_p)
1442 {
1443 int rest = strlen (s), len;
1444 unsigned char *p = (unsigned char *) s;
1445
1446 for (nchars = 0; rest > 0; ++nchars)
1447 {
1448 string_char_and_length (p, rest, &len);
1449 rest -= len, p += len;
1450 }
1451 }
1452 else
1453 nchars = strlen (s);
1454
1455 return nchars;
1456 }
1457
1458
1459 /* Compute byte position NEWPOS->bytepos corresponding to
1460 NEWPOS->charpos. POS is a known position in string STRING.
1461 NEWPOS->charpos must be >= POS.charpos. */
1462
1463 static void
1464 compute_string_pos (newpos, pos, string)
1465 struct text_pos *newpos, pos;
1466 Lisp_Object string;
1467 {
1468 xassert (STRINGP (string));
1469 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1470
1471 if (STRING_MULTIBYTE (string))
1472 *newpos = string_pos_nchars_ahead (pos, string,
1473 CHARPOS (*newpos) - CHARPOS (pos));
1474 else
1475 BYTEPOS (*newpos) = CHARPOS (*newpos);
1476 }
1477
1478 /* EXPORT:
1479 Return an estimation of the pixel height of mode or top lines on
1480 frame F. FACE_ID specifies what line's height to estimate. */
1481
1482 int
1483 estimate_mode_line_height (f, face_id)
1484 struct frame *f;
1485 enum face_id face_id;
1486 {
1487 #ifdef HAVE_WINDOW_SYSTEM
1488 if (FRAME_WINDOW_P (f))
1489 {
1490 int height = FONT_HEIGHT (FRAME_FONT (f));
1491
1492 /* This function is called so early when Emacs starts that the face
1493 cache and mode line face are not yet initialized. */
1494 if (FRAME_FACE_CACHE (f))
1495 {
1496 struct face *face = FACE_FROM_ID (f, face_id);
1497 if (face)
1498 {
1499 if (face->font)
1500 height = FONT_HEIGHT (face->font);
1501 if (face->box_line_width > 0)
1502 height += 2 * face->box_line_width;
1503 }
1504 }
1505
1506 return height;
1507 }
1508 #endif
1509
1510 return 1;
1511 }
1512
1513 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1514 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1515 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1516 not force the value into range. */
1517
1518 void
1519 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1520 FRAME_PTR f;
1521 register int pix_x, pix_y;
1522 int *x, *y;
1523 NativeRectangle *bounds;
1524 int noclip;
1525 {
1526
1527 #ifdef HAVE_WINDOW_SYSTEM
1528 if (FRAME_WINDOW_P (f))
1529 {
1530 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1531 even for negative values. */
1532 if (pix_x < 0)
1533 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1534 if (pix_y < 0)
1535 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1536
1537 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1538 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1539
1540 if (bounds)
1541 STORE_NATIVE_RECT (*bounds,
1542 FRAME_COL_TO_PIXEL_X (f, pix_x),
1543 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1544 FRAME_COLUMN_WIDTH (f) - 1,
1545 FRAME_LINE_HEIGHT (f) - 1);
1546
1547 if (!noclip)
1548 {
1549 if (pix_x < 0)
1550 pix_x = 0;
1551 else if (pix_x > FRAME_TOTAL_COLS (f))
1552 pix_x = FRAME_TOTAL_COLS (f);
1553
1554 if (pix_y < 0)
1555 pix_y = 0;
1556 else if (pix_y > FRAME_LINES (f))
1557 pix_y = FRAME_LINES (f);
1558 }
1559 }
1560 #endif
1561
1562 *x = pix_x;
1563 *y = pix_y;
1564 }
1565
1566
1567 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1568 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1569 can't tell the positions because W's display is not up to date,
1570 return 0. */
1571
1572 int
1573 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1574 struct window *w;
1575 int hpos, vpos;
1576 int *frame_x, *frame_y;
1577 {
1578 #ifdef HAVE_WINDOW_SYSTEM
1579 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1580 {
1581 int success_p;
1582
1583 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1584 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1585
1586 if (display_completed)
1587 {
1588 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1589 struct glyph *glyph = row->glyphs[TEXT_AREA];
1590 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1591
1592 hpos = row->x;
1593 vpos = row->y;
1594 while (glyph < end)
1595 {
1596 hpos += glyph->pixel_width;
1597 ++glyph;
1598 }
1599
1600 /* If first glyph is partially visible, its first visible position is still 0. */
1601 if (hpos < 0)
1602 hpos = 0;
1603
1604 success_p = 1;
1605 }
1606 else
1607 {
1608 hpos = vpos = 0;
1609 success_p = 0;
1610 }
1611
1612 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1613 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1614 return success_p;
1615 }
1616 #endif
1617
1618 *frame_x = hpos;
1619 *frame_y = vpos;
1620 return 1;
1621 }
1622
1623
1624 #ifdef HAVE_WINDOW_SYSTEM
1625
1626 /* Find the glyph under window-relative coordinates X/Y in window W.
1627 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1628 strings. Return in *HPOS and *VPOS the row and column number of
1629 the glyph found. Return in *AREA the glyph area containing X.
1630 Value is a pointer to the glyph found or null if X/Y is not on
1631 text, or we can't tell because W's current matrix is not up to
1632 date. */
1633
1634 static struct glyph *
1635 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1636 struct window *w;
1637 int x, y;
1638 int *hpos, *vpos, *dx, *dy, *area;
1639 {
1640 struct glyph *glyph, *end;
1641 struct glyph_row *row = NULL;
1642 int x0, i;
1643
1644 /* Find row containing Y. Give up if some row is not enabled. */
1645 for (i = 0; i < w->current_matrix->nrows; ++i)
1646 {
1647 row = MATRIX_ROW (w->current_matrix, i);
1648 if (!row->enabled_p)
1649 return NULL;
1650 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1651 break;
1652 }
1653
1654 *vpos = i;
1655 *hpos = 0;
1656
1657 /* Give up if Y is not in the window. */
1658 if (i == w->current_matrix->nrows)
1659 return NULL;
1660
1661 /* Get the glyph area containing X. */
1662 if (w->pseudo_window_p)
1663 {
1664 *area = TEXT_AREA;
1665 x0 = 0;
1666 }
1667 else
1668 {
1669 if (x < window_box_left_offset (w, TEXT_AREA))
1670 {
1671 *area = LEFT_MARGIN_AREA;
1672 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1673 }
1674 else if (x < window_box_right_offset (w, TEXT_AREA))
1675 {
1676 *area = TEXT_AREA;
1677 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1678 }
1679 else
1680 {
1681 *area = RIGHT_MARGIN_AREA;
1682 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1683 }
1684 }
1685
1686 /* Find glyph containing X. */
1687 glyph = row->glyphs[*area];
1688 end = glyph + row->used[*area];
1689 x -= x0;
1690 while (glyph < end && x >= glyph->pixel_width)
1691 {
1692 x -= glyph->pixel_width;
1693 ++glyph;
1694 }
1695
1696 if (glyph == end)
1697 return NULL;
1698
1699 if (dx)
1700 {
1701 *dx = x;
1702 *dy = y - (row->y + row->ascent - glyph->ascent);
1703 }
1704
1705 *hpos = glyph - row->glyphs[*area];
1706 return glyph;
1707 }
1708
1709
1710 /* EXPORT:
1711 Convert frame-relative x/y to coordinates relative to window W.
1712 Takes pseudo-windows into account. */
1713
1714 void
1715 frame_to_window_pixel_xy (w, x, y)
1716 struct window *w;
1717 int *x, *y;
1718 {
1719 if (w->pseudo_window_p)
1720 {
1721 /* A pseudo-window is always full-width, and starts at the
1722 left edge of the frame, plus a frame border. */
1723 struct frame *f = XFRAME (w->frame);
1724 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1725 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1726 }
1727 else
1728 {
1729 *x -= WINDOW_LEFT_EDGE_X (w);
1730 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1731 }
1732 }
1733
1734 /* EXPORT:
1735 Return in *R the clipping rectangle for glyph string S. */
1736
1737 void
1738 get_glyph_string_clip_rect (s, nr)
1739 struct glyph_string *s;
1740 NativeRectangle *nr;
1741 {
1742 XRectangle r;
1743
1744 if (s->row->full_width_p)
1745 {
1746 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1747 r.x = WINDOW_LEFT_EDGE_X (s->w);
1748 r.width = WINDOW_TOTAL_WIDTH (s->w);
1749
1750 /* Unless displaying a mode or menu bar line, which are always
1751 fully visible, clip to the visible part of the row. */
1752 if (s->w->pseudo_window_p)
1753 r.height = s->row->visible_height;
1754 else
1755 r.height = s->height;
1756 }
1757 else
1758 {
1759 /* This is a text line that may be partially visible. */
1760 r.x = window_box_left (s->w, s->area);
1761 r.width = window_box_width (s->w, s->area);
1762 r.height = s->row->visible_height;
1763 }
1764
1765 /* If S draws overlapping rows, it's sufficient to use the top and
1766 bottom of the window for clipping because this glyph string
1767 intentionally draws over other lines. */
1768 if (s->for_overlaps_p)
1769 {
1770 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1771 r.height = window_text_bottom_y (s->w) - r.y;
1772 }
1773 else
1774 {
1775 /* Don't use S->y for clipping because it doesn't take partially
1776 visible lines into account. For example, it can be negative for
1777 partially visible lines at the top of a window. */
1778 if (!s->row->full_width_p
1779 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1780 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1781 else
1782 r.y = max (0, s->row->y);
1783
1784 /* If drawing a tool-bar window, draw it over the internal border
1785 at the top of the window. */
1786 if (s->w == XWINDOW (s->f->tool_bar_window))
1787 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1788 }
1789
1790 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1791
1792 /* If drawing the cursor, don't let glyph draw outside its
1793 advertised boundaries. Cleartype does this under some circumstances. */
1794 if (s->hl == DRAW_CURSOR)
1795 {
1796 struct glyph *glyph = s->first_glyph;
1797 int height;
1798
1799 if (s->x > r.x)
1800 {
1801 r.width -= s->x - r.x;
1802 r.x = s->x;
1803 }
1804 r.width = min (r.width, glyph->pixel_width);
1805
1806 /* Don't draw cursor glyph taller than our actual glyph. */
1807 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1808 if (height < r.height)
1809 {
1810 int max_y = r.y + r.height;
1811 r.y = min (max_y, s->ybase + glyph->descent - height);
1812 r.height = min (max_y - r.y, height);
1813 }
1814 }
1815
1816 #ifdef CONVERT_FROM_XRECT
1817 CONVERT_FROM_XRECT (r, *nr);
1818 #else
1819 *nr = r;
1820 #endif
1821 }
1822
1823 #endif /* HAVE_WINDOW_SYSTEM */
1824
1825 \f
1826 /***********************************************************************
1827 Lisp form evaluation
1828 ***********************************************************************/
1829
1830 /* Error handler for safe_eval and safe_call. */
1831
1832 static Lisp_Object
1833 safe_eval_handler (arg)
1834 Lisp_Object arg;
1835 {
1836 add_to_log ("Error during redisplay: %s", arg, Qnil);
1837 return Qnil;
1838 }
1839
1840
1841 /* Evaluate SEXPR and return the result, or nil if something went
1842 wrong. Prevent redisplay during the evaluation. */
1843
1844 Lisp_Object
1845 safe_eval (sexpr)
1846 Lisp_Object sexpr;
1847 {
1848 Lisp_Object val;
1849
1850 if (inhibit_eval_during_redisplay)
1851 val = Qnil;
1852 else
1853 {
1854 int count = SPECPDL_INDEX ();
1855 struct gcpro gcpro1;
1856
1857 GCPRO1 (sexpr);
1858 specbind (Qinhibit_redisplay, Qt);
1859 /* Use Qt to ensure debugger does not run,
1860 so there is no possibility of wanting to redisplay. */
1861 val = internal_condition_case_1 (Feval, sexpr, Qt,
1862 safe_eval_handler);
1863 UNGCPRO;
1864 val = unbind_to (count, val);
1865 }
1866
1867 return val;
1868 }
1869
1870
1871 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1872 Return the result, or nil if something went wrong. Prevent
1873 redisplay during the evaluation. */
1874
1875 Lisp_Object
1876 safe_call (nargs, args)
1877 int nargs;
1878 Lisp_Object *args;
1879 {
1880 Lisp_Object val;
1881
1882 if (inhibit_eval_during_redisplay)
1883 val = Qnil;
1884 else
1885 {
1886 int count = SPECPDL_INDEX ();
1887 struct gcpro gcpro1;
1888
1889 GCPRO1 (args[0]);
1890 gcpro1.nvars = nargs;
1891 specbind (Qinhibit_redisplay, Qt);
1892 /* Use Qt to ensure debugger does not run,
1893 so there is no possibility of wanting to redisplay. */
1894 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1895 safe_eval_handler);
1896 UNGCPRO;
1897 val = unbind_to (count, val);
1898 }
1899
1900 return val;
1901 }
1902
1903
1904 /* Call function FN with one argument ARG.
1905 Return the result, or nil if something went wrong. */
1906
1907 Lisp_Object
1908 safe_call1 (fn, arg)
1909 Lisp_Object fn, arg;
1910 {
1911 Lisp_Object args[2];
1912 args[0] = fn;
1913 args[1] = arg;
1914 return safe_call (2, args);
1915 }
1916
1917
1918 \f
1919 /***********************************************************************
1920 Debugging
1921 ***********************************************************************/
1922
1923 #if 0
1924
1925 /* Define CHECK_IT to perform sanity checks on iterators.
1926 This is for debugging. It is too slow to do unconditionally. */
1927
1928 static void
1929 check_it (it)
1930 struct it *it;
1931 {
1932 if (it->method == next_element_from_string)
1933 {
1934 xassert (STRINGP (it->string));
1935 xassert (IT_STRING_CHARPOS (*it) >= 0);
1936 }
1937 else
1938 {
1939 xassert (IT_STRING_CHARPOS (*it) < 0);
1940 if (it->method == next_element_from_buffer)
1941 {
1942 /* Check that character and byte positions agree. */
1943 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1944 }
1945 }
1946
1947 if (it->dpvec)
1948 xassert (it->current.dpvec_index >= 0);
1949 else
1950 xassert (it->current.dpvec_index < 0);
1951 }
1952
1953 #define CHECK_IT(IT) check_it ((IT))
1954
1955 #else /* not 0 */
1956
1957 #define CHECK_IT(IT) (void) 0
1958
1959 #endif /* not 0 */
1960
1961
1962 #if GLYPH_DEBUG
1963
1964 /* Check that the window end of window W is what we expect it
1965 to be---the last row in the current matrix displaying text. */
1966
1967 static void
1968 check_window_end (w)
1969 struct window *w;
1970 {
1971 if (!MINI_WINDOW_P (w)
1972 && !NILP (w->window_end_valid))
1973 {
1974 struct glyph_row *row;
1975 xassert ((row = MATRIX_ROW (w->current_matrix,
1976 XFASTINT (w->window_end_vpos)),
1977 !row->enabled_p
1978 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1979 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1980 }
1981 }
1982
1983 #define CHECK_WINDOW_END(W) check_window_end ((W))
1984
1985 #else /* not GLYPH_DEBUG */
1986
1987 #define CHECK_WINDOW_END(W) (void) 0
1988
1989 #endif /* not GLYPH_DEBUG */
1990
1991
1992 \f
1993 /***********************************************************************
1994 Iterator initialization
1995 ***********************************************************************/
1996
1997 /* Initialize IT for displaying current_buffer in window W, starting
1998 at character position CHARPOS. CHARPOS < 0 means that no buffer
1999 position is specified which is useful when the iterator is assigned
2000 a position later. BYTEPOS is the byte position corresponding to
2001 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2002
2003 If ROW is not null, calls to produce_glyphs with IT as parameter
2004 will produce glyphs in that row.
2005
2006 BASE_FACE_ID is the id of a base face to use. It must be one of
2007 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2008 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2009 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2010
2011 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2012 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2013 will be initialized to use the corresponding mode line glyph row of
2014 the desired matrix of W. */
2015
2016 void
2017 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2018 struct it *it;
2019 struct window *w;
2020 int charpos, bytepos;
2021 struct glyph_row *row;
2022 enum face_id base_face_id;
2023 {
2024 int highlight_region_p;
2025
2026 /* Some precondition checks. */
2027 xassert (w != NULL && it != NULL);
2028 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2029 && charpos <= ZV));
2030
2031 /* If face attributes have been changed since the last redisplay,
2032 free realized faces now because they depend on face definitions
2033 that might have changed. Don't free faces while there might be
2034 desired matrices pending which reference these faces. */
2035 if (face_change_count && !inhibit_free_realized_faces)
2036 {
2037 face_change_count = 0;
2038 free_all_realized_faces (Qnil);
2039 }
2040
2041 /* Use one of the mode line rows of W's desired matrix if
2042 appropriate. */
2043 if (row == NULL)
2044 {
2045 if (base_face_id == MODE_LINE_FACE_ID
2046 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2047 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2048 else if (base_face_id == HEADER_LINE_FACE_ID)
2049 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2050 }
2051
2052 /* Clear IT. */
2053 bzero (it, sizeof *it);
2054 it->current.overlay_string_index = -1;
2055 it->current.dpvec_index = -1;
2056 it->base_face_id = base_face_id;
2057 it->string = Qnil;
2058 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2059
2060 /* The window in which we iterate over current_buffer: */
2061 XSETWINDOW (it->window, w);
2062 it->w = w;
2063 it->f = XFRAME (w->frame);
2064
2065 /* Extra space between lines (on window systems only). */
2066 if (base_face_id == DEFAULT_FACE_ID
2067 && FRAME_WINDOW_P (it->f))
2068 {
2069 if (NATNUMP (current_buffer->extra_line_spacing))
2070 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2071 else if (FLOATP (current_buffer->extra_line_spacing))
2072 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2073 * FRAME_LINE_HEIGHT (it->f));
2074 else if (it->f->extra_line_spacing > 0)
2075 it->extra_line_spacing = it->f->extra_line_spacing;
2076 }
2077
2078 /* If realized faces have been removed, e.g. because of face
2079 attribute changes of named faces, recompute them. When running
2080 in batch mode, the face cache of Vterminal_frame is null. If
2081 we happen to get called, make a dummy face cache. */
2082 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2083 init_frame_faces (it->f);
2084 if (FRAME_FACE_CACHE (it->f)->used == 0)
2085 recompute_basic_faces (it->f);
2086
2087 /* Current value of the `slice', `space-width', and 'height' properties. */
2088 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2089 it->space_width = Qnil;
2090 it->font_height = Qnil;
2091 it->override_ascent = -1;
2092
2093 /* Are control characters displayed as `^C'? */
2094 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2095
2096 /* -1 means everything between a CR and the following line end
2097 is invisible. >0 means lines indented more than this value are
2098 invisible. */
2099 it->selective = (INTEGERP (current_buffer->selective_display)
2100 ? XFASTINT (current_buffer->selective_display)
2101 : (!NILP (current_buffer->selective_display)
2102 ? -1 : 0));
2103 it->selective_display_ellipsis_p
2104 = !NILP (current_buffer->selective_display_ellipses);
2105
2106 /* Display table to use. */
2107 it->dp = window_display_table (w);
2108
2109 /* Are multibyte characters enabled in current_buffer? */
2110 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2111
2112 /* Non-zero if we should highlight the region. */
2113 highlight_region_p
2114 = (!NILP (Vtransient_mark_mode)
2115 && !NILP (current_buffer->mark_active)
2116 && XMARKER (current_buffer->mark)->buffer != 0);
2117
2118 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2119 start and end of a visible region in window IT->w. Set both to
2120 -1 to indicate no region. */
2121 if (highlight_region_p
2122 /* Maybe highlight only in selected window. */
2123 && (/* Either show region everywhere. */
2124 highlight_nonselected_windows
2125 /* Or show region in the selected window. */
2126 || w == XWINDOW (selected_window)
2127 /* Or show the region if we are in the mini-buffer and W is
2128 the window the mini-buffer refers to. */
2129 || (MINI_WINDOW_P (XWINDOW (selected_window))
2130 && WINDOWP (minibuf_selected_window)
2131 && w == XWINDOW (minibuf_selected_window))))
2132 {
2133 int charpos = marker_position (current_buffer->mark);
2134 it->region_beg_charpos = min (PT, charpos);
2135 it->region_end_charpos = max (PT, charpos);
2136 }
2137 else
2138 it->region_beg_charpos = it->region_end_charpos = -1;
2139
2140 /* Get the position at which the redisplay_end_trigger hook should
2141 be run, if it is to be run at all. */
2142 if (MARKERP (w->redisplay_end_trigger)
2143 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2144 it->redisplay_end_trigger_charpos
2145 = marker_position (w->redisplay_end_trigger);
2146 else if (INTEGERP (w->redisplay_end_trigger))
2147 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2148
2149 /* Correct bogus values of tab_width. */
2150 it->tab_width = XINT (current_buffer->tab_width);
2151 if (it->tab_width <= 0 || it->tab_width > 1000)
2152 it->tab_width = 8;
2153
2154 /* Are lines in the display truncated? */
2155 it->truncate_lines_p
2156 = (base_face_id != DEFAULT_FACE_ID
2157 || XINT (it->w->hscroll)
2158 || (truncate_partial_width_windows
2159 && !WINDOW_FULL_WIDTH_P (it->w))
2160 || !NILP (current_buffer->truncate_lines));
2161
2162 /* Get dimensions of truncation and continuation glyphs. These are
2163 displayed as fringe bitmaps under X, so we don't need them for such
2164 frames. */
2165 if (!FRAME_WINDOW_P (it->f))
2166 {
2167 if (it->truncate_lines_p)
2168 {
2169 /* We will need the truncation glyph. */
2170 xassert (it->glyph_row == NULL);
2171 produce_special_glyphs (it, IT_TRUNCATION);
2172 it->truncation_pixel_width = it->pixel_width;
2173 }
2174 else
2175 {
2176 /* We will need the continuation glyph. */
2177 xassert (it->glyph_row == NULL);
2178 produce_special_glyphs (it, IT_CONTINUATION);
2179 it->continuation_pixel_width = it->pixel_width;
2180 }
2181
2182 /* Reset these values to zero because the produce_special_glyphs
2183 above has changed them. */
2184 it->pixel_width = it->ascent = it->descent = 0;
2185 it->phys_ascent = it->phys_descent = 0;
2186 }
2187
2188 /* Set this after getting the dimensions of truncation and
2189 continuation glyphs, so that we don't produce glyphs when calling
2190 produce_special_glyphs, above. */
2191 it->glyph_row = row;
2192 it->area = TEXT_AREA;
2193
2194 /* Get the dimensions of the display area. The display area
2195 consists of the visible window area plus a horizontally scrolled
2196 part to the left of the window. All x-values are relative to the
2197 start of this total display area. */
2198 if (base_face_id != DEFAULT_FACE_ID)
2199 {
2200 /* Mode lines, menu bar in terminal frames. */
2201 it->first_visible_x = 0;
2202 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2203 }
2204 else
2205 {
2206 it->first_visible_x
2207 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2208 it->last_visible_x = (it->first_visible_x
2209 + window_box_width (w, TEXT_AREA));
2210
2211 /* If we truncate lines, leave room for the truncator glyph(s) at
2212 the right margin. Otherwise, leave room for the continuation
2213 glyph(s). Truncation and continuation glyphs are not inserted
2214 for window-based redisplay. */
2215 if (!FRAME_WINDOW_P (it->f))
2216 {
2217 if (it->truncate_lines_p)
2218 it->last_visible_x -= it->truncation_pixel_width;
2219 else
2220 it->last_visible_x -= it->continuation_pixel_width;
2221 }
2222
2223 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2224 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2225 }
2226
2227 /* Leave room for a border glyph. */
2228 if (!FRAME_WINDOW_P (it->f)
2229 && !WINDOW_RIGHTMOST_P (it->w))
2230 it->last_visible_x -= 1;
2231
2232 it->last_visible_y = window_text_bottom_y (w);
2233
2234 /* For mode lines and alike, arrange for the first glyph having a
2235 left box line if the face specifies a box. */
2236 if (base_face_id != DEFAULT_FACE_ID)
2237 {
2238 struct face *face;
2239
2240 it->face_id = base_face_id;
2241
2242 /* If we have a boxed mode line, make the first character appear
2243 with a left box line. */
2244 face = FACE_FROM_ID (it->f, base_face_id);
2245 if (face->box != FACE_NO_BOX)
2246 it->start_of_box_run_p = 1;
2247 }
2248
2249 /* If a buffer position was specified, set the iterator there,
2250 getting overlays and face properties from that position. */
2251 if (charpos >= BUF_BEG (current_buffer))
2252 {
2253 it->end_charpos = ZV;
2254 it->face_id = -1;
2255 IT_CHARPOS (*it) = charpos;
2256
2257 /* Compute byte position if not specified. */
2258 if (bytepos < charpos)
2259 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2260 else
2261 IT_BYTEPOS (*it) = bytepos;
2262
2263 it->start = it->current;
2264
2265 /* Compute faces etc. */
2266 reseat (it, it->current.pos, 1);
2267 }
2268
2269 CHECK_IT (it);
2270 }
2271
2272
2273 /* Initialize IT for the display of window W with window start POS. */
2274
2275 void
2276 start_display (it, w, pos)
2277 struct it *it;
2278 struct window *w;
2279 struct text_pos pos;
2280 {
2281 struct glyph_row *row;
2282 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2283
2284 row = w->desired_matrix->rows + first_vpos;
2285 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2286 it->first_vpos = first_vpos;
2287
2288 if (!it->truncate_lines_p)
2289 {
2290 int start_at_line_beg_p;
2291 int first_y = it->current_y;
2292
2293 /* If window start is not at a line start, skip forward to POS to
2294 get the correct continuation lines width. */
2295 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2296 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2297 if (!start_at_line_beg_p)
2298 {
2299 int new_x;
2300
2301 reseat_at_previous_visible_line_start (it);
2302 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2303
2304 new_x = it->current_x + it->pixel_width;
2305
2306 /* If lines are continued, this line may end in the middle
2307 of a multi-glyph character (e.g. a control character
2308 displayed as \003, or in the middle of an overlay
2309 string). In this case move_it_to above will not have
2310 taken us to the start of the continuation line but to the
2311 end of the continued line. */
2312 if (it->current_x > 0
2313 && !it->truncate_lines_p /* Lines are continued. */
2314 && (/* And glyph doesn't fit on the line. */
2315 new_x > it->last_visible_x
2316 /* Or it fits exactly and we're on a window
2317 system frame. */
2318 || (new_x == it->last_visible_x
2319 && FRAME_WINDOW_P (it->f))))
2320 {
2321 if (it->current.dpvec_index >= 0
2322 || it->current.overlay_string_index >= 0)
2323 {
2324 set_iterator_to_next (it, 1);
2325 move_it_in_display_line_to (it, -1, -1, 0);
2326 }
2327
2328 it->continuation_lines_width += it->current_x;
2329 }
2330
2331 /* We're starting a new display line, not affected by the
2332 height of the continued line, so clear the appropriate
2333 fields in the iterator structure. */
2334 it->max_ascent = it->max_descent = 0;
2335 it->max_phys_ascent = it->max_phys_descent = 0;
2336
2337 it->current_y = first_y;
2338 it->vpos = 0;
2339 it->current_x = it->hpos = 0;
2340 }
2341 }
2342
2343 #if 0 /* Don't assert the following because start_display is sometimes
2344 called intentionally with a window start that is not at a
2345 line start. Please leave this code in as a comment. */
2346
2347 /* Window start should be on a line start, now. */
2348 xassert (it->continuation_lines_width
2349 || IT_CHARPOS (it) == BEGV
2350 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2351 #endif /* 0 */
2352 }
2353
2354
2355 /* Return 1 if POS is a position in ellipses displayed for invisible
2356 text. W is the window we display, for text property lookup. */
2357
2358 static int
2359 in_ellipses_for_invisible_text_p (pos, w)
2360 struct display_pos *pos;
2361 struct window *w;
2362 {
2363 Lisp_Object prop, window;
2364 int ellipses_p = 0;
2365 int charpos = CHARPOS (pos->pos);
2366
2367 /* If POS specifies a position in a display vector, this might
2368 be for an ellipsis displayed for invisible text. We won't
2369 get the iterator set up for delivering that ellipsis unless
2370 we make sure that it gets aware of the invisible text. */
2371 if (pos->dpvec_index >= 0
2372 && pos->overlay_string_index < 0
2373 && CHARPOS (pos->string_pos) < 0
2374 && charpos > BEGV
2375 && (XSETWINDOW (window, w),
2376 prop = Fget_char_property (make_number (charpos),
2377 Qinvisible, window),
2378 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2379 {
2380 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2381 window);
2382 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2383 }
2384
2385 return ellipses_p;
2386 }
2387
2388
2389 /* Initialize IT for stepping through current_buffer in window W,
2390 starting at position POS that includes overlay string and display
2391 vector/ control character translation position information. Value
2392 is zero if there are overlay strings with newlines at POS. */
2393
2394 static int
2395 init_from_display_pos (it, w, pos)
2396 struct it *it;
2397 struct window *w;
2398 struct display_pos *pos;
2399 {
2400 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2401 int i, overlay_strings_with_newlines = 0;
2402
2403 /* If POS specifies a position in a display vector, this might
2404 be for an ellipsis displayed for invisible text. We won't
2405 get the iterator set up for delivering that ellipsis unless
2406 we make sure that it gets aware of the invisible text. */
2407 if (in_ellipses_for_invisible_text_p (pos, w))
2408 {
2409 --charpos;
2410 bytepos = 0;
2411 }
2412
2413 /* Keep in mind: the call to reseat in init_iterator skips invisible
2414 text, so we might end up at a position different from POS. This
2415 is only a problem when POS is a row start after a newline and an
2416 overlay starts there with an after-string, and the overlay has an
2417 invisible property. Since we don't skip invisible text in
2418 display_line and elsewhere immediately after consuming the
2419 newline before the row start, such a POS will not be in a string,
2420 but the call to init_iterator below will move us to the
2421 after-string. */
2422 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2423
2424 for (i = 0; i < it->n_overlay_strings; ++i)
2425 {
2426 const char *s = SDATA (it->overlay_strings[i]);
2427 const char *e = s + SBYTES (it->overlay_strings[i]);
2428
2429 while (s < e && *s != '\n')
2430 ++s;
2431
2432 if (s < e)
2433 {
2434 overlay_strings_with_newlines = 1;
2435 break;
2436 }
2437 }
2438
2439 /* If position is within an overlay string, set up IT to the right
2440 overlay string. */
2441 if (pos->overlay_string_index >= 0)
2442 {
2443 int relative_index;
2444
2445 /* If the first overlay string happens to have a `display'
2446 property for an image, the iterator will be set up for that
2447 image, and we have to undo that setup first before we can
2448 correct the overlay string index. */
2449 if (it->method == next_element_from_image)
2450 pop_it (it);
2451
2452 /* We already have the first chunk of overlay strings in
2453 IT->overlay_strings. Load more until the one for
2454 pos->overlay_string_index is in IT->overlay_strings. */
2455 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2456 {
2457 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2458 it->current.overlay_string_index = 0;
2459 while (n--)
2460 {
2461 load_overlay_strings (it, 0);
2462 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2463 }
2464 }
2465
2466 it->current.overlay_string_index = pos->overlay_string_index;
2467 relative_index = (it->current.overlay_string_index
2468 % OVERLAY_STRING_CHUNK_SIZE);
2469 it->string = it->overlay_strings[relative_index];
2470 xassert (STRINGP (it->string));
2471 it->current.string_pos = pos->string_pos;
2472 it->method = next_element_from_string;
2473 }
2474
2475 #if 0 /* This is bogus because POS not having an overlay string
2476 position does not mean it's after the string. Example: A
2477 line starting with a before-string and initialization of IT
2478 to the previous row's end position. */
2479 else if (it->current.overlay_string_index >= 0)
2480 {
2481 /* If POS says we're already after an overlay string ending at
2482 POS, make sure to pop the iterator because it will be in
2483 front of that overlay string. When POS is ZV, we've thereby
2484 also ``processed'' overlay strings at ZV. */
2485 while (it->sp)
2486 pop_it (it);
2487 it->current.overlay_string_index = -1;
2488 it->method = next_element_from_buffer;
2489 if (CHARPOS (pos->pos) == ZV)
2490 it->overlay_strings_at_end_processed_p = 1;
2491 }
2492 #endif /* 0 */
2493
2494 if (CHARPOS (pos->string_pos) >= 0)
2495 {
2496 /* Recorded position is not in an overlay string, but in another
2497 string. This can only be a string from a `display' property.
2498 IT should already be filled with that string. */
2499 it->current.string_pos = pos->string_pos;
2500 xassert (STRINGP (it->string));
2501 }
2502
2503 /* Restore position in display vector translations, control
2504 character translations or ellipses. */
2505 if (pos->dpvec_index >= 0)
2506 {
2507 if (it->dpvec == NULL)
2508 get_next_display_element (it);
2509 xassert (it->dpvec && it->current.dpvec_index == 0);
2510 it->current.dpvec_index = pos->dpvec_index;
2511 }
2512
2513 CHECK_IT (it);
2514 return !overlay_strings_with_newlines;
2515 }
2516
2517
2518 /* Initialize IT for stepping through current_buffer in window W
2519 starting at ROW->start. */
2520
2521 static void
2522 init_to_row_start (it, w, row)
2523 struct it *it;
2524 struct window *w;
2525 struct glyph_row *row;
2526 {
2527 init_from_display_pos (it, w, &row->start);
2528 it->start = row->start;
2529 it->continuation_lines_width = row->continuation_lines_width;
2530 CHECK_IT (it);
2531 }
2532
2533
2534 /* Initialize IT for stepping through current_buffer in window W
2535 starting in the line following ROW, i.e. starting at ROW->end.
2536 Value is zero if there are overlay strings with newlines at ROW's
2537 end position. */
2538
2539 static int
2540 init_to_row_end (it, w, row)
2541 struct it *it;
2542 struct window *w;
2543 struct glyph_row *row;
2544 {
2545 int success = 0;
2546
2547 if (init_from_display_pos (it, w, &row->end))
2548 {
2549 if (row->continued_p)
2550 it->continuation_lines_width
2551 = row->continuation_lines_width + row->pixel_width;
2552 CHECK_IT (it);
2553 success = 1;
2554 }
2555
2556 return success;
2557 }
2558
2559
2560
2561 \f
2562 /***********************************************************************
2563 Text properties
2564 ***********************************************************************/
2565
2566 /* Called when IT reaches IT->stop_charpos. Handle text property and
2567 overlay changes. Set IT->stop_charpos to the next position where
2568 to stop. */
2569
2570 static void
2571 handle_stop (it)
2572 struct it *it;
2573 {
2574 enum prop_handled handled;
2575 int handle_overlay_change_p = 1;
2576 struct props *p;
2577
2578 it->dpvec = NULL;
2579 it->current.dpvec_index = -1;
2580
2581 do
2582 {
2583 handled = HANDLED_NORMALLY;
2584
2585 /* Call text property handlers. */
2586 for (p = it_props; p->handler; ++p)
2587 {
2588 handled = p->handler (it);
2589
2590 if (handled == HANDLED_RECOMPUTE_PROPS)
2591 break;
2592 else if (handled == HANDLED_RETURN)
2593 return;
2594 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2595 handle_overlay_change_p = 0;
2596 }
2597
2598 if (handled != HANDLED_RECOMPUTE_PROPS)
2599 {
2600 /* Don't check for overlay strings below when set to deliver
2601 characters from a display vector. */
2602 if (it->method == next_element_from_display_vector)
2603 handle_overlay_change_p = 0;
2604
2605 /* Handle overlay changes. */
2606 if (handle_overlay_change_p)
2607 handled = handle_overlay_change (it);
2608
2609 /* Determine where to stop next. */
2610 if (handled == HANDLED_NORMALLY)
2611 compute_stop_pos (it);
2612 }
2613 }
2614 while (handled == HANDLED_RECOMPUTE_PROPS);
2615 }
2616
2617
2618 /* Compute IT->stop_charpos from text property and overlay change
2619 information for IT's current position. */
2620
2621 static void
2622 compute_stop_pos (it)
2623 struct it *it;
2624 {
2625 register INTERVAL iv, next_iv;
2626 Lisp_Object object, limit, position;
2627
2628 /* If nowhere else, stop at the end. */
2629 it->stop_charpos = it->end_charpos;
2630
2631 if (STRINGP (it->string))
2632 {
2633 /* Strings are usually short, so don't limit the search for
2634 properties. */
2635 object = it->string;
2636 limit = Qnil;
2637 position = make_number (IT_STRING_CHARPOS (*it));
2638 }
2639 else
2640 {
2641 int charpos;
2642
2643 /* If next overlay change is in front of the current stop pos
2644 (which is IT->end_charpos), stop there. Note: value of
2645 next_overlay_change is point-max if no overlay change
2646 follows. */
2647 charpos = next_overlay_change (IT_CHARPOS (*it));
2648 if (charpos < it->stop_charpos)
2649 it->stop_charpos = charpos;
2650
2651 /* If showing the region, we have to stop at the region
2652 start or end because the face might change there. */
2653 if (it->region_beg_charpos > 0)
2654 {
2655 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2656 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2657 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2658 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2659 }
2660
2661 /* Set up variables for computing the stop position from text
2662 property changes. */
2663 XSETBUFFER (object, current_buffer);
2664 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2665 position = make_number (IT_CHARPOS (*it));
2666
2667 }
2668
2669 /* Get the interval containing IT's position. Value is a null
2670 interval if there isn't such an interval. */
2671 iv = validate_interval_range (object, &position, &position, 0);
2672 if (!NULL_INTERVAL_P (iv))
2673 {
2674 Lisp_Object values_here[LAST_PROP_IDX];
2675 struct props *p;
2676
2677 /* Get properties here. */
2678 for (p = it_props; p->handler; ++p)
2679 values_here[p->idx] = textget (iv->plist, *p->name);
2680
2681 /* Look for an interval following iv that has different
2682 properties. */
2683 for (next_iv = next_interval (iv);
2684 (!NULL_INTERVAL_P (next_iv)
2685 && (NILP (limit)
2686 || XFASTINT (limit) > next_iv->position));
2687 next_iv = next_interval (next_iv))
2688 {
2689 for (p = it_props; p->handler; ++p)
2690 {
2691 Lisp_Object new_value;
2692
2693 new_value = textget (next_iv->plist, *p->name);
2694 if (!EQ (values_here[p->idx], new_value))
2695 break;
2696 }
2697
2698 if (p->handler)
2699 break;
2700 }
2701
2702 if (!NULL_INTERVAL_P (next_iv))
2703 {
2704 if (INTEGERP (limit)
2705 && next_iv->position >= XFASTINT (limit))
2706 /* No text property change up to limit. */
2707 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2708 else
2709 /* Text properties change in next_iv. */
2710 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2711 }
2712 }
2713
2714 xassert (STRINGP (it->string)
2715 || (it->stop_charpos >= BEGV
2716 && it->stop_charpos >= IT_CHARPOS (*it)));
2717 }
2718
2719
2720 /* Return the position of the next overlay change after POS in
2721 current_buffer. Value is point-max if no overlay change
2722 follows. This is like `next-overlay-change' but doesn't use
2723 xmalloc. */
2724
2725 static int
2726 next_overlay_change (pos)
2727 int pos;
2728 {
2729 int noverlays;
2730 int endpos;
2731 Lisp_Object *overlays;
2732 int i;
2733
2734 /* Get all overlays at the given position. */
2735 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2736
2737 /* If any of these overlays ends before endpos,
2738 use its ending point instead. */
2739 for (i = 0; i < noverlays; ++i)
2740 {
2741 Lisp_Object oend;
2742 int oendpos;
2743
2744 oend = OVERLAY_END (overlays[i]);
2745 oendpos = OVERLAY_POSITION (oend);
2746 endpos = min (endpos, oendpos);
2747 }
2748
2749 return endpos;
2750 }
2751
2752
2753 \f
2754 /***********************************************************************
2755 Fontification
2756 ***********************************************************************/
2757
2758 /* Handle changes in the `fontified' property of the current buffer by
2759 calling hook functions from Qfontification_functions to fontify
2760 regions of text. */
2761
2762 static enum prop_handled
2763 handle_fontified_prop (it)
2764 struct it *it;
2765 {
2766 Lisp_Object prop, pos;
2767 enum prop_handled handled = HANDLED_NORMALLY;
2768
2769 /* Get the value of the `fontified' property at IT's current buffer
2770 position. (The `fontified' property doesn't have a special
2771 meaning in strings.) If the value is nil, call functions from
2772 Qfontification_functions. */
2773 if (!STRINGP (it->string)
2774 && it->s == NULL
2775 && !NILP (Vfontification_functions)
2776 && !NILP (Vrun_hooks)
2777 && (pos = make_number (IT_CHARPOS (*it)),
2778 prop = Fget_char_property (pos, Qfontified, Qnil),
2779 NILP (prop)))
2780 {
2781 int count = SPECPDL_INDEX ();
2782 Lisp_Object val;
2783
2784 val = Vfontification_functions;
2785 specbind (Qfontification_functions, Qnil);
2786
2787 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2788 safe_call1 (val, pos);
2789 else
2790 {
2791 Lisp_Object globals, fn;
2792 struct gcpro gcpro1, gcpro2;
2793
2794 globals = Qnil;
2795 GCPRO2 (val, globals);
2796
2797 for (; CONSP (val); val = XCDR (val))
2798 {
2799 fn = XCAR (val);
2800
2801 if (EQ (fn, Qt))
2802 {
2803 /* A value of t indicates this hook has a local
2804 binding; it means to run the global binding too.
2805 In a global value, t should not occur. If it
2806 does, we must ignore it to avoid an endless
2807 loop. */
2808 for (globals = Fdefault_value (Qfontification_functions);
2809 CONSP (globals);
2810 globals = XCDR (globals))
2811 {
2812 fn = XCAR (globals);
2813 if (!EQ (fn, Qt))
2814 safe_call1 (fn, pos);
2815 }
2816 }
2817 else
2818 safe_call1 (fn, pos);
2819 }
2820
2821 UNGCPRO;
2822 }
2823
2824 unbind_to (count, Qnil);
2825
2826 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2827 something. This avoids an endless loop if they failed to
2828 fontify the text for which reason ever. */
2829 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2830 handled = HANDLED_RECOMPUTE_PROPS;
2831 }
2832
2833 return handled;
2834 }
2835
2836
2837 \f
2838 /***********************************************************************
2839 Faces
2840 ***********************************************************************/
2841
2842 /* Set up iterator IT from face properties at its current position.
2843 Called from handle_stop. */
2844
2845 static enum prop_handled
2846 handle_face_prop (it)
2847 struct it *it;
2848 {
2849 int new_face_id, next_stop;
2850
2851 if (!STRINGP (it->string))
2852 {
2853 new_face_id
2854 = face_at_buffer_position (it->w,
2855 IT_CHARPOS (*it),
2856 it->region_beg_charpos,
2857 it->region_end_charpos,
2858 &next_stop,
2859 (IT_CHARPOS (*it)
2860 + TEXT_PROP_DISTANCE_LIMIT),
2861 0);
2862
2863 /* Is this a start of a run of characters with box face?
2864 Caveat: this can be called for a freshly initialized
2865 iterator; face_id is -1 in this case. We know that the new
2866 face will not change until limit, i.e. if the new face has a
2867 box, all characters up to limit will have one. But, as
2868 usual, we don't know whether limit is really the end. */
2869 if (new_face_id != it->face_id)
2870 {
2871 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2872
2873 /* If new face has a box but old face has not, this is
2874 the start of a run of characters with box, i.e. it has
2875 a shadow on the left side. The value of face_id of the
2876 iterator will be -1 if this is the initial call that gets
2877 the face. In this case, we have to look in front of IT's
2878 position and see whether there is a face != new_face_id. */
2879 it->start_of_box_run_p
2880 = (new_face->box != FACE_NO_BOX
2881 && (it->face_id >= 0
2882 || IT_CHARPOS (*it) == BEG
2883 || new_face_id != face_before_it_pos (it)));
2884 it->face_box_p = new_face->box != FACE_NO_BOX;
2885 }
2886 }
2887 else
2888 {
2889 int base_face_id, bufpos;
2890
2891 if (it->current.overlay_string_index >= 0)
2892 bufpos = IT_CHARPOS (*it);
2893 else
2894 bufpos = 0;
2895
2896 /* For strings from a buffer, i.e. overlay strings or strings
2897 from a `display' property, use the face at IT's current
2898 buffer position as the base face to merge with, so that
2899 overlay strings appear in the same face as surrounding
2900 text, unless they specify their own faces. */
2901 base_face_id = underlying_face_id (it);
2902
2903 new_face_id = face_at_string_position (it->w,
2904 it->string,
2905 IT_STRING_CHARPOS (*it),
2906 bufpos,
2907 it->region_beg_charpos,
2908 it->region_end_charpos,
2909 &next_stop,
2910 base_face_id, 0);
2911
2912 #if 0 /* This shouldn't be neccessary. Let's check it. */
2913 /* If IT is used to display a mode line we would really like to
2914 use the mode line face instead of the frame's default face. */
2915 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2916 && new_face_id == DEFAULT_FACE_ID)
2917 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2918 #endif
2919
2920 /* Is this a start of a run of characters with box? Caveat:
2921 this can be called for a freshly allocated iterator; face_id
2922 is -1 is this case. We know that the new face will not
2923 change until the next check pos, i.e. if the new face has a
2924 box, all characters up to that position will have a
2925 box. But, as usual, we don't know whether that position
2926 is really the end. */
2927 if (new_face_id != it->face_id)
2928 {
2929 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2930 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2931
2932 /* If new face has a box but old face hasn't, this is the
2933 start of a run of characters with box, i.e. it has a
2934 shadow on the left side. */
2935 it->start_of_box_run_p
2936 = new_face->box && (old_face == NULL || !old_face->box);
2937 it->face_box_p = new_face->box != FACE_NO_BOX;
2938 }
2939 }
2940
2941 it->face_id = new_face_id;
2942 return HANDLED_NORMALLY;
2943 }
2944
2945
2946 /* Return the ID of the face ``underlying'' IT's current position,
2947 which is in a string. If the iterator is associated with a
2948 buffer, return the face at IT's current buffer position.
2949 Otherwise, use the iterator's base_face_id. */
2950
2951 static int
2952 underlying_face_id (it)
2953 struct it *it;
2954 {
2955 int face_id = it->base_face_id, i;
2956
2957 xassert (STRINGP (it->string));
2958
2959 for (i = it->sp - 1; i >= 0; --i)
2960 if (NILP (it->stack[i].string))
2961 face_id = it->stack[i].face_id;
2962
2963 return face_id;
2964 }
2965
2966
2967 /* Compute the face one character before or after the current position
2968 of IT. BEFORE_P non-zero means get the face in front of IT's
2969 position. Value is the id of the face. */
2970
2971 static int
2972 face_before_or_after_it_pos (it, before_p)
2973 struct it *it;
2974 int before_p;
2975 {
2976 int face_id, limit;
2977 int next_check_charpos;
2978 struct text_pos pos;
2979
2980 xassert (it->s == NULL);
2981
2982 if (STRINGP (it->string))
2983 {
2984 int bufpos, base_face_id;
2985
2986 /* No face change past the end of the string (for the case
2987 we are padding with spaces). No face change before the
2988 string start. */
2989 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2990 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2991 return it->face_id;
2992
2993 /* Set pos to the position before or after IT's current position. */
2994 if (before_p)
2995 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2996 else
2997 /* For composition, we must check the character after the
2998 composition. */
2999 pos = (it->what == IT_COMPOSITION
3000 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3001 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3002
3003 if (it->current.overlay_string_index >= 0)
3004 bufpos = IT_CHARPOS (*it);
3005 else
3006 bufpos = 0;
3007
3008 base_face_id = underlying_face_id (it);
3009
3010 /* Get the face for ASCII, or unibyte. */
3011 face_id = face_at_string_position (it->w,
3012 it->string,
3013 CHARPOS (pos),
3014 bufpos,
3015 it->region_beg_charpos,
3016 it->region_end_charpos,
3017 &next_check_charpos,
3018 base_face_id, 0);
3019
3020 /* Correct the face for charsets different from ASCII. Do it
3021 for the multibyte case only. The face returned above is
3022 suitable for unibyte text if IT->string is unibyte. */
3023 if (STRING_MULTIBYTE (it->string))
3024 {
3025 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3026 int rest = SBYTES (it->string) - BYTEPOS (pos);
3027 int c, len;
3028 struct face *face = FACE_FROM_ID (it->f, face_id);
3029
3030 c = string_char_and_length (p, rest, &len);
3031 face_id = FACE_FOR_CHAR (it->f, face, c);
3032 }
3033 }
3034 else
3035 {
3036 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3037 || (IT_CHARPOS (*it) <= BEGV && before_p))
3038 return it->face_id;
3039
3040 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3041 pos = it->current.pos;
3042
3043 if (before_p)
3044 DEC_TEXT_POS (pos, it->multibyte_p);
3045 else
3046 {
3047 if (it->what == IT_COMPOSITION)
3048 /* For composition, we must check the position after the
3049 composition. */
3050 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3051 else
3052 INC_TEXT_POS (pos, it->multibyte_p);
3053 }
3054
3055 /* Determine face for CHARSET_ASCII, or unibyte. */
3056 face_id = face_at_buffer_position (it->w,
3057 CHARPOS (pos),
3058 it->region_beg_charpos,
3059 it->region_end_charpos,
3060 &next_check_charpos,
3061 limit, 0);
3062
3063 /* Correct the face for charsets different from ASCII. Do it
3064 for the multibyte case only. The face returned above is
3065 suitable for unibyte text if current_buffer is unibyte. */
3066 if (it->multibyte_p)
3067 {
3068 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3069 struct face *face = FACE_FROM_ID (it->f, face_id);
3070 face_id = FACE_FOR_CHAR (it->f, face, c);
3071 }
3072 }
3073
3074 return face_id;
3075 }
3076
3077
3078 \f
3079 /***********************************************************************
3080 Invisible text
3081 ***********************************************************************/
3082
3083 /* Set up iterator IT from invisible properties at its current
3084 position. Called from handle_stop. */
3085
3086 static enum prop_handled
3087 handle_invisible_prop (it)
3088 struct it *it;
3089 {
3090 enum prop_handled handled = HANDLED_NORMALLY;
3091
3092 if (STRINGP (it->string))
3093 {
3094 extern Lisp_Object Qinvisible;
3095 Lisp_Object prop, end_charpos, limit, charpos;
3096
3097 /* Get the value of the invisible text property at the
3098 current position. Value will be nil if there is no such
3099 property. */
3100 charpos = make_number (IT_STRING_CHARPOS (*it));
3101 prop = Fget_text_property (charpos, Qinvisible, it->string);
3102
3103 if (!NILP (prop)
3104 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3105 {
3106 handled = HANDLED_RECOMPUTE_PROPS;
3107
3108 /* Get the position at which the next change of the
3109 invisible text property can be found in IT->string.
3110 Value will be nil if the property value is the same for
3111 all the rest of IT->string. */
3112 XSETINT (limit, SCHARS (it->string));
3113 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3114 it->string, limit);
3115
3116 /* Text at current position is invisible. The next
3117 change in the property is at position end_charpos.
3118 Move IT's current position to that position. */
3119 if (INTEGERP (end_charpos)
3120 && XFASTINT (end_charpos) < XFASTINT (limit))
3121 {
3122 struct text_pos old;
3123 old = it->current.string_pos;
3124 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3125 compute_string_pos (&it->current.string_pos, old, it->string);
3126 }
3127 else
3128 {
3129 /* The rest of the string is invisible. If this is an
3130 overlay string, proceed with the next overlay string
3131 or whatever comes and return a character from there. */
3132 if (it->current.overlay_string_index >= 0)
3133 {
3134 next_overlay_string (it);
3135 /* Don't check for overlay strings when we just
3136 finished processing them. */
3137 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3138 }
3139 else
3140 {
3141 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3142 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3143 }
3144 }
3145 }
3146 }
3147 else
3148 {
3149 int invis_p, newpos, next_stop, start_charpos;
3150 Lisp_Object pos, prop, overlay;
3151
3152 /* First of all, is there invisible text at this position? */
3153 start_charpos = IT_CHARPOS (*it);
3154 pos = make_number (IT_CHARPOS (*it));
3155 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3156 &overlay);
3157 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3158
3159 /* If we are on invisible text, skip over it. */
3160 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3161 {
3162 /* Record whether we have to display an ellipsis for the
3163 invisible text. */
3164 int display_ellipsis_p = invis_p == 2;
3165
3166 handled = HANDLED_RECOMPUTE_PROPS;
3167
3168 /* Loop skipping over invisible text. The loop is left at
3169 ZV or with IT on the first char being visible again. */
3170 do
3171 {
3172 /* Try to skip some invisible text. Return value is the
3173 position reached which can be equal to IT's position
3174 if there is nothing invisible here. This skips both
3175 over invisible text properties and overlays with
3176 invisible property. */
3177 newpos = skip_invisible (IT_CHARPOS (*it),
3178 &next_stop, ZV, it->window);
3179
3180 /* If we skipped nothing at all we weren't at invisible
3181 text in the first place. If everything to the end of
3182 the buffer was skipped, end the loop. */
3183 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3184 invis_p = 0;
3185 else
3186 {
3187 /* We skipped some characters but not necessarily
3188 all there are. Check if we ended up on visible
3189 text. Fget_char_property returns the property of
3190 the char before the given position, i.e. if we
3191 get invis_p = 0, this means that the char at
3192 newpos is visible. */
3193 pos = make_number (newpos);
3194 prop = Fget_char_property (pos, Qinvisible, it->window);
3195 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3196 }
3197
3198 /* If we ended up on invisible text, proceed to
3199 skip starting with next_stop. */
3200 if (invis_p)
3201 IT_CHARPOS (*it) = next_stop;
3202 }
3203 while (invis_p);
3204
3205 /* The position newpos is now either ZV or on visible text. */
3206 IT_CHARPOS (*it) = newpos;
3207 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3208
3209 /* If there are before-strings at the start of invisible
3210 text, and the text is invisible because of a text
3211 property, arrange to show before-strings because 20.x did
3212 it that way. (If the text is invisible because of an
3213 overlay property instead of a text property, this is
3214 already handled in the overlay code.) */
3215 if (NILP (overlay)
3216 && get_overlay_strings (it, start_charpos))
3217 {
3218 handled = HANDLED_RECOMPUTE_PROPS;
3219 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3220 }
3221 else if (display_ellipsis_p)
3222 setup_for_ellipsis (it);
3223 }
3224 }
3225
3226 return handled;
3227 }
3228
3229
3230 /* Make iterator IT return `...' next. */
3231
3232 static void
3233 setup_for_ellipsis (it)
3234 struct it *it;
3235 {
3236 if (it->dp
3237 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3238 {
3239 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3240 it->dpvec = v->contents;
3241 it->dpend = v->contents + v->size;
3242 }
3243 else
3244 {
3245 /* Default `...'. */
3246 it->dpvec = default_invis_vector;
3247 it->dpend = default_invis_vector + 3;
3248 }
3249
3250 /* The ellipsis display does not replace the display of the
3251 character at the new position. Indicate this by setting
3252 IT->dpvec_char_len to zero. */
3253 it->dpvec_char_len = 0;
3254
3255 it->current.dpvec_index = 0;
3256 it->method = next_element_from_display_vector;
3257 }
3258
3259
3260 \f
3261 /***********************************************************************
3262 'display' property
3263 ***********************************************************************/
3264
3265 /* Set up iterator IT from `display' property at its current position.
3266 Called from handle_stop. */
3267
3268 static enum prop_handled
3269 handle_display_prop (it)
3270 struct it *it;
3271 {
3272 Lisp_Object prop, object;
3273 struct text_pos *position;
3274 int display_replaced_p = 0;
3275
3276 if (STRINGP (it->string))
3277 {
3278 object = it->string;
3279 position = &it->current.string_pos;
3280 }
3281 else
3282 {
3283 object = it->w->buffer;
3284 position = &it->current.pos;
3285 }
3286
3287 /* Reset those iterator values set from display property values. */
3288 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3289 it->space_width = Qnil;
3290 it->font_height = Qnil;
3291 it->voffset = 0;
3292
3293 /* We don't support recursive `display' properties, i.e. string
3294 values that have a string `display' property, that have a string
3295 `display' property etc. */
3296 if (!it->string_from_display_prop_p)
3297 it->area = TEXT_AREA;
3298
3299 prop = Fget_char_property (make_number (position->charpos),
3300 Qdisplay, object);
3301 if (NILP (prop))
3302 return HANDLED_NORMALLY;
3303
3304 if (CONSP (prop)
3305 /* Simple properties. */
3306 && !EQ (XCAR (prop), Qimage)
3307 && !EQ (XCAR (prop), Qspace)
3308 && !EQ (XCAR (prop), Qwhen)
3309 && !EQ (XCAR (prop), Qslice)
3310 && !EQ (XCAR (prop), Qspace_width)
3311 && !EQ (XCAR (prop), Qheight)
3312 && !EQ (XCAR (prop), Qraise)
3313 /* Marginal area specifications. */
3314 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3315 && !EQ (XCAR (prop), Qleft_fringe)
3316 && !EQ (XCAR (prop), Qright_fringe)
3317 && !NILP (XCAR (prop)))
3318 {
3319 for (; CONSP (prop); prop = XCDR (prop))
3320 {
3321 if (handle_single_display_prop (it, XCAR (prop), object,
3322 position, display_replaced_p))
3323 display_replaced_p = 1;
3324 }
3325 }
3326 else if (VECTORP (prop))
3327 {
3328 int i;
3329 for (i = 0; i < ASIZE (prop); ++i)
3330 if (handle_single_display_prop (it, AREF (prop, i), object,
3331 position, display_replaced_p))
3332 display_replaced_p = 1;
3333 }
3334 else
3335 {
3336 if (handle_single_display_prop (it, prop, object, position, 0))
3337 display_replaced_p = 1;
3338 }
3339
3340 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3341 }
3342
3343
3344 /* Value is the position of the end of the `display' property starting
3345 at START_POS in OBJECT. */
3346
3347 static struct text_pos
3348 display_prop_end (it, object, start_pos)
3349 struct it *it;
3350 Lisp_Object object;
3351 struct text_pos start_pos;
3352 {
3353 Lisp_Object end;
3354 struct text_pos end_pos;
3355
3356 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3357 Qdisplay, object, Qnil);
3358 CHARPOS (end_pos) = XFASTINT (end);
3359 if (STRINGP (object))
3360 compute_string_pos (&end_pos, start_pos, it->string);
3361 else
3362 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3363
3364 return end_pos;
3365 }
3366
3367
3368 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3369 is the object in which the `display' property was found. *POSITION
3370 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3371 means that we previously saw a display sub-property which already
3372 replaced text display with something else, for example an image;
3373 ignore such properties after the first one has been processed.
3374
3375 If PROP is a `space' or `image' sub-property, set *POSITION to the
3376 end position of the `display' property.
3377
3378 Value is non-zero if something was found which replaces the display
3379 of buffer or string text. */
3380
3381 static int
3382 handle_single_display_prop (it, prop, object, position,
3383 display_replaced_before_p)
3384 struct it *it;
3385 Lisp_Object prop;
3386 Lisp_Object object;
3387 struct text_pos *position;
3388 int display_replaced_before_p;
3389 {
3390 Lisp_Object value;
3391 int replaces_text_display_p = 0;
3392 Lisp_Object form;
3393
3394 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3395 evaluated. If the result is nil, VALUE is ignored. */
3396 form = Qt;
3397 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3398 {
3399 prop = XCDR (prop);
3400 if (!CONSP (prop))
3401 return 0;
3402 form = XCAR (prop);
3403 prop = XCDR (prop);
3404 }
3405
3406 if (!NILP (form) && !EQ (form, Qt))
3407 {
3408 int count = SPECPDL_INDEX ();
3409 struct gcpro gcpro1;
3410
3411 /* Bind `object' to the object having the `display' property, a
3412 buffer or string. Bind `position' to the position in the
3413 object where the property was found, and `buffer-position'
3414 to the current position in the buffer. */
3415 specbind (Qobject, object);
3416 specbind (Qposition, make_number (CHARPOS (*position)));
3417 specbind (Qbuffer_position,
3418 make_number (STRINGP (object)
3419 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3420 GCPRO1 (form);
3421 form = safe_eval (form);
3422 UNGCPRO;
3423 unbind_to (count, Qnil);
3424 }
3425
3426 if (NILP (form))
3427 return 0;
3428
3429 if (CONSP (prop)
3430 && EQ (XCAR (prop), Qheight)
3431 && CONSP (XCDR (prop)))
3432 {
3433 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3434 return 0;
3435
3436 /* `(height HEIGHT)'. */
3437 it->font_height = XCAR (XCDR (prop));
3438 if (!NILP (it->font_height))
3439 {
3440 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3441 int new_height = -1;
3442
3443 if (CONSP (it->font_height)
3444 && (EQ (XCAR (it->font_height), Qplus)
3445 || EQ (XCAR (it->font_height), Qminus))
3446 && CONSP (XCDR (it->font_height))
3447 && INTEGERP (XCAR (XCDR (it->font_height))))
3448 {
3449 /* `(+ N)' or `(- N)' where N is an integer. */
3450 int steps = XINT (XCAR (XCDR (it->font_height)));
3451 if (EQ (XCAR (it->font_height), Qplus))
3452 steps = - steps;
3453 it->face_id = smaller_face (it->f, it->face_id, steps);
3454 }
3455 else if (FUNCTIONP (it->font_height))
3456 {
3457 /* Call function with current height as argument.
3458 Value is the new height. */
3459 Lisp_Object height;
3460 height = safe_call1 (it->font_height,
3461 face->lface[LFACE_HEIGHT_INDEX]);
3462 if (NUMBERP (height))
3463 new_height = XFLOATINT (height);
3464 }
3465 else if (NUMBERP (it->font_height))
3466 {
3467 /* Value is a multiple of the canonical char height. */
3468 struct face *face;
3469
3470 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3471 new_height = (XFLOATINT (it->font_height)
3472 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3473 }
3474 else
3475 {
3476 /* Evaluate IT->font_height with `height' bound to the
3477 current specified height to get the new height. */
3478 Lisp_Object value;
3479 int count = SPECPDL_INDEX ();
3480
3481 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3482 value = safe_eval (it->font_height);
3483 unbind_to (count, Qnil);
3484
3485 if (NUMBERP (value))
3486 new_height = XFLOATINT (value);
3487 }
3488
3489 if (new_height > 0)
3490 it->face_id = face_with_height (it->f, it->face_id, new_height);
3491 }
3492 }
3493 else if (CONSP (prop)
3494 && EQ (XCAR (prop), Qspace_width)
3495 && CONSP (XCDR (prop)))
3496 {
3497 /* `(space_width WIDTH)'. */
3498 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3499 return 0;
3500
3501 value = XCAR (XCDR (prop));
3502 if (NUMBERP (value) && XFLOATINT (value) > 0)
3503 it->space_width = value;
3504 }
3505 else if (CONSP (prop)
3506 && EQ (XCAR (prop), Qslice))
3507 {
3508 /* `(slice X Y WIDTH HEIGHT)'. */
3509 Lisp_Object tem;
3510
3511 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3512 return 0;
3513
3514 if (tem = XCDR (prop), CONSP (tem))
3515 {
3516 it->slice.x = XCAR (tem);
3517 if (tem = XCDR (tem), CONSP (tem))
3518 {
3519 it->slice.y = XCAR (tem);
3520 if (tem = XCDR (tem), CONSP (tem))
3521 {
3522 it->slice.width = XCAR (tem);
3523 if (tem = XCDR (tem), CONSP (tem))
3524 it->slice.height = XCAR (tem);
3525 }
3526 }
3527 }
3528 }
3529 else if (CONSP (prop)
3530 && EQ (XCAR (prop), Qraise)
3531 && CONSP (XCDR (prop)))
3532 {
3533 /* `(raise FACTOR)'. */
3534 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3535 return 0;
3536
3537 #ifdef HAVE_WINDOW_SYSTEM
3538 value = XCAR (XCDR (prop));
3539 if (NUMBERP (value))
3540 {
3541 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3542 it->voffset = - (XFLOATINT (value)
3543 * (FONT_HEIGHT (face->font)));
3544 }
3545 #endif /* HAVE_WINDOW_SYSTEM */
3546 }
3547 else if (!it->string_from_display_prop_p)
3548 {
3549 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3550 VALUE) or `((margin nil) VALUE)' or VALUE. */
3551 Lisp_Object location, value;
3552 struct text_pos start_pos;
3553 int valid_p;
3554
3555 /* Characters having this form of property are not displayed, so
3556 we have to find the end of the property. */
3557 start_pos = *position;
3558 *position = display_prop_end (it, object, start_pos);
3559 value = Qnil;
3560
3561 /* Let's stop at the new position and assume that all
3562 text properties change there. */
3563 it->stop_charpos = position->charpos;
3564
3565 if (CONSP (prop)
3566 && (EQ (XCAR (prop), Qleft_fringe)
3567 || EQ (XCAR (prop), Qright_fringe))
3568 && CONSP (XCDR (prop)))
3569 {
3570 unsigned face_id = DEFAULT_FACE_ID;
3571
3572 /* Save current settings of IT so that we can restore them
3573 when we are finished with the glyph property value. */
3574
3575 /* `(left-fringe BITMAP FACE)'. */
3576 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3577 return 0;
3578
3579 #ifdef HAVE_WINDOW_SYSTEM
3580 value = XCAR (XCDR (prop));
3581 if (!NUMBERP (value)
3582 || !valid_fringe_bitmap_id_p (XINT (value)))
3583 return 0;
3584
3585 if (CONSP (XCDR (XCDR (prop))))
3586 {
3587 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3588
3589 face_id = lookup_named_face (it->f, face_name, 'A');
3590 if (face_id < 0)
3591 return 0;
3592 }
3593
3594 push_it (it);
3595
3596 it->area = TEXT_AREA;
3597 it->what = IT_IMAGE;
3598 it->image_id = -1; /* no image */
3599 it->position = start_pos;
3600 it->object = NILP (object) ? it->w->buffer : object;
3601 it->method = next_element_from_image;
3602 it->face_id = face_id;
3603
3604 /* Say that we haven't consumed the characters with
3605 `display' property yet. The call to pop_it in
3606 set_iterator_to_next will clean this up. */
3607 *position = start_pos;
3608
3609 if (EQ (XCAR (prop), Qleft_fringe))
3610 {
3611 it->left_user_fringe_bitmap = XINT (value);
3612 it->left_user_fringe_face_id = face_id;
3613 }
3614 else
3615 {
3616 it->right_user_fringe_bitmap = XINT (value);
3617 it->right_user_fringe_face_id = face_id;
3618 }
3619 #endif /* HAVE_WINDOW_SYSTEM */
3620 return 1;
3621 }
3622
3623 location = Qunbound;
3624 if (CONSP (prop) && CONSP (XCAR (prop)))
3625 {
3626 Lisp_Object tem;
3627
3628 value = XCDR (prop);
3629 if (CONSP (value))
3630 value = XCAR (value);
3631
3632 tem = XCAR (prop);
3633 if (EQ (XCAR (tem), Qmargin)
3634 && (tem = XCDR (tem),
3635 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3636 (NILP (tem)
3637 || EQ (tem, Qleft_margin)
3638 || EQ (tem, Qright_margin))))
3639 location = tem;
3640 }
3641
3642 if (EQ (location, Qunbound))
3643 {
3644 location = Qnil;
3645 value = prop;
3646 }
3647
3648 valid_p = (STRINGP (value)
3649 #ifdef HAVE_WINDOW_SYSTEM
3650 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3651 #endif /* not HAVE_WINDOW_SYSTEM */
3652 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3653
3654 if ((EQ (location, Qleft_margin)
3655 || EQ (location, Qright_margin)
3656 || NILP (location))
3657 && valid_p
3658 && !display_replaced_before_p)
3659 {
3660 replaces_text_display_p = 1;
3661
3662 /* Save current settings of IT so that we can restore them
3663 when we are finished with the glyph property value. */
3664 push_it (it);
3665
3666 if (NILP (location))
3667 it->area = TEXT_AREA;
3668 else if (EQ (location, Qleft_margin))
3669 it->area = LEFT_MARGIN_AREA;
3670 else
3671 it->area = RIGHT_MARGIN_AREA;
3672
3673 if (STRINGP (value))
3674 {
3675 it->string = value;
3676 it->multibyte_p = STRING_MULTIBYTE (it->string);
3677 it->current.overlay_string_index = -1;
3678 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3679 it->end_charpos = it->string_nchars = SCHARS (it->string);
3680 it->method = next_element_from_string;
3681 it->stop_charpos = 0;
3682 it->string_from_display_prop_p = 1;
3683 /* Say that we haven't consumed the characters with
3684 `display' property yet. The call to pop_it in
3685 set_iterator_to_next will clean this up. */
3686 *position = start_pos;
3687 }
3688 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3689 {
3690 it->method = next_element_from_stretch;
3691 it->object = value;
3692 it->current.pos = it->position = start_pos;
3693 }
3694 #ifdef HAVE_WINDOW_SYSTEM
3695 else
3696 {
3697 it->what = IT_IMAGE;
3698 it->image_id = lookup_image (it->f, value);
3699 it->position = start_pos;
3700 it->object = NILP (object) ? it->w->buffer : object;
3701 it->method = next_element_from_image;
3702
3703 /* Say that we haven't consumed the characters with
3704 `display' property yet. The call to pop_it in
3705 set_iterator_to_next will clean this up. */
3706 *position = start_pos;
3707 }
3708 #endif /* HAVE_WINDOW_SYSTEM */
3709 }
3710 else
3711 /* Invalid property or property not supported. Restore
3712 the position to what it was before. */
3713 *position = start_pos;
3714 }
3715
3716 return replaces_text_display_p;
3717 }
3718
3719
3720 /* Check if PROP is a display sub-property value whose text should be
3721 treated as intangible. */
3722
3723 static int
3724 single_display_prop_intangible_p (prop)
3725 Lisp_Object prop;
3726 {
3727 /* Skip over `when FORM'. */
3728 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3729 {
3730 prop = XCDR (prop);
3731 if (!CONSP (prop))
3732 return 0;
3733 prop = XCDR (prop);
3734 }
3735
3736 if (STRINGP (prop))
3737 return 1;
3738
3739 if (!CONSP (prop))
3740 return 0;
3741
3742 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3743 we don't need to treat text as intangible. */
3744 if (EQ (XCAR (prop), Qmargin))
3745 {
3746 prop = XCDR (prop);
3747 if (!CONSP (prop))
3748 return 0;
3749
3750 prop = XCDR (prop);
3751 if (!CONSP (prop)
3752 || EQ (XCAR (prop), Qleft_margin)
3753 || EQ (XCAR (prop), Qright_margin))
3754 return 0;
3755 }
3756
3757 return (CONSP (prop)
3758 && (EQ (XCAR (prop), Qimage)
3759 || EQ (XCAR (prop), Qspace)));
3760 }
3761
3762
3763 /* Check if PROP is a display property value whose text should be
3764 treated as intangible. */
3765
3766 int
3767 display_prop_intangible_p (prop)
3768 Lisp_Object prop;
3769 {
3770 if (CONSP (prop)
3771 && CONSP (XCAR (prop))
3772 && !EQ (Qmargin, XCAR (XCAR (prop))))
3773 {
3774 /* A list of sub-properties. */
3775 while (CONSP (prop))
3776 {
3777 if (single_display_prop_intangible_p (XCAR (prop)))
3778 return 1;
3779 prop = XCDR (prop);
3780 }
3781 }
3782 else if (VECTORP (prop))
3783 {
3784 /* A vector of sub-properties. */
3785 int i;
3786 for (i = 0; i < ASIZE (prop); ++i)
3787 if (single_display_prop_intangible_p (AREF (prop, i)))
3788 return 1;
3789 }
3790 else
3791 return single_display_prop_intangible_p (prop);
3792
3793 return 0;
3794 }
3795
3796
3797 /* Return 1 if PROP is a display sub-property value containing STRING. */
3798
3799 static int
3800 single_display_prop_string_p (prop, string)
3801 Lisp_Object prop, string;
3802 {
3803 if (EQ (string, prop))
3804 return 1;
3805
3806 /* Skip over `when FORM'. */
3807 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3808 {
3809 prop = XCDR (prop);
3810 if (!CONSP (prop))
3811 return 0;
3812 prop = XCDR (prop);
3813 }
3814
3815 if (CONSP (prop))
3816 /* Skip over `margin LOCATION'. */
3817 if (EQ (XCAR (prop), Qmargin))
3818 {
3819 prop = XCDR (prop);
3820 if (!CONSP (prop))
3821 return 0;
3822
3823 prop = XCDR (prop);
3824 if (!CONSP (prop))
3825 return 0;
3826 }
3827
3828 return CONSP (prop) && EQ (XCAR (prop), string);
3829 }
3830
3831
3832 /* Return 1 if STRING appears in the `display' property PROP. */
3833
3834 static int
3835 display_prop_string_p (prop, string)
3836 Lisp_Object prop, string;
3837 {
3838 if (CONSP (prop)
3839 && CONSP (XCAR (prop))
3840 && !EQ (Qmargin, XCAR (XCAR (prop))))
3841 {
3842 /* A list of sub-properties. */
3843 while (CONSP (prop))
3844 {
3845 if (single_display_prop_string_p (XCAR (prop), string))
3846 return 1;
3847 prop = XCDR (prop);
3848 }
3849 }
3850 else if (VECTORP (prop))
3851 {
3852 /* A vector of sub-properties. */
3853 int i;
3854 for (i = 0; i < ASIZE (prop); ++i)
3855 if (single_display_prop_string_p (AREF (prop, i), string))
3856 return 1;
3857 }
3858 else
3859 return single_display_prop_string_p (prop, string);
3860
3861 return 0;
3862 }
3863
3864
3865 /* Determine from which buffer position in W's buffer STRING comes
3866 from. AROUND_CHARPOS is an approximate position where it could
3867 be from. Value is the buffer position or 0 if it couldn't be
3868 determined.
3869
3870 W's buffer must be current.
3871
3872 This function is necessary because we don't record buffer positions
3873 in glyphs generated from strings (to keep struct glyph small).
3874 This function may only use code that doesn't eval because it is
3875 called asynchronously from note_mouse_highlight. */
3876
3877 int
3878 string_buffer_position (w, string, around_charpos)
3879 struct window *w;
3880 Lisp_Object string;
3881 int around_charpos;
3882 {
3883 Lisp_Object limit, prop, pos;
3884 const int MAX_DISTANCE = 1000;
3885 int found = 0;
3886
3887 pos = make_number (around_charpos);
3888 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3889 while (!found && !EQ (pos, limit))
3890 {
3891 prop = Fget_char_property (pos, Qdisplay, Qnil);
3892 if (!NILP (prop) && display_prop_string_p (prop, string))
3893 found = 1;
3894 else
3895 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3896 }
3897
3898 if (!found)
3899 {
3900 pos = make_number (around_charpos);
3901 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3902 while (!found && !EQ (pos, limit))
3903 {
3904 prop = Fget_char_property (pos, Qdisplay, Qnil);
3905 if (!NILP (prop) && display_prop_string_p (prop, string))
3906 found = 1;
3907 else
3908 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3909 limit);
3910 }
3911 }
3912
3913 return found ? XINT (pos) : 0;
3914 }
3915
3916
3917 \f
3918 /***********************************************************************
3919 `composition' property
3920 ***********************************************************************/
3921
3922 /* Set up iterator IT from `composition' property at its current
3923 position. Called from handle_stop. */
3924
3925 static enum prop_handled
3926 handle_composition_prop (it)
3927 struct it *it;
3928 {
3929 Lisp_Object prop, string;
3930 int pos, pos_byte, end;
3931 enum prop_handled handled = HANDLED_NORMALLY;
3932
3933 if (STRINGP (it->string))
3934 {
3935 pos = IT_STRING_CHARPOS (*it);
3936 pos_byte = IT_STRING_BYTEPOS (*it);
3937 string = it->string;
3938 }
3939 else
3940 {
3941 pos = IT_CHARPOS (*it);
3942 pos_byte = IT_BYTEPOS (*it);
3943 string = Qnil;
3944 }
3945
3946 /* If there's a valid composition and point is not inside of the
3947 composition (in the case that the composition is from the current
3948 buffer), draw a glyph composed from the composition components. */
3949 if (find_composition (pos, -1, &pos, &end, &prop, string)
3950 && COMPOSITION_VALID_P (pos, end, prop)
3951 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3952 {
3953 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3954
3955 if (id >= 0)
3956 {
3957 it->method = next_element_from_composition;
3958 it->cmp_id = id;
3959 it->cmp_len = COMPOSITION_LENGTH (prop);
3960 /* For a terminal, draw only the first character of the
3961 components. */
3962 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3963 it->len = (STRINGP (it->string)
3964 ? string_char_to_byte (it->string, end)
3965 : CHAR_TO_BYTE (end)) - pos_byte;
3966 it->stop_charpos = end;
3967 handled = HANDLED_RETURN;
3968 }
3969 }
3970
3971 return handled;
3972 }
3973
3974
3975 \f
3976 /***********************************************************************
3977 Overlay strings
3978 ***********************************************************************/
3979
3980 /* The following structure is used to record overlay strings for
3981 later sorting in load_overlay_strings. */
3982
3983 struct overlay_entry
3984 {
3985 Lisp_Object overlay;
3986 Lisp_Object string;
3987 int priority;
3988 int after_string_p;
3989 };
3990
3991
3992 /* Set up iterator IT from overlay strings at its current position.
3993 Called from handle_stop. */
3994
3995 static enum prop_handled
3996 handle_overlay_change (it)
3997 struct it *it;
3998 {
3999 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4000 return HANDLED_RECOMPUTE_PROPS;
4001 else
4002 return HANDLED_NORMALLY;
4003 }
4004
4005
4006 /* Set up the next overlay string for delivery by IT, if there is an
4007 overlay string to deliver. Called by set_iterator_to_next when the
4008 end of the current overlay string is reached. If there are more
4009 overlay strings to display, IT->string and
4010 IT->current.overlay_string_index are set appropriately here.
4011 Otherwise IT->string is set to nil. */
4012
4013 static void
4014 next_overlay_string (it)
4015 struct it *it;
4016 {
4017 ++it->current.overlay_string_index;
4018 if (it->current.overlay_string_index == it->n_overlay_strings)
4019 {
4020 /* No more overlay strings. Restore IT's settings to what
4021 they were before overlay strings were processed, and
4022 continue to deliver from current_buffer. */
4023 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4024
4025 pop_it (it);
4026 xassert (it->stop_charpos >= BEGV
4027 && it->stop_charpos <= it->end_charpos);
4028 it->string = Qnil;
4029 it->current.overlay_string_index = -1;
4030 SET_TEXT_POS (it->current.string_pos, -1, -1);
4031 it->n_overlay_strings = 0;
4032 it->method = next_element_from_buffer;
4033
4034 /* If we're at the end of the buffer, record that we have
4035 processed the overlay strings there already, so that
4036 next_element_from_buffer doesn't try it again. */
4037 if (IT_CHARPOS (*it) >= it->end_charpos)
4038 it->overlay_strings_at_end_processed_p = 1;
4039
4040 /* If we have to display `...' for invisible text, set
4041 the iterator up for that. */
4042 if (display_ellipsis_p)
4043 setup_for_ellipsis (it);
4044 }
4045 else
4046 {
4047 /* There are more overlay strings to process. If
4048 IT->current.overlay_string_index has advanced to a position
4049 where we must load IT->overlay_strings with more strings, do
4050 it. */
4051 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4052
4053 if (it->current.overlay_string_index && i == 0)
4054 load_overlay_strings (it, 0);
4055
4056 /* Initialize IT to deliver display elements from the overlay
4057 string. */
4058 it->string = it->overlay_strings[i];
4059 it->multibyte_p = STRING_MULTIBYTE (it->string);
4060 SET_TEXT_POS (it->current.string_pos, 0, 0);
4061 it->method = next_element_from_string;
4062 it->stop_charpos = 0;
4063 }
4064
4065 CHECK_IT (it);
4066 }
4067
4068
4069 /* Compare two overlay_entry structures E1 and E2. Used as a
4070 comparison function for qsort in load_overlay_strings. Overlay
4071 strings for the same position are sorted so that
4072
4073 1. All after-strings come in front of before-strings, except
4074 when they come from the same overlay.
4075
4076 2. Within after-strings, strings are sorted so that overlay strings
4077 from overlays with higher priorities come first.
4078
4079 2. Within before-strings, strings are sorted so that overlay
4080 strings from overlays with higher priorities come last.
4081
4082 Value is analogous to strcmp. */
4083
4084
4085 static int
4086 compare_overlay_entries (e1, e2)
4087 void *e1, *e2;
4088 {
4089 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4090 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4091 int result;
4092
4093 if (entry1->after_string_p != entry2->after_string_p)
4094 {
4095 /* Let after-strings appear in front of before-strings if
4096 they come from different overlays. */
4097 if (EQ (entry1->overlay, entry2->overlay))
4098 result = entry1->after_string_p ? 1 : -1;
4099 else
4100 result = entry1->after_string_p ? -1 : 1;
4101 }
4102 else if (entry1->after_string_p)
4103 /* After-strings sorted in order of decreasing priority. */
4104 result = entry2->priority - entry1->priority;
4105 else
4106 /* Before-strings sorted in order of increasing priority. */
4107 result = entry1->priority - entry2->priority;
4108
4109 return result;
4110 }
4111
4112
4113 /* Load the vector IT->overlay_strings with overlay strings from IT's
4114 current buffer position, or from CHARPOS if that is > 0. Set
4115 IT->n_overlays to the total number of overlay strings found.
4116
4117 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4118 a time. On entry into load_overlay_strings,
4119 IT->current.overlay_string_index gives the number of overlay
4120 strings that have already been loaded by previous calls to this
4121 function.
4122
4123 IT->add_overlay_start contains an additional overlay start
4124 position to consider for taking overlay strings from, if non-zero.
4125 This position comes into play when the overlay has an `invisible'
4126 property, and both before and after-strings. When we've skipped to
4127 the end of the overlay, because of its `invisible' property, we
4128 nevertheless want its before-string to appear.
4129 IT->add_overlay_start will contain the overlay start position
4130 in this case.
4131
4132 Overlay strings are sorted so that after-string strings come in
4133 front of before-string strings. Within before and after-strings,
4134 strings are sorted by overlay priority. See also function
4135 compare_overlay_entries. */
4136
4137 static void
4138 load_overlay_strings (it, charpos)
4139 struct it *it;
4140 int charpos;
4141 {
4142 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4143 Lisp_Object overlay, window, str, invisible;
4144 struct Lisp_Overlay *ov;
4145 int start, end;
4146 int size = 20;
4147 int n = 0, i, j, invis_p;
4148 struct overlay_entry *entries
4149 = (struct overlay_entry *) alloca (size * sizeof *entries);
4150
4151 if (charpos <= 0)
4152 charpos = IT_CHARPOS (*it);
4153
4154 /* Append the overlay string STRING of overlay OVERLAY to vector
4155 `entries' which has size `size' and currently contains `n'
4156 elements. AFTER_P non-zero means STRING is an after-string of
4157 OVERLAY. */
4158 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4159 do \
4160 { \
4161 Lisp_Object priority; \
4162 \
4163 if (n == size) \
4164 { \
4165 int new_size = 2 * size; \
4166 struct overlay_entry *old = entries; \
4167 entries = \
4168 (struct overlay_entry *) alloca (new_size \
4169 * sizeof *entries); \
4170 bcopy (old, entries, size * sizeof *entries); \
4171 size = new_size; \
4172 } \
4173 \
4174 entries[n].string = (STRING); \
4175 entries[n].overlay = (OVERLAY); \
4176 priority = Foverlay_get ((OVERLAY), Qpriority); \
4177 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4178 entries[n].after_string_p = (AFTER_P); \
4179 ++n; \
4180 } \
4181 while (0)
4182
4183 /* Process overlay before the overlay center. */
4184 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4185 {
4186 XSETMISC (overlay, ov);
4187 xassert (OVERLAYP (overlay));
4188 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4189 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4190
4191 if (end < charpos)
4192 break;
4193
4194 /* Skip this overlay if it doesn't start or end at IT's current
4195 position. */
4196 if (end != charpos && start != charpos)
4197 continue;
4198
4199 /* Skip this overlay if it doesn't apply to IT->w. */
4200 window = Foverlay_get (overlay, Qwindow);
4201 if (WINDOWP (window) && XWINDOW (window) != it->w)
4202 continue;
4203
4204 /* If the text ``under'' the overlay is invisible, both before-
4205 and after-strings from this overlay are visible; start and
4206 end position are indistinguishable. */
4207 invisible = Foverlay_get (overlay, Qinvisible);
4208 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4209
4210 /* If overlay has a non-empty before-string, record it. */
4211 if ((start == charpos || (end == charpos && invis_p))
4212 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4213 && SCHARS (str))
4214 RECORD_OVERLAY_STRING (overlay, str, 0);
4215
4216 /* If overlay has a non-empty after-string, record it. */
4217 if ((end == charpos || (start == charpos && invis_p))
4218 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4219 && SCHARS (str))
4220 RECORD_OVERLAY_STRING (overlay, str, 1);
4221 }
4222
4223 /* Process overlays after the overlay center. */
4224 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4225 {
4226 XSETMISC (overlay, ov);
4227 xassert (OVERLAYP (overlay));
4228 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4229 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4230
4231 if (start > charpos)
4232 break;
4233
4234 /* Skip this overlay if it doesn't start or end at IT's current
4235 position. */
4236 if (end != charpos && start != charpos)
4237 continue;
4238
4239 /* Skip this overlay if it doesn't apply to IT->w. */
4240 window = Foverlay_get (overlay, Qwindow);
4241 if (WINDOWP (window) && XWINDOW (window) != it->w)
4242 continue;
4243
4244 /* If the text ``under'' the overlay is invisible, it has a zero
4245 dimension, and both before- and after-strings apply. */
4246 invisible = Foverlay_get (overlay, Qinvisible);
4247 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4248
4249 /* If overlay has a non-empty before-string, record it. */
4250 if ((start == charpos || (end == charpos && invis_p))
4251 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4252 && SCHARS (str))
4253 RECORD_OVERLAY_STRING (overlay, str, 0);
4254
4255 /* If overlay has a non-empty after-string, record it. */
4256 if ((end == charpos || (start == charpos && invis_p))
4257 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4258 && SCHARS (str))
4259 RECORD_OVERLAY_STRING (overlay, str, 1);
4260 }
4261
4262 #undef RECORD_OVERLAY_STRING
4263
4264 /* Sort entries. */
4265 if (n > 1)
4266 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4267
4268 /* Record the total number of strings to process. */
4269 it->n_overlay_strings = n;
4270
4271 /* IT->current.overlay_string_index is the number of overlay strings
4272 that have already been consumed by IT. Copy some of the
4273 remaining overlay strings to IT->overlay_strings. */
4274 i = 0;
4275 j = it->current.overlay_string_index;
4276 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4277 it->overlay_strings[i++] = entries[j++].string;
4278
4279 CHECK_IT (it);
4280 }
4281
4282
4283 /* Get the first chunk of overlay strings at IT's current buffer
4284 position, or at CHARPOS if that is > 0. Value is non-zero if at
4285 least one overlay string was found. */
4286
4287 static int
4288 get_overlay_strings (it, charpos)
4289 struct it *it;
4290 int charpos;
4291 {
4292 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4293 process. This fills IT->overlay_strings with strings, and sets
4294 IT->n_overlay_strings to the total number of strings to process.
4295 IT->pos.overlay_string_index has to be set temporarily to zero
4296 because load_overlay_strings needs this; it must be set to -1
4297 when no overlay strings are found because a zero value would
4298 indicate a position in the first overlay string. */
4299 it->current.overlay_string_index = 0;
4300 load_overlay_strings (it, charpos);
4301
4302 /* If we found overlay strings, set up IT to deliver display
4303 elements from the first one. Otherwise set up IT to deliver
4304 from current_buffer. */
4305 if (it->n_overlay_strings)
4306 {
4307 /* Make sure we know settings in current_buffer, so that we can
4308 restore meaningful values when we're done with the overlay
4309 strings. */
4310 compute_stop_pos (it);
4311 xassert (it->face_id >= 0);
4312
4313 /* Save IT's settings. They are restored after all overlay
4314 strings have been processed. */
4315 xassert (it->sp == 0);
4316 push_it (it);
4317
4318 /* Set up IT to deliver display elements from the first overlay
4319 string. */
4320 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4321 it->string = it->overlay_strings[0];
4322 it->stop_charpos = 0;
4323 xassert (STRINGP (it->string));
4324 it->end_charpos = SCHARS (it->string);
4325 it->multibyte_p = STRING_MULTIBYTE (it->string);
4326 it->method = next_element_from_string;
4327 }
4328 else
4329 {
4330 it->string = Qnil;
4331 it->current.overlay_string_index = -1;
4332 it->method = next_element_from_buffer;
4333 }
4334
4335 CHECK_IT (it);
4336
4337 /* Value is non-zero if we found at least one overlay string. */
4338 return STRINGP (it->string);
4339 }
4340
4341
4342 \f
4343 /***********************************************************************
4344 Saving and restoring state
4345 ***********************************************************************/
4346
4347 /* Save current settings of IT on IT->stack. Called, for example,
4348 before setting up IT for an overlay string, to be able to restore
4349 IT's settings to what they were after the overlay string has been
4350 processed. */
4351
4352 static void
4353 push_it (it)
4354 struct it *it;
4355 {
4356 struct iterator_stack_entry *p;
4357
4358 xassert (it->sp < 2);
4359 p = it->stack + it->sp;
4360
4361 p->stop_charpos = it->stop_charpos;
4362 xassert (it->face_id >= 0);
4363 p->face_id = it->face_id;
4364 p->string = it->string;
4365 p->pos = it->current;
4366 p->end_charpos = it->end_charpos;
4367 p->string_nchars = it->string_nchars;
4368 p->area = it->area;
4369 p->multibyte_p = it->multibyte_p;
4370 p->slice = it->slice;
4371 p->space_width = it->space_width;
4372 p->font_height = it->font_height;
4373 p->voffset = it->voffset;
4374 p->string_from_display_prop_p = it->string_from_display_prop_p;
4375 p->display_ellipsis_p = 0;
4376 ++it->sp;
4377 }
4378
4379
4380 /* Restore IT's settings from IT->stack. Called, for example, when no
4381 more overlay strings must be processed, and we return to delivering
4382 display elements from a buffer, or when the end of a string from a
4383 `display' property is reached and we return to delivering display
4384 elements from an overlay string, or from a buffer. */
4385
4386 static void
4387 pop_it (it)
4388 struct it *it;
4389 {
4390 struct iterator_stack_entry *p;
4391
4392 xassert (it->sp > 0);
4393 --it->sp;
4394 p = it->stack + it->sp;
4395 it->stop_charpos = p->stop_charpos;
4396 it->face_id = p->face_id;
4397 it->string = p->string;
4398 it->current = p->pos;
4399 it->end_charpos = p->end_charpos;
4400 it->string_nchars = p->string_nchars;
4401 it->area = p->area;
4402 it->multibyte_p = p->multibyte_p;
4403 it->slice = p->slice;
4404 it->space_width = p->space_width;
4405 it->font_height = p->font_height;
4406 it->voffset = p->voffset;
4407 it->string_from_display_prop_p = p->string_from_display_prop_p;
4408 }
4409
4410
4411 \f
4412 /***********************************************************************
4413 Moving over lines
4414 ***********************************************************************/
4415
4416 /* Set IT's current position to the previous line start. */
4417
4418 static void
4419 back_to_previous_line_start (it)
4420 struct it *it;
4421 {
4422 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4423 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4424 }
4425
4426
4427 /* Move IT to the next line start.
4428
4429 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4430 we skipped over part of the text (as opposed to moving the iterator
4431 continuously over the text). Otherwise, don't change the value
4432 of *SKIPPED_P.
4433
4434 Newlines may come from buffer text, overlay strings, or strings
4435 displayed via the `display' property. That's the reason we can't
4436 simply use find_next_newline_no_quit.
4437
4438 Note that this function may not skip over invisible text that is so
4439 because of text properties and immediately follows a newline. If
4440 it would, function reseat_at_next_visible_line_start, when called
4441 from set_iterator_to_next, would effectively make invisible
4442 characters following a newline part of the wrong glyph row, which
4443 leads to wrong cursor motion. */
4444
4445 static int
4446 forward_to_next_line_start (it, skipped_p)
4447 struct it *it;
4448 int *skipped_p;
4449 {
4450 int old_selective, newline_found_p, n;
4451 const int MAX_NEWLINE_DISTANCE = 500;
4452
4453 /* If already on a newline, just consume it to avoid unintended
4454 skipping over invisible text below. */
4455 if (it->what == IT_CHARACTER
4456 && it->c == '\n'
4457 && CHARPOS (it->position) == IT_CHARPOS (*it))
4458 {
4459 set_iterator_to_next (it, 0);
4460 it->c = 0;
4461 return 1;
4462 }
4463
4464 /* Don't handle selective display in the following. It's (a)
4465 unnecessary because it's done by the caller, and (b) leads to an
4466 infinite recursion because next_element_from_ellipsis indirectly
4467 calls this function. */
4468 old_selective = it->selective;
4469 it->selective = 0;
4470
4471 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4472 from buffer text. */
4473 for (n = newline_found_p = 0;
4474 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4475 n += STRINGP (it->string) ? 0 : 1)
4476 {
4477 if (!get_next_display_element (it))
4478 return 0;
4479 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4480 set_iterator_to_next (it, 0);
4481 }
4482
4483 /* If we didn't find a newline near enough, see if we can use a
4484 short-cut. */
4485 if (!newline_found_p)
4486 {
4487 int start = IT_CHARPOS (*it);
4488 int limit = find_next_newline_no_quit (start, 1);
4489 Lisp_Object pos;
4490
4491 xassert (!STRINGP (it->string));
4492
4493 /* If there isn't any `display' property in sight, and no
4494 overlays, we can just use the position of the newline in
4495 buffer text. */
4496 if (it->stop_charpos >= limit
4497 || ((pos = Fnext_single_property_change (make_number (start),
4498 Qdisplay,
4499 Qnil, make_number (limit)),
4500 NILP (pos))
4501 && next_overlay_change (start) == ZV))
4502 {
4503 IT_CHARPOS (*it) = limit;
4504 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4505 *skipped_p = newline_found_p = 1;
4506 }
4507 else
4508 {
4509 while (get_next_display_element (it)
4510 && !newline_found_p)
4511 {
4512 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4513 set_iterator_to_next (it, 0);
4514 }
4515 }
4516 }
4517
4518 it->selective = old_selective;
4519 return newline_found_p;
4520 }
4521
4522
4523 /* Set IT's current position to the previous visible line start. Skip
4524 invisible text that is so either due to text properties or due to
4525 selective display. Caution: this does not change IT->current_x and
4526 IT->hpos. */
4527
4528 static void
4529 back_to_previous_visible_line_start (it)
4530 struct it *it;
4531 {
4532 int visible_p = 0;
4533
4534 /* Go back one newline if not on BEGV already. */
4535 if (IT_CHARPOS (*it) > BEGV)
4536 back_to_previous_line_start (it);
4537
4538 /* Move over lines that are invisible because of selective display
4539 or text properties. */
4540 while (IT_CHARPOS (*it) > BEGV
4541 && !visible_p)
4542 {
4543 visible_p = 1;
4544
4545 /* If selective > 0, then lines indented more than that values
4546 are invisible. */
4547 if (it->selective > 0
4548 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4549 (double) it->selective)) /* iftc */
4550 visible_p = 0;
4551 else
4552 {
4553 Lisp_Object prop;
4554
4555 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4556 Qinvisible, it->window);
4557 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4558 visible_p = 0;
4559 }
4560
4561 if (visible_p)
4562 {
4563 struct it it2 = *it;
4564
4565 if (handle_display_prop (&it2) == HANDLED_RETURN)
4566 visible_p = 0;
4567 }
4568
4569 /* Back one more newline if the current one is invisible. */
4570 if (!visible_p)
4571 back_to_previous_line_start (it);
4572 }
4573
4574 xassert (IT_CHARPOS (*it) >= BEGV);
4575 xassert (IT_CHARPOS (*it) == BEGV
4576 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4577 CHECK_IT (it);
4578 }
4579
4580
4581 /* Reseat iterator IT at the previous visible line start. Skip
4582 invisible text that is so either due to text properties or due to
4583 selective display. At the end, update IT's overlay information,
4584 face information etc. */
4585
4586 static void
4587 reseat_at_previous_visible_line_start (it)
4588 struct it *it;
4589 {
4590 back_to_previous_visible_line_start (it);
4591 reseat (it, it->current.pos, 1);
4592 CHECK_IT (it);
4593 }
4594
4595
4596 /* Reseat iterator IT on the next visible line start in the current
4597 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4598 preceding the line start. Skip over invisible text that is so
4599 because of selective display. Compute faces, overlays etc at the
4600 new position. Note that this function does not skip over text that
4601 is invisible because of text properties. */
4602
4603 static void
4604 reseat_at_next_visible_line_start (it, on_newline_p)
4605 struct it *it;
4606 int on_newline_p;
4607 {
4608 int newline_found_p, skipped_p = 0;
4609
4610 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4611
4612 /* Skip over lines that are invisible because they are indented
4613 more than the value of IT->selective. */
4614 if (it->selective > 0)
4615 while (IT_CHARPOS (*it) < ZV
4616 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4617 (double) it->selective)) /* iftc */
4618 {
4619 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4620 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4621 }
4622
4623 /* Position on the newline if that's what's requested. */
4624 if (on_newline_p && newline_found_p)
4625 {
4626 if (STRINGP (it->string))
4627 {
4628 if (IT_STRING_CHARPOS (*it) > 0)
4629 {
4630 --IT_STRING_CHARPOS (*it);
4631 --IT_STRING_BYTEPOS (*it);
4632 }
4633 }
4634 else if (IT_CHARPOS (*it) > BEGV)
4635 {
4636 --IT_CHARPOS (*it);
4637 --IT_BYTEPOS (*it);
4638 reseat (it, it->current.pos, 0);
4639 }
4640 }
4641 else if (skipped_p)
4642 reseat (it, it->current.pos, 0);
4643
4644 CHECK_IT (it);
4645 }
4646
4647
4648 \f
4649 /***********************************************************************
4650 Changing an iterator's position
4651 ***********************************************************************/
4652
4653 /* Change IT's current position to POS in current_buffer. If FORCE_P
4654 is non-zero, always check for text properties at the new position.
4655 Otherwise, text properties are only looked up if POS >=
4656 IT->check_charpos of a property. */
4657
4658 static void
4659 reseat (it, pos, force_p)
4660 struct it *it;
4661 struct text_pos pos;
4662 int force_p;
4663 {
4664 int original_pos = IT_CHARPOS (*it);
4665
4666 reseat_1 (it, pos, 0);
4667
4668 /* Determine where to check text properties. Avoid doing it
4669 where possible because text property lookup is very expensive. */
4670 if (force_p
4671 || CHARPOS (pos) > it->stop_charpos
4672 || CHARPOS (pos) < original_pos)
4673 handle_stop (it);
4674
4675 CHECK_IT (it);
4676 }
4677
4678
4679 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4680 IT->stop_pos to POS, also. */
4681
4682 static void
4683 reseat_1 (it, pos, set_stop_p)
4684 struct it *it;
4685 struct text_pos pos;
4686 int set_stop_p;
4687 {
4688 /* Don't call this function when scanning a C string. */
4689 xassert (it->s == NULL);
4690
4691 /* POS must be a reasonable value. */
4692 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4693
4694 it->current.pos = it->position = pos;
4695 XSETBUFFER (it->object, current_buffer);
4696 it->end_charpos = ZV;
4697 it->dpvec = NULL;
4698 it->current.dpvec_index = -1;
4699 it->current.overlay_string_index = -1;
4700 IT_STRING_CHARPOS (*it) = -1;
4701 IT_STRING_BYTEPOS (*it) = -1;
4702 it->string = Qnil;
4703 it->method = next_element_from_buffer;
4704 /* RMS: I added this to fix a bug in move_it_vertically_backward
4705 where it->area continued to relate to the starting point
4706 for the backward motion. Bug report from
4707 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4708 However, I am not sure whether reseat still does the right thing
4709 in general after this change. */
4710 it->area = TEXT_AREA;
4711 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4712 it->sp = 0;
4713 it->face_before_selective_p = 0;
4714
4715 if (set_stop_p)
4716 it->stop_charpos = CHARPOS (pos);
4717 }
4718
4719
4720 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4721 If S is non-null, it is a C string to iterate over. Otherwise,
4722 STRING gives a Lisp string to iterate over.
4723
4724 If PRECISION > 0, don't return more then PRECISION number of
4725 characters from the string.
4726
4727 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4728 characters have been returned. FIELD_WIDTH < 0 means an infinite
4729 field width.
4730
4731 MULTIBYTE = 0 means disable processing of multibyte characters,
4732 MULTIBYTE > 0 means enable it,
4733 MULTIBYTE < 0 means use IT->multibyte_p.
4734
4735 IT must be initialized via a prior call to init_iterator before
4736 calling this function. */
4737
4738 static void
4739 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4740 struct it *it;
4741 unsigned char *s;
4742 Lisp_Object string;
4743 int charpos;
4744 int precision, field_width, multibyte;
4745 {
4746 /* No region in strings. */
4747 it->region_beg_charpos = it->region_end_charpos = -1;
4748
4749 /* No text property checks performed by default, but see below. */
4750 it->stop_charpos = -1;
4751
4752 /* Set iterator position and end position. */
4753 bzero (&it->current, sizeof it->current);
4754 it->current.overlay_string_index = -1;
4755 it->current.dpvec_index = -1;
4756 xassert (charpos >= 0);
4757
4758 /* If STRING is specified, use its multibyteness, otherwise use the
4759 setting of MULTIBYTE, if specified. */
4760 if (multibyte >= 0)
4761 it->multibyte_p = multibyte > 0;
4762
4763 if (s == NULL)
4764 {
4765 xassert (STRINGP (string));
4766 it->string = string;
4767 it->s = NULL;
4768 it->end_charpos = it->string_nchars = SCHARS (string);
4769 it->method = next_element_from_string;
4770 it->current.string_pos = string_pos (charpos, string);
4771 }
4772 else
4773 {
4774 it->s = s;
4775 it->string = Qnil;
4776
4777 /* Note that we use IT->current.pos, not it->current.string_pos,
4778 for displaying C strings. */
4779 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4780 if (it->multibyte_p)
4781 {
4782 it->current.pos = c_string_pos (charpos, s, 1);
4783 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4784 }
4785 else
4786 {
4787 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4788 it->end_charpos = it->string_nchars = strlen (s);
4789 }
4790
4791 it->method = next_element_from_c_string;
4792 }
4793
4794 /* PRECISION > 0 means don't return more than PRECISION characters
4795 from the string. */
4796 if (precision > 0 && it->end_charpos - charpos > precision)
4797 it->end_charpos = it->string_nchars = charpos + precision;
4798
4799 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4800 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4801 FIELD_WIDTH < 0 means infinite field width. This is useful for
4802 padding with `-' at the end of a mode line. */
4803 if (field_width < 0)
4804 field_width = INFINITY;
4805 if (field_width > it->end_charpos - charpos)
4806 it->end_charpos = charpos + field_width;
4807
4808 /* Use the standard display table for displaying strings. */
4809 if (DISP_TABLE_P (Vstandard_display_table))
4810 it->dp = XCHAR_TABLE (Vstandard_display_table);
4811
4812 it->stop_charpos = charpos;
4813 CHECK_IT (it);
4814 }
4815
4816
4817 \f
4818 /***********************************************************************
4819 Iteration
4820 ***********************************************************************/
4821
4822 /* Load IT's display element fields with information about the next
4823 display element from the current position of IT. Value is zero if
4824 end of buffer (or C string) is reached. */
4825
4826 int
4827 get_next_display_element (it)
4828 struct it *it;
4829 {
4830 /* Non-zero means that we found a display element. Zero means that
4831 we hit the end of what we iterate over. Performance note: the
4832 function pointer `method' used here turns out to be faster than
4833 using a sequence of if-statements. */
4834 int success_p = (*it->method) (it);
4835
4836 if (it->what == IT_CHARACTER)
4837 {
4838 /* Map via display table or translate control characters.
4839 IT->c, IT->len etc. have been set to the next character by
4840 the function call above. If we have a display table, and it
4841 contains an entry for IT->c, translate it. Don't do this if
4842 IT->c itself comes from a display table, otherwise we could
4843 end up in an infinite recursion. (An alternative could be to
4844 count the recursion depth of this function and signal an
4845 error when a certain maximum depth is reached.) Is it worth
4846 it? */
4847 if (success_p && it->dpvec == NULL)
4848 {
4849 Lisp_Object dv;
4850
4851 if (it->dp
4852 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4853 VECTORP (dv)))
4854 {
4855 struct Lisp_Vector *v = XVECTOR (dv);
4856
4857 /* Return the first character from the display table
4858 entry, if not empty. If empty, don't display the
4859 current character. */
4860 if (v->size)
4861 {
4862 it->dpvec_char_len = it->len;
4863 it->dpvec = v->contents;
4864 it->dpend = v->contents + v->size;
4865 it->current.dpvec_index = 0;
4866 it->method = next_element_from_display_vector;
4867 success_p = get_next_display_element (it);
4868 }
4869 else
4870 {
4871 set_iterator_to_next (it, 0);
4872 success_p = get_next_display_element (it);
4873 }
4874 }
4875
4876 /* Translate control characters into `\003' or `^C' form.
4877 Control characters coming from a display table entry are
4878 currently not translated because we use IT->dpvec to hold
4879 the translation. This could easily be changed but I
4880 don't believe that it is worth doing.
4881
4882 If it->multibyte_p is nonzero, eight-bit characters and
4883 non-printable multibyte characters are also translated to
4884 octal form.
4885
4886 If it->multibyte_p is zero, eight-bit characters that
4887 don't have corresponding multibyte char code are also
4888 translated to octal form. */
4889 else if ((it->c < ' '
4890 && (it->area != TEXT_AREA
4891 || (it->c != '\n' && it->c != '\t')))
4892 || (it->multibyte_p
4893 ? ((it->c >= 127
4894 && it->len == 1)
4895 || !CHAR_PRINTABLE_P (it->c))
4896 : (it->c >= 127
4897 && it->c == unibyte_char_to_multibyte (it->c))))
4898 {
4899 /* IT->c is a control character which must be displayed
4900 either as '\003' or as `^C' where the '\\' and '^'
4901 can be defined in the display table. Fill
4902 IT->ctl_chars with glyphs for what we have to
4903 display. Then, set IT->dpvec to these glyphs. */
4904 GLYPH g;
4905
4906 if (it->c < 128 && it->ctl_arrow_p)
4907 {
4908 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4909 if (it->dp
4910 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4911 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4912 g = XINT (DISP_CTRL_GLYPH (it->dp));
4913 else
4914 g = FAST_MAKE_GLYPH ('^', 0);
4915 XSETINT (it->ctl_chars[0], g);
4916
4917 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4918 XSETINT (it->ctl_chars[1], g);
4919
4920 /* Set up IT->dpvec and return first character from it. */
4921 it->dpvec_char_len = it->len;
4922 it->dpvec = it->ctl_chars;
4923 it->dpend = it->dpvec + 2;
4924 it->current.dpvec_index = 0;
4925 it->method = next_element_from_display_vector;
4926 get_next_display_element (it);
4927 }
4928 else
4929 {
4930 unsigned char str[MAX_MULTIBYTE_LENGTH];
4931 int len;
4932 int i;
4933 GLYPH escape_glyph;
4934
4935 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4936 if (it->dp
4937 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4938 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4939 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4940 else
4941 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4942
4943 if (SINGLE_BYTE_CHAR_P (it->c))
4944 str[0] = it->c, len = 1;
4945 else
4946 {
4947 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4948 if (len < 0)
4949 {
4950 /* It's an invalid character, which
4951 shouldn't happen actually, but due to
4952 bugs it may happen. Let's print the char
4953 as is, there's not much meaningful we can
4954 do with it. */
4955 str[0] = it->c;
4956 str[1] = it->c >> 8;
4957 str[2] = it->c >> 16;
4958 str[3] = it->c >> 24;
4959 len = 4;
4960 }
4961 }
4962
4963 for (i = 0; i < len; i++)
4964 {
4965 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4966 /* Insert three more glyphs into IT->ctl_chars for
4967 the octal display of the character. */
4968 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4969 XSETINT (it->ctl_chars[i * 4 + 1], g);
4970 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4971 XSETINT (it->ctl_chars[i * 4 + 2], g);
4972 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4973 XSETINT (it->ctl_chars[i * 4 + 3], g);
4974 }
4975
4976 /* Set up IT->dpvec and return the first character
4977 from it. */
4978 it->dpvec_char_len = it->len;
4979 it->dpvec = it->ctl_chars;
4980 it->dpend = it->dpvec + len * 4;
4981 it->current.dpvec_index = 0;
4982 it->method = next_element_from_display_vector;
4983 get_next_display_element (it);
4984 }
4985 }
4986 }
4987
4988 /* Adjust face id for a multibyte character. There are no
4989 multibyte character in unibyte text. */
4990 if (it->multibyte_p
4991 && success_p
4992 && FRAME_WINDOW_P (it->f))
4993 {
4994 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4995 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4996 }
4997 }
4998
4999 /* Is this character the last one of a run of characters with
5000 box? If yes, set IT->end_of_box_run_p to 1. */
5001 if (it->face_box_p
5002 && it->s == NULL)
5003 {
5004 int face_id;
5005 struct face *face;
5006
5007 it->end_of_box_run_p
5008 = ((face_id = face_after_it_pos (it),
5009 face_id != it->face_id)
5010 && (face = FACE_FROM_ID (it->f, face_id),
5011 face->box == FACE_NO_BOX));
5012 }
5013
5014 /* Value is 0 if end of buffer or string reached. */
5015 return success_p;
5016 }
5017
5018
5019 /* Move IT to the next display element.
5020
5021 RESEAT_P non-zero means if called on a newline in buffer text,
5022 skip to the next visible line start.
5023
5024 Functions get_next_display_element and set_iterator_to_next are
5025 separate because I find this arrangement easier to handle than a
5026 get_next_display_element function that also increments IT's
5027 position. The way it is we can first look at an iterator's current
5028 display element, decide whether it fits on a line, and if it does,
5029 increment the iterator position. The other way around we probably
5030 would either need a flag indicating whether the iterator has to be
5031 incremented the next time, or we would have to implement a
5032 decrement position function which would not be easy to write. */
5033
5034 void
5035 set_iterator_to_next (it, reseat_p)
5036 struct it *it;
5037 int reseat_p;
5038 {
5039 /* Reset flags indicating start and end of a sequence of characters
5040 with box. Reset them at the start of this function because
5041 moving the iterator to a new position might set them. */
5042 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5043
5044 if (it->method == next_element_from_buffer)
5045 {
5046 /* The current display element of IT is a character from
5047 current_buffer. Advance in the buffer, and maybe skip over
5048 invisible lines that are so because of selective display. */
5049 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5050 reseat_at_next_visible_line_start (it, 0);
5051 else
5052 {
5053 xassert (it->len != 0);
5054 IT_BYTEPOS (*it) += it->len;
5055 IT_CHARPOS (*it) += 1;
5056 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5057 }
5058 }
5059 else if (it->method == next_element_from_composition)
5060 {
5061 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5062 if (STRINGP (it->string))
5063 {
5064 IT_STRING_BYTEPOS (*it) += it->len;
5065 IT_STRING_CHARPOS (*it) += it->cmp_len;
5066 it->method = next_element_from_string;
5067 goto consider_string_end;
5068 }
5069 else
5070 {
5071 IT_BYTEPOS (*it) += it->len;
5072 IT_CHARPOS (*it) += it->cmp_len;
5073 it->method = next_element_from_buffer;
5074 }
5075 }
5076 else if (it->method == next_element_from_c_string)
5077 {
5078 /* Current display element of IT is from a C string. */
5079 IT_BYTEPOS (*it) += it->len;
5080 IT_CHARPOS (*it) += 1;
5081 }
5082 else if (it->method == next_element_from_display_vector)
5083 {
5084 /* Current display element of IT is from a display table entry.
5085 Advance in the display table definition. Reset it to null if
5086 end reached, and continue with characters from buffers/
5087 strings. */
5088 ++it->current.dpvec_index;
5089
5090 /* Restore face of the iterator to what they were before the
5091 display vector entry (these entries may contain faces). */
5092 it->face_id = it->saved_face_id;
5093
5094 if (it->dpvec + it->current.dpvec_index == it->dpend)
5095 {
5096 if (it->s)
5097 it->method = next_element_from_c_string;
5098 else if (STRINGP (it->string))
5099 it->method = next_element_from_string;
5100 else
5101 it->method = next_element_from_buffer;
5102
5103 it->dpvec = NULL;
5104 it->current.dpvec_index = -1;
5105
5106 /* Skip over characters which were displayed via IT->dpvec. */
5107 if (it->dpvec_char_len < 0)
5108 reseat_at_next_visible_line_start (it, 1);
5109 else if (it->dpvec_char_len > 0)
5110 {
5111 it->len = it->dpvec_char_len;
5112 set_iterator_to_next (it, reseat_p);
5113 }
5114 }
5115 }
5116 else if (it->method == next_element_from_string)
5117 {
5118 /* Current display element is a character from a Lisp string. */
5119 xassert (it->s == NULL && STRINGP (it->string));
5120 IT_STRING_BYTEPOS (*it) += it->len;
5121 IT_STRING_CHARPOS (*it) += 1;
5122
5123 consider_string_end:
5124
5125 if (it->current.overlay_string_index >= 0)
5126 {
5127 /* IT->string is an overlay string. Advance to the
5128 next, if there is one. */
5129 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5130 next_overlay_string (it);
5131 }
5132 else
5133 {
5134 /* IT->string is not an overlay string. If we reached
5135 its end, and there is something on IT->stack, proceed
5136 with what is on the stack. This can be either another
5137 string, this time an overlay string, or a buffer. */
5138 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5139 && it->sp > 0)
5140 {
5141 pop_it (it);
5142 if (!STRINGP (it->string))
5143 it->method = next_element_from_buffer;
5144 else
5145 goto consider_string_end;
5146 }
5147 }
5148 }
5149 else if (it->method == next_element_from_image
5150 || it->method == next_element_from_stretch)
5151 {
5152 /* The position etc with which we have to proceed are on
5153 the stack. The position may be at the end of a string,
5154 if the `display' property takes up the whole string. */
5155 pop_it (it);
5156 it->image_id = 0;
5157 if (STRINGP (it->string))
5158 {
5159 it->method = next_element_from_string;
5160 goto consider_string_end;
5161 }
5162 else
5163 it->method = next_element_from_buffer;
5164 }
5165 else
5166 /* There are no other methods defined, so this should be a bug. */
5167 abort ();
5168
5169 xassert (it->method != next_element_from_string
5170 || (STRINGP (it->string)
5171 && IT_STRING_CHARPOS (*it) >= 0));
5172 }
5173
5174
5175 /* Load IT's display element fields with information about the next
5176 display element which comes from a display table entry or from the
5177 result of translating a control character to one of the forms `^C'
5178 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5179
5180 static int
5181 next_element_from_display_vector (it)
5182 struct it *it;
5183 {
5184 /* Precondition. */
5185 xassert (it->dpvec && it->current.dpvec_index >= 0);
5186
5187 /* Remember the current face id in case glyphs specify faces.
5188 IT's face is restored in set_iterator_to_next. */
5189 it->saved_face_id = it->face_id;
5190
5191 if (INTEGERP (*it->dpvec)
5192 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5193 {
5194 int lface_id;
5195 GLYPH g;
5196
5197 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5198 it->c = FAST_GLYPH_CHAR (g);
5199 it->len = CHAR_BYTES (it->c);
5200
5201 /* The entry may contain a face id to use. Such a face id is
5202 the id of a Lisp face, not a realized face. A face id of
5203 zero means no face is specified. */
5204 lface_id = FAST_GLYPH_FACE (g);
5205 if (lface_id)
5206 {
5207 /* The function returns -1 if lface_id is invalid. */
5208 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5209 if (face_id >= 0)
5210 it->face_id = face_id;
5211 }
5212 }
5213 else
5214 /* Display table entry is invalid. Return a space. */
5215 it->c = ' ', it->len = 1;
5216
5217 /* Don't change position and object of the iterator here. They are
5218 still the values of the character that had this display table
5219 entry or was translated, and that's what we want. */
5220 it->what = IT_CHARACTER;
5221 return 1;
5222 }
5223
5224
5225 /* Load IT with the next display element from Lisp string IT->string.
5226 IT->current.string_pos is the current position within the string.
5227 If IT->current.overlay_string_index >= 0, the Lisp string is an
5228 overlay string. */
5229
5230 static int
5231 next_element_from_string (it)
5232 struct it *it;
5233 {
5234 struct text_pos position;
5235
5236 xassert (STRINGP (it->string));
5237 xassert (IT_STRING_CHARPOS (*it) >= 0);
5238 position = it->current.string_pos;
5239
5240 /* Time to check for invisible text? */
5241 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5242 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5243 {
5244 handle_stop (it);
5245
5246 /* Since a handler may have changed IT->method, we must
5247 recurse here. */
5248 return get_next_display_element (it);
5249 }
5250
5251 if (it->current.overlay_string_index >= 0)
5252 {
5253 /* Get the next character from an overlay string. In overlay
5254 strings, There is no field width or padding with spaces to
5255 do. */
5256 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5257 {
5258 it->what = IT_EOB;
5259 return 0;
5260 }
5261 else if (STRING_MULTIBYTE (it->string))
5262 {
5263 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5264 const unsigned char *s = (SDATA (it->string)
5265 + IT_STRING_BYTEPOS (*it));
5266 it->c = string_char_and_length (s, remaining, &it->len);
5267 }
5268 else
5269 {
5270 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5271 it->len = 1;
5272 }
5273 }
5274 else
5275 {
5276 /* Get the next character from a Lisp string that is not an
5277 overlay string. Such strings come from the mode line, for
5278 example. We may have to pad with spaces, or truncate the
5279 string. See also next_element_from_c_string. */
5280 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5281 {
5282 it->what = IT_EOB;
5283 return 0;
5284 }
5285 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5286 {
5287 /* Pad with spaces. */
5288 it->c = ' ', it->len = 1;
5289 CHARPOS (position) = BYTEPOS (position) = -1;
5290 }
5291 else if (STRING_MULTIBYTE (it->string))
5292 {
5293 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5294 const unsigned char *s = (SDATA (it->string)
5295 + IT_STRING_BYTEPOS (*it));
5296 it->c = string_char_and_length (s, maxlen, &it->len);
5297 }
5298 else
5299 {
5300 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5301 it->len = 1;
5302 }
5303 }
5304
5305 /* Record what we have and where it came from. Note that we store a
5306 buffer position in IT->position although it could arguably be a
5307 string position. */
5308 it->what = IT_CHARACTER;
5309 it->object = it->string;
5310 it->position = position;
5311 return 1;
5312 }
5313
5314
5315 /* Load IT with next display element from C string IT->s.
5316 IT->string_nchars is the maximum number of characters to return
5317 from the string. IT->end_charpos may be greater than
5318 IT->string_nchars when this function is called, in which case we
5319 may have to return padding spaces. Value is zero if end of string
5320 reached, including padding spaces. */
5321
5322 static int
5323 next_element_from_c_string (it)
5324 struct it *it;
5325 {
5326 int success_p = 1;
5327
5328 xassert (it->s);
5329 it->what = IT_CHARACTER;
5330 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5331 it->object = Qnil;
5332
5333 /* IT's position can be greater IT->string_nchars in case a field
5334 width or precision has been specified when the iterator was
5335 initialized. */
5336 if (IT_CHARPOS (*it) >= it->end_charpos)
5337 {
5338 /* End of the game. */
5339 it->what = IT_EOB;
5340 success_p = 0;
5341 }
5342 else if (IT_CHARPOS (*it) >= it->string_nchars)
5343 {
5344 /* Pad with spaces. */
5345 it->c = ' ', it->len = 1;
5346 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5347 }
5348 else if (it->multibyte_p)
5349 {
5350 /* Implementation note: The calls to strlen apparently aren't a
5351 performance problem because there is no noticeable performance
5352 difference between Emacs running in unibyte or multibyte mode. */
5353 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5354 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5355 maxlen, &it->len);
5356 }
5357 else
5358 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5359
5360 return success_p;
5361 }
5362
5363
5364 /* Set up IT to return characters from an ellipsis, if appropriate.
5365 The definition of the ellipsis glyphs may come from a display table
5366 entry. This function Fills IT with the first glyph from the
5367 ellipsis if an ellipsis is to be displayed. */
5368
5369 static int
5370 next_element_from_ellipsis (it)
5371 struct it *it;
5372 {
5373 if (it->selective_display_ellipsis_p)
5374 {
5375 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5376 {
5377 /* Use the display table definition for `...'. Invalid glyphs
5378 will be handled by the method returning elements from dpvec. */
5379 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5380 it->dpvec_char_len = it->len;
5381 it->dpvec = v->contents;
5382 it->dpend = v->contents + v->size;
5383 it->current.dpvec_index = 0;
5384 it->method = next_element_from_display_vector;
5385 }
5386 else
5387 {
5388 /* Use default `...' which is stored in default_invis_vector. */
5389 it->dpvec_char_len = it->len;
5390 it->dpvec = default_invis_vector;
5391 it->dpend = default_invis_vector + 3;
5392 it->current.dpvec_index = 0;
5393 it->method = next_element_from_display_vector;
5394 }
5395 }
5396 else
5397 {
5398 /* The face at the current position may be different from the
5399 face we find after the invisible text. Remember what it
5400 was in IT->saved_face_id, and signal that it's there by
5401 setting face_before_selective_p. */
5402 it->saved_face_id = it->face_id;
5403 it->method = next_element_from_buffer;
5404 reseat_at_next_visible_line_start (it, 1);
5405 it->face_before_selective_p = 1;
5406 }
5407
5408 return get_next_display_element (it);
5409 }
5410
5411
5412 /* Deliver an image display element. The iterator IT is already
5413 filled with image information (done in handle_display_prop). Value
5414 is always 1. */
5415
5416
5417 static int
5418 next_element_from_image (it)
5419 struct it *it;
5420 {
5421 it->what = IT_IMAGE;
5422 return 1;
5423 }
5424
5425
5426 /* Fill iterator IT with next display element from a stretch glyph
5427 property. IT->object is the value of the text property. Value is
5428 always 1. */
5429
5430 static int
5431 next_element_from_stretch (it)
5432 struct it *it;
5433 {
5434 it->what = IT_STRETCH;
5435 return 1;
5436 }
5437
5438
5439 /* Load IT with the next display element from current_buffer. Value
5440 is zero if end of buffer reached. IT->stop_charpos is the next
5441 position at which to stop and check for text properties or buffer
5442 end. */
5443
5444 static int
5445 next_element_from_buffer (it)
5446 struct it *it;
5447 {
5448 int success_p = 1;
5449
5450 /* Check this assumption, otherwise, we would never enter the
5451 if-statement, below. */
5452 xassert (IT_CHARPOS (*it) >= BEGV
5453 && IT_CHARPOS (*it) <= it->stop_charpos);
5454
5455 if (IT_CHARPOS (*it) >= it->stop_charpos)
5456 {
5457 if (IT_CHARPOS (*it) >= it->end_charpos)
5458 {
5459 int overlay_strings_follow_p;
5460
5461 /* End of the game, except when overlay strings follow that
5462 haven't been returned yet. */
5463 if (it->overlay_strings_at_end_processed_p)
5464 overlay_strings_follow_p = 0;
5465 else
5466 {
5467 it->overlay_strings_at_end_processed_p = 1;
5468 overlay_strings_follow_p = get_overlay_strings (it, 0);
5469 }
5470
5471 if (overlay_strings_follow_p)
5472 success_p = get_next_display_element (it);
5473 else
5474 {
5475 it->what = IT_EOB;
5476 it->position = it->current.pos;
5477 success_p = 0;
5478 }
5479 }
5480 else
5481 {
5482 handle_stop (it);
5483 return get_next_display_element (it);
5484 }
5485 }
5486 else
5487 {
5488 /* No face changes, overlays etc. in sight, so just return a
5489 character from current_buffer. */
5490 unsigned char *p;
5491
5492 /* Maybe run the redisplay end trigger hook. Performance note:
5493 This doesn't seem to cost measurable time. */
5494 if (it->redisplay_end_trigger_charpos
5495 && it->glyph_row
5496 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5497 run_redisplay_end_trigger_hook (it);
5498
5499 /* Get the next character, maybe multibyte. */
5500 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5501 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5502 {
5503 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5504 - IT_BYTEPOS (*it));
5505 it->c = string_char_and_length (p, maxlen, &it->len);
5506 }
5507 else
5508 it->c = *p, it->len = 1;
5509
5510 /* Record what we have and where it came from. */
5511 it->what = IT_CHARACTER;;
5512 it->object = it->w->buffer;
5513 it->position = it->current.pos;
5514
5515 /* Normally we return the character found above, except when we
5516 really want to return an ellipsis for selective display. */
5517 if (it->selective)
5518 {
5519 if (it->c == '\n')
5520 {
5521 /* A value of selective > 0 means hide lines indented more
5522 than that number of columns. */
5523 if (it->selective > 0
5524 && IT_CHARPOS (*it) + 1 < ZV
5525 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5526 IT_BYTEPOS (*it) + 1,
5527 (double) it->selective)) /* iftc */
5528 {
5529 success_p = next_element_from_ellipsis (it);
5530 it->dpvec_char_len = -1;
5531 }
5532 }
5533 else if (it->c == '\r' && it->selective == -1)
5534 {
5535 /* A value of selective == -1 means that everything from the
5536 CR to the end of the line is invisible, with maybe an
5537 ellipsis displayed for it. */
5538 success_p = next_element_from_ellipsis (it);
5539 it->dpvec_char_len = -1;
5540 }
5541 }
5542 }
5543
5544 /* Value is zero if end of buffer reached. */
5545 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5546 return success_p;
5547 }
5548
5549
5550 /* Run the redisplay end trigger hook for IT. */
5551
5552 static void
5553 run_redisplay_end_trigger_hook (it)
5554 struct it *it;
5555 {
5556 Lisp_Object args[3];
5557
5558 /* IT->glyph_row should be non-null, i.e. we should be actually
5559 displaying something, or otherwise we should not run the hook. */
5560 xassert (it->glyph_row);
5561
5562 /* Set up hook arguments. */
5563 args[0] = Qredisplay_end_trigger_functions;
5564 args[1] = it->window;
5565 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5566 it->redisplay_end_trigger_charpos = 0;
5567
5568 /* Since we are *trying* to run these functions, don't try to run
5569 them again, even if they get an error. */
5570 it->w->redisplay_end_trigger = Qnil;
5571 Frun_hook_with_args (3, args);
5572
5573 /* Notice if it changed the face of the character we are on. */
5574 handle_face_prop (it);
5575 }
5576
5577
5578 /* Deliver a composition display element. The iterator IT is already
5579 filled with composition information (done in
5580 handle_composition_prop). Value is always 1. */
5581
5582 static int
5583 next_element_from_composition (it)
5584 struct it *it;
5585 {
5586 it->what = IT_COMPOSITION;
5587 it->position = (STRINGP (it->string)
5588 ? it->current.string_pos
5589 : it->current.pos);
5590 return 1;
5591 }
5592
5593
5594 \f
5595 /***********************************************************************
5596 Moving an iterator without producing glyphs
5597 ***********************************************************************/
5598
5599 /* Move iterator IT to a specified buffer or X position within one
5600 line on the display without producing glyphs.
5601
5602 OP should be a bit mask including some or all of these bits:
5603 MOVE_TO_X: Stop on reaching x-position TO_X.
5604 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5605 Regardless of OP's value, stop in reaching the end of the display line.
5606
5607 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5608 This means, in particular, that TO_X includes window's horizontal
5609 scroll amount.
5610
5611 The return value has several possible values that
5612 say what condition caused the scan to stop:
5613
5614 MOVE_POS_MATCH_OR_ZV
5615 - when TO_POS or ZV was reached.
5616
5617 MOVE_X_REACHED
5618 -when TO_X was reached before TO_POS or ZV were reached.
5619
5620 MOVE_LINE_CONTINUED
5621 - when we reached the end of the display area and the line must
5622 be continued.
5623
5624 MOVE_LINE_TRUNCATED
5625 - when we reached the end of the display area and the line is
5626 truncated.
5627
5628 MOVE_NEWLINE_OR_CR
5629 - when we stopped at a line end, i.e. a newline or a CR and selective
5630 display is on. */
5631
5632 static enum move_it_result
5633 move_it_in_display_line_to (it, to_charpos, to_x, op)
5634 struct it *it;
5635 int to_charpos, to_x, op;
5636 {
5637 enum move_it_result result = MOVE_UNDEFINED;
5638 struct glyph_row *saved_glyph_row;
5639
5640 /* Don't produce glyphs in produce_glyphs. */
5641 saved_glyph_row = it->glyph_row;
5642 it->glyph_row = NULL;
5643
5644 #define BUFFER_POS_REACHED_P() \
5645 ((op & MOVE_TO_POS) != 0 \
5646 && BUFFERP (it->object) \
5647 && IT_CHARPOS (*it) >= to_charpos)
5648
5649 while (1)
5650 {
5651 int x, i, ascent = 0, descent = 0;
5652
5653 /* Stop when ZV reached.
5654 We used to stop here when TO_CHARPOS reached as well, but that is
5655 too soon if this glyph does not fit on this line. So we handle it
5656 explicitly below. */
5657 if (!get_next_display_element (it)
5658 || (it->truncate_lines_p
5659 && BUFFER_POS_REACHED_P ()))
5660 {
5661 result = MOVE_POS_MATCH_OR_ZV;
5662 break;
5663 }
5664
5665 /* The call to produce_glyphs will get the metrics of the
5666 display element IT is loaded with. We record in x the
5667 x-position before this display element in case it does not
5668 fit on the line. */
5669 x = it->current_x;
5670
5671 /* Remember the line height so far in case the next element doesn't
5672 fit on the line. */
5673 if (!it->truncate_lines_p)
5674 {
5675 ascent = it->max_ascent;
5676 descent = it->max_descent;
5677 }
5678
5679 PRODUCE_GLYPHS (it);
5680
5681 if (it->area != TEXT_AREA)
5682 {
5683 set_iterator_to_next (it, 1);
5684 continue;
5685 }
5686
5687 /* The number of glyphs we get back in IT->nglyphs will normally
5688 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5689 character on a terminal frame, or (iii) a line end. For the
5690 second case, IT->nglyphs - 1 padding glyphs will be present
5691 (on X frames, there is only one glyph produced for a
5692 composite character.
5693
5694 The behavior implemented below means, for continuation lines,
5695 that as many spaces of a TAB as fit on the current line are
5696 displayed there. For terminal frames, as many glyphs of a
5697 multi-glyph character are displayed in the current line, too.
5698 This is what the old redisplay code did, and we keep it that
5699 way. Under X, the whole shape of a complex character must
5700 fit on the line or it will be completely displayed in the
5701 next line.
5702
5703 Note that both for tabs and padding glyphs, all glyphs have
5704 the same width. */
5705 if (it->nglyphs)
5706 {
5707 /* More than one glyph or glyph doesn't fit on line. All
5708 glyphs have the same width. */
5709 int single_glyph_width = it->pixel_width / it->nglyphs;
5710 int new_x;
5711
5712 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5713 {
5714 new_x = x + single_glyph_width;
5715
5716 /* We want to leave anything reaching TO_X to the caller. */
5717 if ((op & MOVE_TO_X) && new_x > to_x)
5718 {
5719 if (BUFFER_POS_REACHED_P ())
5720 goto buffer_pos_reached;
5721 it->current_x = x;
5722 result = MOVE_X_REACHED;
5723 break;
5724 }
5725 else if (/* Lines are continued. */
5726 !it->truncate_lines_p
5727 && (/* And glyph doesn't fit on the line. */
5728 new_x > it->last_visible_x
5729 /* Or it fits exactly and we're on a window
5730 system frame. */
5731 || (new_x == it->last_visible_x
5732 && FRAME_WINDOW_P (it->f))))
5733 {
5734 if (/* IT->hpos == 0 means the very first glyph
5735 doesn't fit on the line, e.g. a wide image. */
5736 it->hpos == 0
5737 || (new_x == it->last_visible_x
5738 && FRAME_WINDOW_P (it->f)))
5739 {
5740 ++it->hpos;
5741 it->current_x = new_x;
5742 if (i == it->nglyphs - 1)
5743 {
5744 set_iterator_to_next (it, 1);
5745 #ifdef HAVE_WINDOW_SYSTEM
5746 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5747 {
5748 if (!get_next_display_element (it))
5749 {
5750 result = MOVE_POS_MATCH_OR_ZV;
5751 break;
5752 }
5753 if (BUFFER_POS_REACHED_P ())
5754 {
5755 if (ITERATOR_AT_END_OF_LINE_P (it))
5756 result = MOVE_POS_MATCH_OR_ZV;
5757 else
5758 result = MOVE_LINE_CONTINUED;
5759 break;
5760 }
5761 if (ITERATOR_AT_END_OF_LINE_P (it))
5762 {
5763 result = MOVE_NEWLINE_OR_CR;
5764 break;
5765 }
5766 }
5767 #endif /* HAVE_WINDOW_SYSTEM */
5768 }
5769 }
5770 else
5771 {
5772 it->current_x = x;
5773 it->max_ascent = ascent;
5774 it->max_descent = descent;
5775 }
5776
5777 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5778 IT_CHARPOS (*it)));
5779 result = MOVE_LINE_CONTINUED;
5780 break;
5781 }
5782 else if (BUFFER_POS_REACHED_P ())
5783 goto buffer_pos_reached;
5784 else if (new_x > it->first_visible_x)
5785 {
5786 /* Glyph is visible. Increment number of glyphs that
5787 would be displayed. */
5788 ++it->hpos;
5789 }
5790 else
5791 {
5792 /* Glyph is completely off the left margin of the display
5793 area. Nothing to do. */
5794 }
5795 }
5796
5797 if (result != MOVE_UNDEFINED)
5798 break;
5799 }
5800 else if (BUFFER_POS_REACHED_P ())
5801 {
5802 buffer_pos_reached:
5803 it->current_x = x;
5804 it->max_ascent = ascent;
5805 it->max_descent = descent;
5806 result = MOVE_POS_MATCH_OR_ZV;
5807 break;
5808 }
5809 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5810 {
5811 /* Stop when TO_X specified and reached. This check is
5812 necessary here because of lines consisting of a line end,
5813 only. The line end will not produce any glyphs and we
5814 would never get MOVE_X_REACHED. */
5815 xassert (it->nglyphs == 0);
5816 result = MOVE_X_REACHED;
5817 break;
5818 }
5819
5820 /* Is this a line end? If yes, we're done. */
5821 if (ITERATOR_AT_END_OF_LINE_P (it))
5822 {
5823 result = MOVE_NEWLINE_OR_CR;
5824 break;
5825 }
5826
5827 /* The current display element has been consumed. Advance
5828 to the next. */
5829 set_iterator_to_next (it, 1);
5830
5831 /* Stop if lines are truncated and IT's current x-position is
5832 past the right edge of the window now. */
5833 if (it->truncate_lines_p
5834 && it->current_x >= it->last_visible_x)
5835 {
5836 #ifdef HAVE_WINDOW_SYSTEM
5837 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5838 {
5839 if (!get_next_display_element (it)
5840 || BUFFER_POS_REACHED_P ())
5841 {
5842 result = MOVE_POS_MATCH_OR_ZV;
5843 break;
5844 }
5845 if (ITERATOR_AT_END_OF_LINE_P (it))
5846 {
5847 result = MOVE_NEWLINE_OR_CR;
5848 break;
5849 }
5850 }
5851 #endif /* HAVE_WINDOW_SYSTEM */
5852 result = MOVE_LINE_TRUNCATED;
5853 break;
5854 }
5855 }
5856
5857 #undef BUFFER_POS_REACHED_P
5858
5859 /* Restore the iterator settings altered at the beginning of this
5860 function. */
5861 it->glyph_row = saved_glyph_row;
5862 return result;
5863 }
5864
5865
5866 /* Move IT forward until it satisfies one or more of the criteria in
5867 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5868
5869 OP is a bit-mask that specifies where to stop, and in particular,
5870 which of those four position arguments makes a difference. See the
5871 description of enum move_operation_enum.
5872
5873 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5874 screen line, this function will set IT to the next position >
5875 TO_CHARPOS. */
5876
5877 void
5878 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5879 struct it *it;
5880 int to_charpos, to_x, to_y, to_vpos;
5881 int op;
5882 {
5883 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5884 int line_height;
5885 int reached = 0;
5886
5887 for (;;)
5888 {
5889 if (op & MOVE_TO_VPOS)
5890 {
5891 /* If no TO_CHARPOS and no TO_X specified, stop at the
5892 start of the line TO_VPOS. */
5893 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5894 {
5895 if (it->vpos == to_vpos)
5896 {
5897 reached = 1;
5898 break;
5899 }
5900 else
5901 skip = move_it_in_display_line_to (it, -1, -1, 0);
5902 }
5903 else
5904 {
5905 /* TO_VPOS >= 0 means stop at TO_X in the line at
5906 TO_VPOS, or at TO_POS, whichever comes first. */
5907 if (it->vpos == to_vpos)
5908 {
5909 reached = 2;
5910 break;
5911 }
5912
5913 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5914
5915 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5916 {
5917 reached = 3;
5918 break;
5919 }
5920 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5921 {
5922 /* We have reached TO_X but not in the line we want. */
5923 skip = move_it_in_display_line_to (it, to_charpos,
5924 -1, MOVE_TO_POS);
5925 if (skip == MOVE_POS_MATCH_OR_ZV)
5926 {
5927 reached = 4;
5928 break;
5929 }
5930 }
5931 }
5932 }
5933 else if (op & MOVE_TO_Y)
5934 {
5935 struct it it_backup;
5936
5937 /* TO_Y specified means stop at TO_X in the line containing
5938 TO_Y---or at TO_CHARPOS if this is reached first. The
5939 problem is that we can't really tell whether the line
5940 contains TO_Y before we have completely scanned it, and
5941 this may skip past TO_X. What we do is to first scan to
5942 TO_X.
5943
5944 If TO_X is not specified, use a TO_X of zero. The reason
5945 is to make the outcome of this function more predictable.
5946 If we didn't use TO_X == 0, we would stop at the end of
5947 the line which is probably not what a caller would expect
5948 to happen. */
5949 skip = move_it_in_display_line_to (it, to_charpos,
5950 ((op & MOVE_TO_X)
5951 ? to_x : 0),
5952 (MOVE_TO_X
5953 | (op & MOVE_TO_POS)));
5954
5955 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5956 if (skip == MOVE_POS_MATCH_OR_ZV)
5957 {
5958 reached = 5;
5959 break;
5960 }
5961
5962 /* If TO_X was reached, we would like to know whether TO_Y
5963 is in the line. This can only be said if we know the
5964 total line height which requires us to scan the rest of
5965 the line. */
5966 if (skip == MOVE_X_REACHED)
5967 {
5968 it_backup = *it;
5969 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5970 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5971 op & MOVE_TO_POS);
5972 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5973 }
5974
5975 /* Now, decide whether TO_Y is in this line. */
5976 line_height = it->max_ascent + it->max_descent;
5977 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5978
5979 if (to_y >= it->current_y
5980 && to_y < it->current_y + line_height)
5981 {
5982 if (skip == MOVE_X_REACHED)
5983 /* If TO_Y is in this line and TO_X was reached above,
5984 we scanned too far. We have to restore IT's settings
5985 to the ones before skipping. */
5986 *it = it_backup;
5987 reached = 6;
5988 }
5989 else if (skip == MOVE_X_REACHED)
5990 {
5991 skip = skip2;
5992 if (skip == MOVE_POS_MATCH_OR_ZV)
5993 reached = 7;
5994 }
5995
5996 if (reached)
5997 break;
5998 }
5999 else
6000 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6001
6002 switch (skip)
6003 {
6004 case MOVE_POS_MATCH_OR_ZV:
6005 reached = 8;
6006 goto out;
6007
6008 case MOVE_NEWLINE_OR_CR:
6009 set_iterator_to_next (it, 1);
6010 it->continuation_lines_width = 0;
6011 break;
6012
6013 case MOVE_LINE_TRUNCATED:
6014 it->continuation_lines_width = 0;
6015 reseat_at_next_visible_line_start (it, 0);
6016 if ((op & MOVE_TO_POS) != 0
6017 && IT_CHARPOS (*it) > to_charpos)
6018 {
6019 reached = 9;
6020 goto out;
6021 }
6022 break;
6023
6024 case MOVE_LINE_CONTINUED:
6025 it->continuation_lines_width += it->current_x;
6026 break;
6027
6028 default:
6029 abort ();
6030 }
6031
6032 /* Reset/increment for the next run. */
6033 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6034 it->current_x = it->hpos = 0;
6035 it->current_y += it->max_ascent + it->max_descent;
6036 ++it->vpos;
6037 last_height = it->max_ascent + it->max_descent;
6038 last_max_ascent = it->max_ascent;
6039 it->max_ascent = it->max_descent = 0;
6040 }
6041
6042 out:
6043
6044 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6045 }
6046
6047
6048 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6049
6050 If DY > 0, move IT backward at least that many pixels. DY = 0
6051 means move IT backward to the preceding line start or BEGV. This
6052 function may move over more than DY pixels if IT->current_y - DY
6053 ends up in the middle of a line; in this case IT->current_y will be
6054 set to the top of the line moved to. */
6055
6056 void
6057 move_it_vertically_backward (it, dy)
6058 struct it *it;
6059 int dy;
6060 {
6061 int nlines, h;
6062 struct it it2, it3;
6063 int start_pos = IT_CHARPOS (*it);
6064
6065 xassert (dy >= 0);
6066
6067 /* Estimate how many newlines we must move back. */
6068 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6069
6070 /* Set the iterator's position that many lines back. */
6071 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6072 back_to_previous_visible_line_start (it);
6073
6074 /* Reseat the iterator here. When moving backward, we don't want
6075 reseat to skip forward over invisible text, set up the iterator
6076 to deliver from overlay strings at the new position etc. So,
6077 use reseat_1 here. */
6078 reseat_1 (it, it->current.pos, 1);
6079
6080 /* We are now surely at a line start. */
6081 it->current_x = it->hpos = 0;
6082 it->continuation_lines_width = 0;
6083
6084 /* Move forward and see what y-distance we moved. First move to the
6085 start of the next line so that we get its height. We need this
6086 height to be able to tell whether we reached the specified
6087 y-distance. */
6088 it2 = *it;
6089 it2.max_ascent = it2.max_descent = 0;
6090 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6091 MOVE_TO_POS | MOVE_TO_VPOS);
6092 xassert (IT_CHARPOS (*it) >= BEGV);
6093 it3 = it2;
6094
6095 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6096 xassert (IT_CHARPOS (*it) >= BEGV);
6097 /* H is the actual vertical distance from the position in *IT
6098 and the starting position. */
6099 h = it2.current_y - it->current_y;
6100 /* NLINES is the distance in number of lines. */
6101 nlines = it2.vpos - it->vpos;
6102
6103 /* Correct IT's y and vpos position
6104 so that they are relative to the starting point. */
6105 it->vpos -= nlines;
6106 it->current_y -= h;
6107
6108 if (dy == 0)
6109 {
6110 /* DY == 0 means move to the start of the screen line. The
6111 value of nlines is > 0 if continuation lines were involved. */
6112 if (nlines > 0)
6113 move_it_by_lines (it, nlines, 1);
6114 xassert (IT_CHARPOS (*it) <= start_pos);
6115 }
6116 else
6117 {
6118 /* The y-position we try to reach, relative to *IT.
6119 Note that H has been subtracted in front of the if-statement. */
6120 int target_y = it->current_y + h - dy;
6121 int y0 = it3.current_y;
6122 int y1 = line_bottom_y (&it3);
6123 int line_height = y1 - y0;
6124
6125 /* If we did not reach target_y, try to move further backward if
6126 we can. If we moved too far backward, try to move forward. */
6127 if (target_y < it->current_y
6128 /* This is heuristic. In a window that's 3 lines high, with
6129 a line height of 13 pixels each, recentering with point
6130 on the bottom line will try to move -39/2 = 19 pixels
6131 backward. Try to avoid moving into the first line. */
6132 && it->current_y - target_y > line_height / 3 * 2
6133 && IT_CHARPOS (*it) > BEGV)
6134 {
6135 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6136 target_y - it->current_y));
6137 move_it_vertically (it, target_y - it->current_y);
6138 xassert (IT_CHARPOS (*it) >= BEGV);
6139 }
6140 else if (target_y >= it->current_y + line_height
6141 && IT_CHARPOS (*it) < ZV)
6142 {
6143 /* Should move forward by at least one line, maybe more.
6144
6145 Note: Calling move_it_by_lines can be expensive on
6146 terminal frames, where compute_motion is used (via
6147 vmotion) to do the job, when there are very long lines
6148 and truncate-lines is nil. That's the reason for
6149 treating terminal frames specially here. */
6150
6151 if (!FRAME_WINDOW_P (it->f))
6152 move_it_vertically (it, target_y - (it->current_y + line_height));
6153 else
6154 {
6155 do
6156 {
6157 move_it_by_lines (it, 1, 1);
6158 }
6159 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6160 }
6161
6162 xassert (IT_CHARPOS (*it) >= BEGV);
6163 }
6164 }
6165 }
6166
6167
6168 /* Move IT by a specified amount of pixel lines DY. DY negative means
6169 move backwards. DY = 0 means move to start of screen line. At the
6170 end, IT will be on the start of a screen line. */
6171
6172 void
6173 move_it_vertically (it, dy)
6174 struct it *it;
6175 int dy;
6176 {
6177 if (dy <= 0)
6178 move_it_vertically_backward (it, -dy);
6179 else if (dy > 0)
6180 {
6181 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6182 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6183 MOVE_TO_POS | MOVE_TO_Y);
6184 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6185
6186 /* If buffer ends in ZV without a newline, move to the start of
6187 the line to satisfy the post-condition. */
6188 if (IT_CHARPOS (*it) == ZV
6189 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6190 move_it_by_lines (it, 0, 0);
6191 }
6192 }
6193
6194
6195 /* Move iterator IT past the end of the text line it is in. */
6196
6197 void
6198 move_it_past_eol (it)
6199 struct it *it;
6200 {
6201 enum move_it_result rc;
6202
6203 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6204 if (rc == MOVE_NEWLINE_OR_CR)
6205 set_iterator_to_next (it, 0);
6206 }
6207
6208
6209 #if 0 /* Currently not used. */
6210
6211 /* Return non-zero if some text between buffer positions START_CHARPOS
6212 and END_CHARPOS is invisible. IT->window is the window for text
6213 property lookup. */
6214
6215 static int
6216 invisible_text_between_p (it, start_charpos, end_charpos)
6217 struct it *it;
6218 int start_charpos, end_charpos;
6219 {
6220 Lisp_Object prop, limit;
6221 int invisible_found_p;
6222
6223 xassert (it != NULL && start_charpos <= end_charpos);
6224
6225 /* Is text at START invisible? */
6226 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6227 it->window);
6228 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6229 invisible_found_p = 1;
6230 else
6231 {
6232 limit = Fnext_single_char_property_change (make_number (start_charpos),
6233 Qinvisible, Qnil,
6234 make_number (end_charpos));
6235 invisible_found_p = XFASTINT (limit) < end_charpos;
6236 }
6237
6238 return invisible_found_p;
6239 }
6240
6241 #endif /* 0 */
6242
6243
6244 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6245 negative means move up. DVPOS == 0 means move to the start of the
6246 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6247 NEED_Y_P is zero, IT->current_y will be left unchanged.
6248
6249 Further optimization ideas: If we would know that IT->f doesn't use
6250 a face with proportional font, we could be faster for
6251 truncate-lines nil. */
6252
6253 void
6254 move_it_by_lines (it, dvpos, need_y_p)
6255 struct it *it;
6256 int dvpos, need_y_p;
6257 {
6258 struct position pos;
6259
6260 if (!FRAME_WINDOW_P (it->f))
6261 {
6262 struct text_pos textpos;
6263
6264 /* We can use vmotion on frames without proportional fonts. */
6265 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6266 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6267 reseat (it, textpos, 1);
6268 it->vpos += pos.vpos;
6269 it->current_y += pos.vpos;
6270 }
6271 else if (dvpos == 0)
6272 {
6273 /* DVPOS == 0 means move to the start of the screen line. */
6274 move_it_vertically_backward (it, 0);
6275 xassert (it->current_x == 0 && it->hpos == 0);
6276 }
6277 else if (dvpos > 0)
6278 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6279 else
6280 {
6281 struct it it2;
6282 int start_charpos, i;
6283
6284 /* Start at the beginning of the screen line containing IT's
6285 position. */
6286 move_it_vertically_backward (it, 0);
6287
6288 /* Go back -DVPOS visible lines and reseat the iterator there. */
6289 start_charpos = IT_CHARPOS (*it);
6290 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6291 back_to_previous_visible_line_start (it);
6292 reseat (it, it->current.pos, 1);
6293 it->current_x = it->hpos = 0;
6294
6295 /* Above call may have moved too far if continuation lines
6296 are involved. Scan forward and see if it did. */
6297 it2 = *it;
6298 it2.vpos = it2.current_y = 0;
6299 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6300 it->vpos -= it2.vpos;
6301 it->current_y -= it2.current_y;
6302 it->current_x = it->hpos = 0;
6303
6304 /* If we moved too far, move IT some lines forward. */
6305 if (it2.vpos > -dvpos)
6306 {
6307 int delta = it2.vpos + dvpos;
6308 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6309 }
6310 }
6311 }
6312
6313 /* Return 1 if IT points into the middle of a display vector. */
6314
6315 int
6316 in_display_vector_p (it)
6317 struct it *it;
6318 {
6319 return (it->method == next_element_from_display_vector
6320 && it->current.dpvec_index > 0
6321 && it->dpvec + it->current.dpvec_index != it->dpend);
6322 }
6323
6324 \f
6325 /***********************************************************************
6326 Messages
6327 ***********************************************************************/
6328
6329
6330 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6331 to *Messages*. */
6332
6333 void
6334 add_to_log (format, arg1, arg2)
6335 char *format;
6336 Lisp_Object arg1, arg2;
6337 {
6338 Lisp_Object args[3];
6339 Lisp_Object msg, fmt;
6340 char *buffer;
6341 int len;
6342 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6343 USE_SAFE_ALLOCA;
6344
6345 /* Do nothing if called asynchronously. Inserting text into
6346 a buffer may call after-change-functions and alike and
6347 that would means running Lisp asynchronously. */
6348 if (handling_signal)
6349 return;
6350
6351 fmt = msg = Qnil;
6352 GCPRO4 (fmt, msg, arg1, arg2);
6353
6354 args[0] = fmt = build_string (format);
6355 args[1] = arg1;
6356 args[2] = arg2;
6357 msg = Fformat (3, args);
6358
6359 len = SBYTES (msg) + 1;
6360 SAFE_ALLOCA (buffer, char *, len);
6361 bcopy (SDATA (msg), buffer, len);
6362
6363 message_dolog (buffer, len - 1, 1, 0);
6364 SAFE_FREE (len);
6365
6366 UNGCPRO;
6367 }
6368
6369
6370 /* Output a newline in the *Messages* buffer if "needs" one. */
6371
6372 void
6373 message_log_maybe_newline ()
6374 {
6375 if (message_log_need_newline)
6376 message_dolog ("", 0, 1, 0);
6377 }
6378
6379
6380 /* Add a string M of length NBYTES to the message log, optionally
6381 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6382 nonzero, means interpret the contents of M as multibyte. This
6383 function calls low-level routines in order to bypass text property
6384 hooks, etc. which might not be safe to run. */
6385
6386 void
6387 message_dolog (m, nbytes, nlflag, multibyte)
6388 const char *m;
6389 int nbytes, nlflag, multibyte;
6390 {
6391 if (!NILP (Vmemory_full))
6392 return;
6393
6394 if (!NILP (Vmessage_log_max))
6395 {
6396 struct buffer *oldbuf;
6397 Lisp_Object oldpoint, oldbegv, oldzv;
6398 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6399 int point_at_end = 0;
6400 int zv_at_end = 0;
6401 Lisp_Object old_deactivate_mark, tem;
6402 struct gcpro gcpro1;
6403
6404 old_deactivate_mark = Vdeactivate_mark;
6405 oldbuf = current_buffer;
6406 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6407 current_buffer->undo_list = Qt;
6408
6409 oldpoint = message_dolog_marker1;
6410 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6411 oldbegv = message_dolog_marker2;
6412 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6413 oldzv = message_dolog_marker3;
6414 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6415 GCPRO1 (old_deactivate_mark);
6416
6417 if (PT == Z)
6418 point_at_end = 1;
6419 if (ZV == Z)
6420 zv_at_end = 1;
6421
6422 BEGV = BEG;
6423 BEGV_BYTE = BEG_BYTE;
6424 ZV = Z;
6425 ZV_BYTE = Z_BYTE;
6426 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6427
6428 /* Insert the string--maybe converting multibyte to single byte
6429 or vice versa, so that all the text fits the buffer. */
6430 if (multibyte
6431 && NILP (current_buffer->enable_multibyte_characters))
6432 {
6433 int i, c, char_bytes;
6434 unsigned char work[1];
6435
6436 /* Convert a multibyte string to single-byte
6437 for the *Message* buffer. */
6438 for (i = 0; i < nbytes; i += char_bytes)
6439 {
6440 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6441 work[0] = (SINGLE_BYTE_CHAR_P (c)
6442 ? c
6443 : multibyte_char_to_unibyte (c, Qnil));
6444 insert_1_both (work, 1, 1, 1, 0, 0);
6445 }
6446 }
6447 else if (! multibyte
6448 && ! NILP (current_buffer->enable_multibyte_characters))
6449 {
6450 int i, c, char_bytes;
6451 unsigned char *msg = (unsigned char *) m;
6452 unsigned char str[MAX_MULTIBYTE_LENGTH];
6453 /* Convert a single-byte string to multibyte
6454 for the *Message* buffer. */
6455 for (i = 0; i < nbytes; i++)
6456 {
6457 c = unibyte_char_to_multibyte (msg[i]);
6458 char_bytes = CHAR_STRING (c, str);
6459 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6460 }
6461 }
6462 else if (nbytes)
6463 insert_1 (m, nbytes, 1, 0, 0);
6464
6465 if (nlflag)
6466 {
6467 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6468 insert_1 ("\n", 1, 1, 0, 0);
6469
6470 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6471 this_bol = PT;
6472 this_bol_byte = PT_BYTE;
6473
6474 /* See if this line duplicates the previous one.
6475 If so, combine duplicates. */
6476 if (this_bol > BEG)
6477 {
6478 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6479 prev_bol = PT;
6480 prev_bol_byte = PT_BYTE;
6481
6482 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6483 this_bol, this_bol_byte);
6484 if (dup)
6485 {
6486 del_range_both (prev_bol, prev_bol_byte,
6487 this_bol, this_bol_byte, 0);
6488 if (dup > 1)
6489 {
6490 char dupstr[40];
6491 int duplen;
6492
6493 /* If you change this format, don't forget to also
6494 change message_log_check_duplicate. */
6495 sprintf (dupstr, " [%d times]", dup);
6496 duplen = strlen (dupstr);
6497 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6498 insert_1 (dupstr, duplen, 1, 0, 1);
6499 }
6500 }
6501 }
6502
6503 /* If we have more than the desired maximum number of lines
6504 in the *Messages* buffer now, delete the oldest ones.
6505 This is safe because we don't have undo in this buffer. */
6506
6507 if (NATNUMP (Vmessage_log_max))
6508 {
6509 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6510 -XFASTINT (Vmessage_log_max) - 1, 0);
6511 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6512 }
6513 }
6514 BEGV = XMARKER (oldbegv)->charpos;
6515 BEGV_BYTE = marker_byte_position (oldbegv);
6516
6517 if (zv_at_end)
6518 {
6519 ZV = Z;
6520 ZV_BYTE = Z_BYTE;
6521 }
6522 else
6523 {
6524 ZV = XMARKER (oldzv)->charpos;
6525 ZV_BYTE = marker_byte_position (oldzv);
6526 }
6527
6528 if (point_at_end)
6529 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6530 else
6531 /* We can't do Fgoto_char (oldpoint) because it will run some
6532 Lisp code. */
6533 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6534 XMARKER (oldpoint)->bytepos);
6535
6536 UNGCPRO;
6537 unchain_marker (XMARKER (oldpoint));
6538 unchain_marker (XMARKER (oldbegv));
6539 unchain_marker (XMARKER (oldzv));
6540
6541 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6542 set_buffer_internal (oldbuf);
6543 if (NILP (tem))
6544 windows_or_buffers_changed = old_windows_or_buffers_changed;
6545 message_log_need_newline = !nlflag;
6546 Vdeactivate_mark = old_deactivate_mark;
6547 }
6548 }
6549
6550
6551 /* We are at the end of the buffer after just having inserted a newline.
6552 (Note: We depend on the fact we won't be crossing the gap.)
6553 Check to see if the most recent message looks a lot like the previous one.
6554 Return 0 if different, 1 if the new one should just replace it, or a
6555 value N > 1 if we should also append " [N times]". */
6556
6557 static int
6558 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6559 int prev_bol, this_bol;
6560 int prev_bol_byte, this_bol_byte;
6561 {
6562 int i;
6563 int len = Z_BYTE - 1 - this_bol_byte;
6564 int seen_dots = 0;
6565 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6566 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6567
6568 for (i = 0; i < len; i++)
6569 {
6570 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6571 seen_dots = 1;
6572 if (p1[i] != p2[i])
6573 return seen_dots;
6574 }
6575 p1 += len;
6576 if (*p1 == '\n')
6577 return 2;
6578 if (*p1++ == ' ' && *p1++ == '[')
6579 {
6580 int n = 0;
6581 while (*p1 >= '0' && *p1 <= '9')
6582 n = n * 10 + *p1++ - '0';
6583 if (strncmp (p1, " times]\n", 8) == 0)
6584 return n+1;
6585 }
6586 return 0;
6587 }
6588
6589
6590 /* Display an echo area message M with a specified length of NBYTES
6591 bytes. The string may include null characters. If M is 0, clear
6592 out any existing message, and let the mini-buffer text show
6593 through.
6594
6595 The buffer M must continue to exist until after the echo area gets
6596 cleared or some other message gets displayed there. This means do
6597 not pass text that is stored in a Lisp string; do not pass text in
6598 a buffer that was alloca'd. */
6599
6600 void
6601 message2 (m, nbytes, multibyte)
6602 const char *m;
6603 int nbytes;
6604 int multibyte;
6605 {
6606 /* First flush out any partial line written with print. */
6607 message_log_maybe_newline ();
6608 if (m)
6609 message_dolog (m, nbytes, 1, multibyte);
6610 message2_nolog (m, nbytes, multibyte);
6611 }
6612
6613
6614 /* The non-logging counterpart of message2. */
6615
6616 void
6617 message2_nolog (m, nbytes, multibyte)
6618 const char *m;
6619 int nbytes, multibyte;
6620 {
6621 struct frame *sf = SELECTED_FRAME ();
6622 message_enable_multibyte = multibyte;
6623
6624 if (noninteractive)
6625 {
6626 if (noninteractive_need_newline)
6627 putc ('\n', stderr);
6628 noninteractive_need_newline = 0;
6629 if (m)
6630 fwrite (m, nbytes, 1, stderr);
6631 if (cursor_in_echo_area == 0)
6632 fprintf (stderr, "\n");
6633 fflush (stderr);
6634 }
6635 /* A null message buffer means that the frame hasn't really been
6636 initialized yet. Error messages get reported properly by
6637 cmd_error, so this must be just an informative message; toss it. */
6638 else if (INTERACTIVE
6639 && sf->glyphs_initialized_p
6640 && FRAME_MESSAGE_BUF (sf))
6641 {
6642 Lisp_Object mini_window;
6643 struct frame *f;
6644
6645 /* Get the frame containing the mini-buffer
6646 that the selected frame is using. */
6647 mini_window = FRAME_MINIBUF_WINDOW (sf);
6648 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6649
6650 FRAME_SAMPLE_VISIBILITY (f);
6651 if (FRAME_VISIBLE_P (sf)
6652 && ! FRAME_VISIBLE_P (f))
6653 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6654
6655 if (m)
6656 {
6657 set_message (m, Qnil, nbytes, multibyte);
6658 if (minibuffer_auto_raise)
6659 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6660 }
6661 else
6662 clear_message (1, 1);
6663
6664 do_pending_window_change (0);
6665 echo_area_display (1);
6666 do_pending_window_change (0);
6667 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6668 (*frame_up_to_date_hook) (f);
6669 }
6670 }
6671
6672
6673 /* Display an echo area message M with a specified length of NBYTES
6674 bytes. The string may include null characters. If M is not a
6675 string, clear out any existing message, and let the mini-buffer
6676 text show through. */
6677
6678 void
6679 message3 (m, nbytes, multibyte)
6680 Lisp_Object m;
6681 int nbytes;
6682 int multibyte;
6683 {
6684 struct gcpro gcpro1;
6685
6686 GCPRO1 (m);
6687
6688 /* First flush out any partial line written with print. */
6689 message_log_maybe_newline ();
6690 if (STRINGP (m))
6691 message_dolog (SDATA (m), nbytes, 1, multibyte);
6692 message3_nolog (m, nbytes, multibyte);
6693
6694 UNGCPRO;
6695 }
6696
6697
6698 /* The non-logging version of message3. */
6699
6700 void
6701 message3_nolog (m, nbytes, multibyte)
6702 Lisp_Object m;
6703 int nbytes, multibyte;
6704 {
6705 struct frame *sf = SELECTED_FRAME ();
6706 message_enable_multibyte = multibyte;
6707
6708 if (noninteractive)
6709 {
6710 if (noninteractive_need_newline)
6711 putc ('\n', stderr);
6712 noninteractive_need_newline = 0;
6713 if (STRINGP (m))
6714 fwrite (SDATA (m), nbytes, 1, stderr);
6715 if (cursor_in_echo_area == 0)
6716 fprintf (stderr, "\n");
6717 fflush (stderr);
6718 }
6719 /* A null message buffer means that the frame hasn't really been
6720 initialized yet. Error messages get reported properly by
6721 cmd_error, so this must be just an informative message; toss it. */
6722 else if (INTERACTIVE
6723 && sf->glyphs_initialized_p
6724 && FRAME_MESSAGE_BUF (sf))
6725 {
6726 Lisp_Object mini_window;
6727 Lisp_Object frame;
6728 struct frame *f;
6729
6730 /* Get the frame containing the mini-buffer
6731 that the selected frame is using. */
6732 mini_window = FRAME_MINIBUF_WINDOW (sf);
6733 frame = XWINDOW (mini_window)->frame;
6734 f = XFRAME (frame);
6735
6736 FRAME_SAMPLE_VISIBILITY (f);
6737 if (FRAME_VISIBLE_P (sf)
6738 && !FRAME_VISIBLE_P (f))
6739 Fmake_frame_visible (frame);
6740
6741 if (STRINGP (m) && SCHARS (m) > 0)
6742 {
6743 set_message (NULL, m, nbytes, multibyte);
6744 if (minibuffer_auto_raise)
6745 Fraise_frame (frame);
6746 }
6747 else
6748 clear_message (1, 1);
6749
6750 do_pending_window_change (0);
6751 echo_area_display (1);
6752 do_pending_window_change (0);
6753 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6754 (*frame_up_to_date_hook) (f);
6755 }
6756 }
6757
6758
6759 /* Display a null-terminated echo area message M. If M is 0, clear
6760 out any existing message, and let the mini-buffer text show through.
6761
6762 The buffer M must continue to exist until after the echo area gets
6763 cleared or some other message gets displayed there. Do not pass
6764 text that is stored in a Lisp string. Do not pass text in a buffer
6765 that was alloca'd. */
6766
6767 void
6768 message1 (m)
6769 char *m;
6770 {
6771 message2 (m, (m ? strlen (m) : 0), 0);
6772 }
6773
6774
6775 /* The non-logging counterpart of message1. */
6776
6777 void
6778 message1_nolog (m)
6779 char *m;
6780 {
6781 message2_nolog (m, (m ? strlen (m) : 0), 0);
6782 }
6783
6784 /* Display a message M which contains a single %s
6785 which gets replaced with STRING. */
6786
6787 void
6788 message_with_string (m, string, log)
6789 char *m;
6790 Lisp_Object string;
6791 int log;
6792 {
6793 CHECK_STRING (string);
6794
6795 if (noninteractive)
6796 {
6797 if (m)
6798 {
6799 if (noninteractive_need_newline)
6800 putc ('\n', stderr);
6801 noninteractive_need_newline = 0;
6802 fprintf (stderr, m, SDATA (string));
6803 if (cursor_in_echo_area == 0)
6804 fprintf (stderr, "\n");
6805 fflush (stderr);
6806 }
6807 }
6808 else if (INTERACTIVE)
6809 {
6810 /* The frame whose minibuffer we're going to display the message on.
6811 It may be larger than the selected frame, so we need
6812 to use its buffer, not the selected frame's buffer. */
6813 Lisp_Object mini_window;
6814 struct frame *f, *sf = SELECTED_FRAME ();
6815
6816 /* Get the frame containing the minibuffer
6817 that the selected frame is using. */
6818 mini_window = FRAME_MINIBUF_WINDOW (sf);
6819 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6820
6821 /* A null message buffer means that the frame hasn't really been
6822 initialized yet. Error messages get reported properly by
6823 cmd_error, so this must be just an informative message; toss it. */
6824 if (FRAME_MESSAGE_BUF (f))
6825 {
6826 Lisp_Object args[2], message;
6827 struct gcpro gcpro1, gcpro2;
6828
6829 args[0] = build_string (m);
6830 args[1] = message = string;
6831 GCPRO2 (args[0], message);
6832 gcpro1.nvars = 2;
6833
6834 message = Fformat (2, args);
6835
6836 if (log)
6837 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6838 else
6839 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6840
6841 UNGCPRO;
6842
6843 /* Print should start at the beginning of the message
6844 buffer next time. */
6845 message_buf_print = 0;
6846 }
6847 }
6848 }
6849
6850
6851 /* Dump an informative message to the minibuf. If M is 0, clear out
6852 any existing message, and let the mini-buffer text show through. */
6853
6854 /* VARARGS 1 */
6855 void
6856 message (m, a1, a2, a3)
6857 char *m;
6858 EMACS_INT a1, a2, a3;
6859 {
6860 if (noninteractive)
6861 {
6862 if (m)
6863 {
6864 if (noninteractive_need_newline)
6865 putc ('\n', stderr);
6866 noninteractive_need_newline = 0;
6867 fprintf (stderr, m, a1, a2, a3);
6868 if (cursor_in_echo_area == 0)
6869 fprintf (stderr, "\n");
6870 fflush (stderr);
6871 }
6872 }
6873 else if (INTERACTIVE)
6874 {
6875 /* The frame whose mini-buffer we're going to display the message
6876 on. It may be larger than the selected frame, so we need to
6877 use its buffer, not the selected frame's buffer. */
6878 Lisp_Object mini_window;
6879 struct frame *f, *sf = SELECTED_FRAME ();
6880
6881 /* Get the frame containing the mini-buffer
6882 that the selected frame is using. */
6883 mini_window = FRAME_MINIBUF_WINDOW (sf);
6884 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6885
6886 /* A null message buffer means that the frame hasn't really been
6887 initialized yet. Error messages get reported properly by
6888 cmd_error, so this must be just an informative message; toss
6889 it. */
6890 if (FRAME_MESSAGE_BUF (f))
6891 {
6892 if (m)
6893 {
6894 int len;
6895 #ifdef NO_ARG_ARRAY
6896 char *a[3];
6897 a[0] = (char *) a1;
6898 a[1] = (char *) a2;
6899 a[2] = (char *) a3;
6900
6901 len = doprnt (FRAME_MESSAGE_BUF (f),
6902 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6903 #else
6904 len = doprnt (FRAME_MESSAGE_BUF (f),
6905 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6906 (char **) &a1);
6907 #endif /* NO_ARG_ARRAY */
6908
6909 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6910 }
6911 else
6912 message1 (0);
6913
6914 /* Print should start at the beginning of the message
6915 buffer next time. */
6916 message_buf_print = 0;
6917 }
6918 }
6919 }
6920
6921
6922 /* The non-logging version of message. */
6923
6924 void
6925 message_nolog (m, a1, a2, a3)
6926 char *m;
6927 EMACS_INT a1, a2, a3;
6928 {
6929 Lisp_Object old_log_max;
6930 old_log_max = Vmessage_log_max;
6931 Vmessage_log_max = Qnil;
6932 message (m, a1, a2, a3);
6933 Vmessage_log_max = old_log_max;
6934 }
6935
6936
6937 /* Display the current message in the current mini-buffer. This is
6938 only called from error handlers in process.c, and is not time
6939 critical. */
6940
6941 void
6942 update_echo_area ()
6943 {
6944 if (!NILP (echo_area_buffer[0]))
6945 {
6946 Lisp_Object string;
6947 string = Fcurrent_message ();
6948 message3 (string, SBYTES (string),
6949 !NILP (current_buffer->enable_multibyte_characters));
6950 }
6951 }
6952
6953
6954 /* Make sure echo area buffers in `echo_buffers' are live.
6955 If they aren't, make new ones. */
6956
6957 static void
6958 ensure_echo_area_buffers ()
6959 {
6960 int i;
6961
6962 for (i = 0; i < 2; ++i)
6963 if (!BUFFERP (echo_buffer[i])
6964 || NILP (XBUFFER (echo_buffer[i])->name))
6965 {
6966 char name[30];
6967 Lisp_Object old_buffer;
6968 int j;
6969
6970 old_buffer = echo_buffer[i];
6971 sprintf (name, " *Echo Area %d*", i);
6972 echo_buffer[i] = Fget_buffer_create (build_string (name));
6973 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6974
6975 for (j = 0; j < 2; ++j)
6976 if (EQ (old_buffer, echo_area_buffer[j]))
6977 echo_area_buffer[j] = echo_buffer[i];
6978 }
6979 }
6980
6981
6982 /* Call FN with args A1..A4 with either the current or last displayed
6983 echo_area_buffer as current buffer.
6984
6985 WHICH zero means use the current message buffer
6986 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6987 from echo_buffer[] and clear it.
6988
6989 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6990 suitable buffer from echo_buffer[] and clear it.
6991
6992 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6993 that the current message becomes the last displayed one, make
6994 choose a suitable buffer for echo_area_buffer[0], and clear it.
6995
6996 Value is what FN returns. */
6997
6998 static int
6999 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7000 struct window *w;
7001 int which;
7002 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7003 EMACS_INT a1;
7004 Lisp_Object a2;
7005 EMACS_INT a3, a4;
7006 {
7007 Lisp_Object buffer;
7008 int this_one, the_other, clear_buffer_p, rc;
7009 int count = SPECPDL_INDEX ();
7010
7011 /* If buffers aren't live, make new ones. */
7012 ensure_echo_area_buffers ();
7013
7014 clear_buffer_p = 0;
7015
7016 if (which == 0)
7017 this_one = 0, the_other = 1;
7018 else if (which > 0)
7019 this_one = 1, the_other = 0;
7020 else
7021 {
7022 this_one = 0, the_other = 1;
7023 clear_buffer_p = 1;
7024
7025 /* We need a fresh one in case the current echo buffer equals
7026 the one containing the last displayed echo area message. */
7027 if (!NILP (echo_area_buffer[this_one])
7028 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7029 echo_area_buffer[this_one] = Qnil;
7030 }
7031
7032 /* Choose a suitable buffer from echo_buffer[] is we don't
7033 have one. */
7034 if (NILP (echo_area_buffer[this_one]))
7035 {
7036 echo_area_buffer[this_one]
7037 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7038 ? echo_buffer[the_other]
7039 : echo_buffer[this_one]);
7040 clear_buffer_p = 1;
7041 }
7042
7043 buffer = echo_area_buffer[this_one];
7044
7045 /* Don't get confused by reusing the buffer used for echoing
7046 for a different purpose. */
7047 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7048 cancel_echoing ();
7049
7050 record_unwind_protect (unwind_with_echo_area_buffer,
7051 with_echo_area_buffer_unwind_data (w));
7052
7053 /* Make the echo area buffer current. Note that for display
7054 purposes, it is not necessary that the displayed window's buffer
7055 == current_buffer, except for text property lookup. So, let's
7056 only set that buffer temporarily here without doing a full
7057 Fset_window_buffer. We must also change w->pointm, though,
7058 because otherwise an assertions in unshow_buffer fails, and Emacs
7059 aborts. */
7060 set_buffer_internal_1 (XBUFFER (buffer));
7061 if (w)
7062 {
7063 w->buffer = buffer;
7064 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7065 }
7066
7067 current_buffer->undo_list = Qt;
7068 current_buffer->read_only = Qnil;
7069 specbind (Qinhibit_read_only, Qt);
7070 specbind (Qinhibit_modification_hooks, Qt);
7071
7072 if (clear_buffer_p && Z > BEG)
7073 del_range (BEG, Z);
7074
7075 xassert (BEGV >= BEG);
7076 xassert (ZV <= Z && ZV >= BEGV);
7077
7078 rc = fn (a1, a2, a3, a4);
7079
7080 xassert (BEGV >= BEG);
7081 xassert (ZV <= Z && ZV >= BEGV);
7082
7083 unbind_to (count, Qnil);
7084 return rc;
7085 }
7086
7087
7088 /* Save state that should be preserved around the call to the function
7089 FN called in with_echo_area_buffer. */
7090
7091 static Lisp_Object
7092 with_echo_area_buffer_unwind_data (w)
7093 struct window *w;
7094 {
7095 int i = 0;
7096 Lisp_Object vector;
7097
7098 /* Reduce consing by keeping one vector in
7099 Vwith_echo_area_save_vector. */
7100 vector = Vwith_echo_area_save_vector;
7101 Vwith_echo_area_save_vector = Qnil;
7102
7103 if (NILP (vector))
7104 vector = Fmake_vector (make_number (7), Qnil);
7105
7106 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7107 AREF (vector, i) = Vdeactivate_mark, ++i;
7108 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7109
7110 if (w)
7111 {
7112 XSETWINDOW (AREF (vector, i), w); ++i;
7113 AREF (vector, i) = w->buffer; ++i;
7114 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7115 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7116 }
7117 else
7118 {
7119 int end = i + 4;
7120 for (; i < end; ++i)
7121 AREF (vector, i) = Qnil;
7122 }
7123
7124 xassert (i == ASIZE (vector));
7125 return vector;
7126 }
7127
7128
7129 /* Restore global state from VECTOR which was created by
7130 with_echo_area_buffer_unwind_data. */
7131
7132 static Lisp_Object
7133 unwind_with_echo_area_buffer (vector)
7134 Lisp_Object vector;
7135 {
7136 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7137 Vdeactivate_mark = AREF (vector, 1);
7138 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7139
7140 if (WINDOWP (AREF (vector, 3)))
7141 {
7142 struct window *w;
7143 Lisp_Object buffer, charpos, bytepos;
7144
7145 w = XWINDOW (AREF (vector, 3));
7146 buffer = AREF (vector, 4);
7147 charpos = AREF (vector, 5);
7148 bytepos = AREF (vector, 6);
7149
7150 w->buffer = buffer;
7151 set_marker_both (w->pointm, buffer,
7152 XFASTINT (charpos), XFASTINT (bytepos));
7153 }
7154
7155 Vwith_echo_area_save_vector = vector;
7156 return Qnil;
7157 }
7158
7159
7160 /* Set up the echo area for use by print functions. MULTIBYTE_P
7161 non-zero means we will print multibyte. */
7162
7163 void
7164 setup_echo_area_for_printing (multibyte_p)
7165 int multibyte_p;
7166 {
7167 /* If we can't find an echo area any more, exit. */
7168 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7169 Fkill_emacs (Qnil);
7170
7171 ensure_echo_area_buffers ();
7172
7173 if (!message_buf_print)
7174 {
7175 /* A message has been output since the last time we printed.
7176 Choose a fresh echo area buffer. */
7177 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7178 echo_area_buffer[0] = echo_buffer[1];
7179 else
7180 echo_area_buffer[0] = echo_buffer[0];
7181
7182 /* Switch to that buffer and clear it. */
7183 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7184 current_buffer->truncate_lines = Qnil;
7185
7186 if (Z > BEG)
7187 {
7188 int count = SPECPDL_INDEX ();
7189 specbind (Qinhibit_read_only, Qt);
7190 /* Note that undo recording is always disabled. */
7191 del_range (BEG, Z);
7192 unbind_to (count, Qnil);
7193 }
7194 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7195
7196 /* Set up the buffer for the multibyteness we need. */
7197 if (multibyte_p
7198 != !NILP (current_buffer->enable_multibyte_characters))
7199 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7200
7201 /* Raise the frame containing the echo area. */
7202 if (minibuffer_auto_raise)
7203 {
7204 struct frame *sf = SELECTED_FRAME ();
7205 Lisp_Object mini_window;
7206 mini_window = FRAME_MINIBUF_WINDOW (sf);
7207 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7208 }
7209
7210 message_log_maybe_newline ();
7211 message_buf_print = 1;
7212 }
7213 else
7214 {
7215 if (NILP (echo_area_buffer[0]))
7216 {
7217 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7218 echo_area_buffer[0] = echo_buffer[1];
7219 else
7220 echo_area_buffer[0] = echo_buffer[0];
7221 }
7222
7223 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7224 {
7225 /* Someone switched buffers between print requests. */
7226 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7227 current_buffer->truncate_lines = Qnil;
7228 }
7229 }
7230 }
7231
7232
7233 /* Display an echo area message in window W. Value is non-zero if W's
7234 height is changed. If display_last_displayed_message_p is
7235 non-zero, display the message that was last displayed, otherwise
7236 display the current message. */
7237
7238 static int
7239 display_echo_area (w)
7240 struct window *w;
7241 {
7242 int i, no_message_p, window_height_changed_p, count;
7243
7244 /* Temporarily disable garbage collections while displaying the echo
7245 area. This is done because a GC can print a message itself.
7246 That message would modify the echo area buffer's contents while a
7247 redisplay of the buffer is going on, and seriously confuse
7248 redisplay. */
7249 count = inhibit_garbage_collection ();
7250
7251 /* If there is no message, we must call display_echo_area_1
7252 nevertheless because it resizes the window. But we will have to
7253 reset the echo_area_buffer in question to nil at the end because
7254 with_echo_area_buffer will sets it to an empty buffer. */
7255 i = display_last_displayed_message_p ? 1 : 0;
7256 no_message_p = NILP (echo_area_buffer[i]);
7257
7258 window_height_changed_p
7259 = with_echo_area_buffer (w, display_last_displayed_message_p,
7260 display_echo_area_1,
7261 (EMACS_INT) w, Qnil, 0, 0);
7262
7263 if (no_message_p)
7264 echo_area_buffer[i] = Qnil;
7265
7266 unbind_to (count, Qnil);
7267 return window_height_changed_p;
7268 }
7269
7270
7271 /* Helper for display_echo_area. Display the current buffer which
7272 contains the current echo area message in window W, a mini-window,
7273 a pointer to which is passed in A1. A2..A4 are currently not used.
7274 Change the height of W so that all of the message is displayed.
7275 Value is non-zero if height of W was changed. */
7276
7277 static int
7278 display_echo_area_1 (a1, a2, a3, a4)
7279 EMACS_INT a1;
7280 Lisp_Object a2;
7281 EMACS_INT a3, a4;
7282 {
7283 struct window *w = (struct window *) a1;
7284 Lisp_Object window;
7285 struct text_pos start;
7286 int window_height_changed_p = 0;
7287
7288 /* Do this before displaying, so that we have a large enough glyph
7289 matrix for the display. */
7290 window_height_changed_p = resize_mini_window (w, 0);
7291
7292 /* Display. */
7293 clear_glyph_matrix (w->desired_matrix);
7294 XSETWINDOW (window, w);
7295 SET_TEXT_POS (start, BEG, BEG_BYTE);
7296 try_window (window, start);
7297
7298 return window_height_changed_p;
7299 }
7300
7301
7302 /* Resize the echo area window to exactly the size needed for the
7303 currently displayed message, if there is one. If a mini-buffer
7304 is active, don't shrink it. */
7305
7306 void
7307 resize_echo_area_exactly ()
7308 {
7309 if (BUFFERP (echo_area_buffer[0])
7310 && WINDOWP (echo_area_window))
7311 {
7312 struct window *w = XWINDOW (echo_area_window);
7313 int resized_p;
7314 Lisp_Object resize_exactly;
7315
7316 if (minibuf_level == 0)
7317 resize_exactly = Qt;
7318 else
7319 resize_exactly = Qnil;
7320
7321 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7322 (EMACS_INT) w, resize_exactly, 0, 0);
7323 if (resized_p)
7324 {
7325 ++windows_or_buffers_changed;
7326 ++update_mode_lines;
7327 redisplay_internal (0);
7328 }
7329 }
7330 }
7331
7332
7333 /* Callback function for with_echo_area_buffer, when used from
7334 resize_echo_area_exactly. A1 contains a pointer to the window to
7335 resize, EXACTLY non-nil means resize the mini-window exactly to the
7336 size of the text displayed. A3 and A4 are not used. Value is what
7337 resize_mini_window returns. */
7338
7339 static int
7340 resize_mini_window_1 (a1, exactly, a3, a4)
7341 EMACS_INT a1;
7342 Lisp_Object exactly;
7343 EMACS_INT a3, a4;
7344 {
7345 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7346 }
7347
7348
7349 /* Resize mini-window W to fit the size of its contents. EXACT:P
7350 means size the window exactly to the size needed. Otherwise, it's
7351 only enlarged until W's buffer is empty. Value is non-zero if
7352 the window height has been changed. */
7353
7354 int
7355 resize_mini_window (w, exact_p)
7356 struct window *w;
7357 int exact_p;
7358 {
7359 struct frame *f = XFRAME (w->frame);
7360 int window_height_changed_p = 0;
7361
7362 xassert (MINI_WINDOW_P (w));
7363
7364 /* Don't resize windows while redisplaying a window; it would
7365 confuse redisplay functions when the size of the window they are
7366 displaying changes from under them. Such a resizing can happen,
7367 for instance, when which-func prints a long message while
7368 we are running fontification-functions. We're running these
7369 functions with safe_call which binds inhibit-redisplay to t. */
7370 if (!NILP (Vinhibit_redisplay))
7371 return 0;
7372
7373 /* Nil means don't try to resize. */
7374 if (NILP (Vresize_mini_windows)
7375 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7376 return 0;
7377
7378 if (!FRAME_MINIBUF_ONLY_P (f))
7379 {
7380 struct it it;
7381 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7382 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7383 int height, max_height;
7384 int unit = FRAME_LINE_HEIGHT (f);
7385 struct text_pos start;
7386 struct buffer *old_current_buffer = NULL;
7387
7388 if (current_buffer != XBUFFER (w->buffer))
7389 {
7390 old_current_buffer = current_buffer;
7391 set_buffer_internal (XBUFFER (w->buffer));
7392 }
7393
7394 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7395
7396 /* Compute the max. number of lines specified by the user. */
7397 if (FLOATP (Vmax_mini_window_height))
7398 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7399 else if (INTEGERP (Vmax_mini_window_height))
7400 max_height = XINT (Vmax_mini_window_height);
7401 else
7402 max_height = total_height / 4;
7403
7404 /* Correct that max. height if it's bogus. */
7405 max_height = max (1, max_height);
7406 max_height = min (total_height, max_height);
7407
7408 /* Find out the height of the text in the window. */
7409 if (it.truncate_lines_p)
7410 height = 1;
7411 else
7412 {
7413 last_height = 0;
7414 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7415 if (it.max_ascent == 0 && it.max_descent == 0)
7416 height = it.current_y + last_height;
7417 else
7418 height = it.current_y + it.max_ascent + it.max_descent;
7419 height -= it.extra_line_spacing;
7420 height = (height + unit - 1) / unit;
7421 }
7422
7423 /* Compute a suitable window start. */
7424 if (height > max_height)
7425 {
7426 height = max_height;
7427 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7428 move_it_vertically_backward (&it, (height - 1) * unit);
7429 start = it.current.pos;
7430 }
7431 else
7432 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7433 SET_MARKER_FROM_TEXT_POS (w->start, start);
7434
7435 if (EQ (Vresize_mini_windows, Qgrow_only))
7436 {
7437 /* Let it grow only, until we display an empty message, in which
7438 case the window shrinks again. */
7439 if (height > WINDOW_TOTAL_LINES (w))
7440 {
7441 int old_height = WINDOW_TOTAL_LINES (w);
7442 freeze_window_starts (f, 1);
7443 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7444 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7445 }
7446 else if (height < WINDOW_TOTAL_LINES (w)
7447 && (exact_p || BEGV == ZV))
7448 {
7449 int old_height = WINDOW_TOTAL_LINES (w);
7450 freeze_window_starts (f, 0);
7451 shrink_mini_window (w);
7452 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7453 }
7454 }
7455 else
7456 {
7457 /* Always resize to exact size needed. */
7458 if (height > WINDOW_TOTAL_LINES (w))
7459 {
7460 int old_height = WINDOW_TOTAL_LINES (w);
7461 freeze_window_starts (f, 1);
7462 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7463 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7464 }
7465 else if (height < WINDOW_TOTAL_LINES (w))
7466 {
7467 int old_height = WINDOW_TOTAL_LINES (w);
7468 freeze_window_starts (f, 0);
7469 shrink_mini_window (w);
7470
7471 if (height)
7472 {
7473 freeze_window_starts (f, 1);
7474 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7475 }
7476
7477 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7478 }
7479 }
7480
7481 if (old_current_buffer)
7482 set_buffer_internal (old_current_buffer);
7483 }
7484
7485 return window_height_changed_p;
7486 }
7487
7488
7489 /* Value is the current message, a string, or nil if there is no
7490 current message. */
7491
7492 Lisp_Object
7493 current_message ()
7494 {
7495 Lisp_Object msg;
7496
7497 if (NILP (echo_area_buffer[0]))
7498 msg = Qnil;
7499 else
7500 {
7501 with_echo_area_buffer (0, 0, current_message_1,
7502 (EMACS_INT) &msg, Qnil, 0, 0);
7503 if (NILP (msg))
7504 echo_area_buffer[0] = Qnil;
7505 }
7506
7507 return msg;
7508 }
7509
7510
7511 static int
7512 current_message_1 (a1, a2, a3, a4)
7513 EMACS_INT a1;
7514 Lisp_Object a2;
7515 EMACS_INT a3, a4;
7516 {
7517 Lisp_Object *msg = (Lisp_Object *) a1;
7518
7519 if (Z > BEG)
7520 *msg = make_buffer_string (BEG, Z, 1);
7521 else
7522 *msg = Qnil;
7523 return 0;
7524 }
7525
7526
7527 /* Push the current message on Vmessage_stack for later restauration
7528 by restore_message. Value is non-zero if the current message isn't
7529 empty. This is a relatively infrequent operation, so it's not
7530 worth optimizing. */
7531
7532 int
7533 push_message ()
7534 {
7535 Lisp_Object msg;
7536 msg = current_message ();
7537 Vmessage_stack = Fcons (msg, Vmessage_stack);
7538 return STRINGP (msg);
7539 }
7540
7541
7542 /* Restore message display from the top of Vmessage_stack. */
7543
7544 void
7545 restore_message ()
7546 {
7547 Lisp_Object msg;
7548
7549 xassert (CONSP (Vmessage_stack));
7550 msg = XCAR (Vmessage_stack);
7551 if (STRINGP (msg))
7552 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7553 else
7554 message3_nolog (msg, 0, 0);
7555 }
7556
7557
7558 /* Handler for record_unwind_protect calling pop_message. */
7559
7560 Lisp_Object
7561 pop_message_unwind (dummy)
7562 Lisp_Object dummy;
7563 {
7564 pop_message ();
7565 return Qnil;
7566 }
7567
7568 /* Pop the top-most entry off Vmessage_stack. */
7569
7570 void
7571 pop_message ()
7572 {
7573 xassert (CONSP (Vmessage_stack));
7574 Vmessage_stack = XCDR (Vmessage_stack);
7575 }
7576
7577
7578 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7579 exits. If the stack is not empty, we have a missing pop_message
7580 somewhere. */
7581
7582 void
7583 check_message_stack ()
7584 {
7585 if (!NILP (Vmessage_stack))
7586 abort ();
7587 }
7588
7589
7590 /* Truncate to NCHARS what will be displayed in the echo area the next
7591 time we display it---but don't redisplay it now. */
7592
7593 void
7594 truncate_echo_area (nchars)
7595 int nchars;
7596 {
7597 if (nchars == 0)
7598 echo_area_buffer[0] = Qnil;
7599 /* A null message buffer means that the frame hasn't really been
7600 initialized yet. Error messages get reported properly by
7601 cmd_error, so this must be just an informative message; toss it. */
7602 else if (!noninteractive
7603 && INTERACTIVE
7604 && !NILP (echo_area_buffer[0]))
7605 {
7606 struct frame *sf = SELECTED_FRAME ();
7607 if (FRAME_MESSAGE_BUF (sf))
7608 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7609 }
7610 }
7611
7612
7613 /* Helper function for truncate_echo_area. Truncate the current
7614 message to at most NCHARS characters. */
7615
7616 static int
7617 truncate_message_1 (nchars, a2, a3, a4)
7618 EMACS_INT nchars;
7619 Lisp_Object a2;
7620 EMACS_INT a3, a4;
7621 {
7622 if (BEG + nchars < Z)
7623 del_range (BEG + nchars, Z);
7624 if (Z == BEG)
7625 echo_area_buffer[0] = Qnil;
7626 return 0;
7627 }
7628
7629
7630 /* Set the current message to a substring of S or STRING.
7631
7632 If STRING is a Lisp string, set the message to the first NBYTES
7633 bytes from STRING. NBYTES zero means use the whole string. If
7634 STRING is multibyte, the message will be displayed multibyte.
7635
7636 If S is not null, set the message to the first LEN bytes of S. LEN
7637 zero means use the whole string. MULTIBYTE_P non-zero means S is
7638 multibyte. Display the message multibyte in that case. */
7639
7640 void
7641 set_message (s, string, nbytes, multibyte_p)
7642 const char *s;
7643 Lisp_Object string;
7644 int nbytes, multibyte_p;
7645 {
7646 message_enable_multibyte
7647 = ((s && multibyte_p)
7648 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7649
7650 with_echo_area_buffer (0, -1, set_message_1,
7651 (EMACS_INT) s, string, nbytes, multibyte_p);
7652 message_buf_print = 0;
7653 help_echo_showing_p = 0;
7654 }
7655
7656
7657 /* Helper function for set_message. Arguments have the same meaning
7658 as there, with A1 corresponding to S and A2 corresponding to STRING
7659 This function is called with the echo area buffer being
7660 current. */
7661
7662 static int
7663 set_message_1 (a1, a2, nbytes, multibyte_p)
7664 EMACS_INT a1;
7665 Lisp_Object a2;
7666 EMACS_INT nbytes, multibyte_p;
7667 {
7668 const char *s = (const char *) a1;
7669 Lisp_Object string = a2;
7670
7671 xassert (BEG == Z);
7672
7673 /* Change multibyteness of the echo buffer appropriately. */
7674 if (message_enable_multibyte
7675 != !NILP (current_buffer->enable_multibyte_characters))
7676 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7677
7678 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7679
7680 /* Insert new message at BEG. */
7681 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7682
7683 if (STRINGP (string))
7684 {
7685 int nchars;
7686
7687 if (nbytes == 0)
7688 nbytes = SBYTES (string);
7689 nchars = string_byte_to_char (string, nbytes);
7690
7691 /* This function takes care of single/multibyte conversion. We
7692 just have to ensure that the echo area buffer has the right
7693 setting of enable_multibyte_characters. */
7694 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7695 }
7696 else if (s)
7697 {
7698 if (nbytes == 0)
7699 nbytes = strlen (s);
7700
7701 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7702 {
7703 /* Convert from multi-byte to single-byte. */
7704 int i, c, n;
7705 unsigned char work[1];
7706
7707 /* Convert a multibyte string to single-byte. */
7708 for (i = 0; i < nbytes; i += n)
7709 {
7710 c = string_char_and_length (s + i, nbytes - i, &n);
7711 work[0] = (SINGLE_BYTE_CHAR_P (c)
7712 ? c
7713 : multibyte_char_to_unibyte (c, Qnil));
7714 insert_1_both (work, 1, 1, 1, 0, 0);
7715 }
7716 }
7717 else if (!multibyte_p
7718 && !NILP (current_buffer->enable_multibyte_characters))
7719 {
7720 /* Convert from single-byte to multi-byte. */
7721 int i, c, n;
7722 const unsigned char *msg = (const unsigned char *) s;
7723 unsigned char str[MAX_MULTIBYTE_LENGTH];
7724
7725 /* Convert a single-byte string to multibyte. */
7726 for (i = 0; i < nbytes; i++)
7727 {
7728 c = unibyte_char_to_multibyte (msg[i]);
7729 n = CHAR_STRING (c, str);
7730 insert_1_both (str, 1, n, 1, 0, 0);
7731 }
7732 }
7733 else
7734 insert_1 (s, nbytes, 1, 0, 0);
7735 }
7736
7737 return 0;
7738 }
7739
7740
7741 /* Clear messages. CURRENT_P non-zero means clear the current
7742 message. LAST_DISPLAYED_P non-zero means clear the message
7743 last displayed. */
7744
7745 void
7746 clear_message (current_p, last_displayed_p)
7747 int current_p, last_displayed_p;
7748 {
7749 if (current_p)
7750 {
7751 echo_area_buffer[0] = Qnil;
7752 message_cleared_p = 1;
7753 }
7754
7755 if (last_displayed_p)
7756 echo_area_buffer[1] = Qnil;
7757
7758 message_buf_print = 0;
7759 }
7760
7761 /* Clear garbaged frames.
7762
7763 This function is used where the old redisplay called
7764 redraw_garbaged_frames which in turn called redraw_frame which in
7765 turn called clear_frame. The call to clear_frame was a source of
7766 flickering. I believe a clear_frame is not necessary. It should
7767 suffice in the new redisplay to invalidate all current matrices,
7768 and ensure a complete redisplay of all windows. */
7769
7770 static void
7771 clear_garbaged_frames ()
7772 {
7773 if (frame_garbaged)
7774 {
7775 Lisp_Object tail, frame;
7776 int changed_count = 0;
7777
7778 FOR_EACH_FRAME (tail, frame)
7779 {
7780 struct frame *f = XFRAME (frame);
7781
7782 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7783 {
7784 if (f->resized_p)
7785 {
7786 Fredraw_frame (frame);
7787 f->force_flush_display_p = 1;
7788 }
7789 clear_current_matrices (f);
7790 changed_count++;
7791 f->garbaged = 0;
7792 f->resized_p = 0;
7793 }
7794 }
7795
7796 frame_garbaged = 0;
7797 if (changed_count)
7798 ++windows_or_buffers_changed;
7799 }
7800 }
7801
7802
7803 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7804 is non-zero update selected_frame. Value is non-zero if the
7805 mini-windows height has been changed. */
7806
7807 static int
7808 echo_area_display (update_frame_p)
7809 int update_frame_p;
7810 {
7811 Lisp_Object mini_window;
7812 struct window *w;
7813 struct frame *f;
7814 int window_height_changed_p = 0;
7815 struct frame *sf = SELECTED_FRAME ();
7816
7817 mini_window = FRAME_MINIBUF_WINDOW (sf);
7818 w = XWINDOW (mini_window);
7819 f = XFRAME (WINDOW_FRAME (w));
7820
7821 /* Don't display if frame is invisible or not yet initialized. */
7822 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7823 return 0;
7824
7825 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7826 #ifndef MAC_OS8
7827 #ifdef HAVE_WINDOW_SYSTEM
7828 /* When Emacs starts, selected_frame may be a visible terminal
7829 frame, even if we run under a window system. If we let this
7830 through, a message would be displayed on the terminal. */
7831 if (EQ (selected_frame, Vterminal_frame)
7832 && !NILP (Vwindow_system))
7833 return 0;
7834 #endif /* HAVE_WINDOW_SYSTEM */
7835 #endif
7836
7837 /* Redraw garbaged frames. */
7838 if (frame_garbaged)
7839 clear_garbaged_frames ();
7840
7841 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7842 {
7843 echo_area_window = mini_window;
7844 window_height_changed_p = display_echo_area (w);
7845 w->must_be_updated_p = 1;
7846
7847 /* Update the display, unless called from redisplay_internal.
7848 Also don't update the screen during redisplay itself. The
7849 update will happen at the end of redisplay, and an update
7850 here could cause confusion. */
7851 if (update_frame_p && !redisplaying_p)
7852 {
7853 int n = 0;
7854
7855 /* If the display update has been interrupted by pending
7856 input, update mode lines in the frame. Due to the
7857 pending input, it might have been that redisplay hasn't
7858 been called, so that mode lines above the echo area are
7859 garbaged. This looks odd, so we prevent it here. */
7860 if (!display_completed)
7861 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7862
7863 if (window_height_changed_p
7864 /* Don't do this if Emacs is shutting down. Redisplay
7865 needs to run hooks. */
7866 && !NILP (Vrun_hooks))
7867 {
7868 /* Must update other windows. Likewise as in other
7869 cases, don't let this update be interrupted by
7870 pending input. */
7871 int count = SPECPDL_INDEX ();
7872 specbind (Qredisplay_dont_pause, Qt);
7873 windows_or_buffers_changed = 1;
7874 redisplay_internal (0);
7875 unbind_to (count, Qnil);
7876 }
7877 else if (FRAME_WINDOW_P (f) && n == 0)
7878 {
7879 /* Window configuration is the same as before.
7880 Can do with a display update of the echo area,
7881 unless we displayed some mode lines. */
7882 update_single_window (w, 1);
7883 rif->flush_display (f);
7884 }
7885 else
7886 update_frame (f, 1, 1);
7887
7888 /* If cursor is in the echo area, make sure that the next
7889 redisplay displays the minibuffer, so that the cursor will
7890 be replaced with what the minibuffer wants. */
7891 if (cursor_in_echo_area)
7892 ++windows_or_buffers_changed;
7893 }
7894 }
7895 else if (!EQ (mini_window, selected_window))
7896 windows_or_buffers_changed++;
7897
7898 /* Last displayed message is now the current message. */
7899 echo_area_buffer[1] = echo_area_buffer[0];
7900
7901 /* Prevent redisplay optimization in redisplay_internal by resetting
7902 this_line_start_pos. This is done because the mini-buffer now
7903 displays the message instead of its buffer text. */
7904 if (EQ (mini_window, selected_window))
7905 CHARPOS (this_line_start_pos) = 0;
7906
7907 return window_height_changed_p;
7908 }
7909
7910
7911 \f
7912 /***********************************************************************
7913 Frame Titles
7914 ***********************************************************************/
7915
7916
7917 /* The frame title buffering code is also used by Fformat_mode_line.
7918 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7919
7920 /* A buffer for constructing frame titles in it; allocated from the
7921 heap in init_xdisp and resized as needed in store_frame_title_char. */
7922
7923 static char *frame_title_buf;
7924
7925 /* The buffer's end, and a current output position in it. */
7926
7927 static char *frame_title_buf_end;
7928 static char *frame_title_ptr;
7929
7930
7931 /* Store a single character C for the frame title in frame_title_buf.
7932 Re-allocate frame_title_buf if necessary. */
7933
7934 static void
7935 #ifdef PROTOTYPES
7936 store_frame_title_char (char c)
7937 #else
7938 store_frame_title_char (c)
7939 char c;
7940 #endif
7941 {
7942 /* If output position has reached the end of the allocated buffer,
7943 double the buffer's size. */
7944 if (frame_title_ptr == frame_title_buf_end)
7945 {
7946 int len = frame_title_ptr - frame_title_buf;
7947 int new_size = 2 * len * sizeof *frame_title_buf;
7948 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7949 frame_title_buf_end = frame_title_buf + new_size;
7950 frame_title_ptr = frame_title_buf + len;
7951 }
7952
7953 *frame_title_ptr++ = c;
7954 }
7955
7956
7957 /* Store part of a frame title in frame_title_buf, beginning at
7958 frame_title_ptr. STR is the string to store. Do not copy
7959 characters that yield more columns than PRECISION; PRECISION <= 0
7960 means copy the whole string. Pad with spaces until FIELD_WIDTH
7961 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7962 pad. Called from display_mode_element when it is used to build a
7963 frame title. */
7964
7965 static int
7966 store_frame_title (str, field_width, precision)
7967 const unsigned char *str;
7968 int field_width, precision;
7969 {
7970 int n = 0;
7971 int dummy, nbytes;
7972
7973 /* Copy at most PRECISION chars from STR. */
7974 nbytes = strlen (str);
7975 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7976 while (nbytes--)
7977 store_frame_title_char (*str++);
7978
7979 /* Fill up with spaces until FIELD_WIDTH reached. */
7980 while (field_width > 0
7981 && n < field_width)
7982 {
7983 store_frame_title_char (' ');
7984 ++n;
7985 }
7986
7987 return n;
7988 }
7989
7990 #ifdef HAVE_WINDOW_SYSTEM
7991
7992 /* Set the title of FRAME, if it has changed. The title format is
7993 Vicon_title_format if FRAME is iconified, otherwise it is
7994 frame_title_format. */
7995
7996 static void
7997 x_consider_frame_title (frame)
7998 Lisp_Object frame;
7999 {
8000 struct frame *f = XFRAME (frame);
8001
8002 if (FRAME_WINDOW_P (f)
8003 || FRAME_MINIBUF_ONLY_P (f)
8004 || f->explicit_name)
8005 {
8006 /* Do we have more than one visible frame on this X display? */
8007 Lisp_Object tail;
8008 Lisp_Object fmt;
8009 struct buffer *obuf;
8010 int len;
8011 struct it it;
8012
8013 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8014 {
8015 Lisp_Object other_frame = XCAR (tail);
8016 struct frame *tf = XFRAME (other_frame);
8017
8018 if (tf != f
8019 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8020 && !FRAME_MINIBUF_ONLY_P (tf)
8021 && !EQ (other_frame, tip_frame)
8022 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8023 break;
8024 }
8025
8026 /* Set global variable indicating that multiple frames exist. */
8027 multiple_frames = CONSP (tail);
8028
8029 /* Switch to the buffer of selected window of the frame. Set up
8030 frame_title_ptr so that display_mode_element will output into it;
8031 then display the title. */
8032 obuf = current_buffer;
8033 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8034 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8035 frame_title_ptr = frame_title_buf;
8036 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8037 NULL, DEFAULT_FACE_ID);
8038 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8039 len = frame_title_ptr - frame_title_buf;
8040 frame_title_ptr = NULL;
8041 set_buffer_internal_1 (obuf);
8042
8043 /* Set the title only if it's changed. This avoids consing in
8044 the common case where it hasn't. (If it turns out that we've
8045 already wasted too much time by walking through the list with
8046 display_mode_element, then we might need to optimize at a
8047 higher level than this.) */
8048 if (! STRINGP (f->name)
8049 || SBYTES (f->name) != len
8050 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8051 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8052 }
8053 }
8054
8055 #endif /* not HAVE_WINDOW_SYSTEM */
8056
8057
8058
8059 \f
8060 /***********************************************************************
8061 Menu Bars
8062 ***********************************************************************/
8063
8064
8065 /* Prepare for redisplay by updating menu-bar item lists when
8066 appropriate. This can call eval. */
8067
8068 void
8069 prepare_menu_bars ()
8070 {
8071 int all_windows;
8072 struct gcpro gcpro1, gcpro2;
8073 struct frame *f;
8074 Lisp_Object tooltip_frame;
8075
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 tooltip_frame = tip_frame;
8078 #else
8079 tooltip_frame = Qnil;
8080 #endif
8081
8082 /* Update all frame titles based on their buffer names, etc. We do
8083 this before the menu bars so that the buffer-menu will show the
8084 up-to-date frame titles. */
8085 #ifdef HAVE_WINDOW_SYSTEM
8086 if (windows_or_buffers_changed || update_mode_lines)
8087 {
8088 Lisp_Object tail, frame;
8089
8090 FOR_EACH_FRAME (tail, frame)
8091 {
8092 f = XFRAME (frame);
8093 if (!EQ (frame, tooltip_frame)
8094 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8095 x_consider_frame_title (frame);
8096 }
8097 }
8098 #endif /* HAVE_WINDOW_SYSTEM */
8099
8100 /* Update the menu bar item lists, if appropriate. This has to be
8101 done before any actual redisplay or generation of display lines. */
8102 all_windows = (update_mode_lines
8103 || buffer_shared > 1
8104 || windows_or_buffers_changed);
8105 if (all_windows)
8106 {
8107 Lisp_Object tail, frame;
8108 int count = SPECPDL_INDEX ();
8109
8110 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8111
8112 FOR_EACH_FRAME (tail, frame)
8113 {
8114 f = XFRAME (frame);
8115
8116 /* Ignore tooltip frame. */
8117 if (EQ (frame, tooltip_frame))
8118 continue;
8119
8120 /* If a window on this frame changed size, report that to
8121 the user and clear the size-change flag. */
8122 if (FRAME_WINDOW_SIZES_CHANGED (f))
8123 {
8124 Lisp_Object functions;
8125
8126 /* Clear flag first in case we get an error below. */
8127 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8128 functions = Vwindow_size_change_functions;
8129 GCPRO2 (tail, functions);
8130
8131 while (CONSP (functions))
8132 {
8133 call1 (XCAR (functions), frame);
8134 functions = XCDR (functions);
8135 }
8136 UNGCPRO;
8137 }
8138
8139 GCPRO1 (tail);
8140 update_menu_bar (f, 0);
8141 #ifdef HAVE_WINDOW_SYSTEM
8142 update_tool_bar (f, 0);
8143 #endif
8144 UNGCPRO;
8145 }
8146
8147 unbind_to (count, Qnil);
8148 }
8149 else
8150 {
8151 struct frame *sf = SELECTED_FRAME ();
8152 update_menu_bar (sf, 1);
8153 #ifdef HAVE_WINDOW_SYSTEM
8154 update_tool_bar (sf, 1);
8155 #endif
8156 }
8157
8158 /* Motif needs this. See comment in xmenu.c. Turn it off when
8159 pending_menu_activation is not defined. */
8160 #ifdef USE_X_TOOLKIT
8161 pending_menu_activation = 0;
8162 #endif
8163 }
8164
8165
8166 /* Update the menu bar item list for frame F. This has to be done
8167 before we start to fill in any display lines, because it can call
8168 eval.
8169
8170 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8171
8172 static void
8173 update_menu_bar (f, save_match_data)
8174 struct frame *f;
8175 int save_match_data;
8176 {
8177 Lisp_Object window;
8178 register struct window *w;
8179
8180 /* If called recursively during a menu update, do nothing. This can
8181 happen when, for instance, an activate-menubar-hook causes a
8182 redisplay. */
8183 if (inhibit_menubar_update)
8184 return;
8185
8186 window = FRAME_SELECTED_WINDOW (f);
8187 w = XWINDOW (window);
8188
8189 #if 0 /* The if statement below this if statement used to include the
8190 condition !NILP (w->update_mode_line), rather than using
8191 update_mode_lines directly, and this if statement may have
8192 been added to make that condition work. Now the if
8193 statement below matches its comment, this isn't needed. */
8194 if (update_mode_lines)
8195 w->update_mode_line = Qt;
8196 #endif
8197
8198 if (FRAME_WINDOW_P (f)
8199 ?
8200 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8201 || defined (USE_GTK)
8202 FRAME_EXTERNAL_MENU_BAR (f)
8203 #else
8204 FRAME_MENU_BAR_LINES (f) > 0
8205 #endif
8206 : FRAME_MENU_BAR_LINES (f) > 0)
8207 {
8208 /* If the user has switched buffers or windows, we need to
8209 recompute to reflect the new bindings. But we'll
8210 recompute when update_mode_lines is set too; that means
8211 that people can use force-mode-line-update to request
8212 that the menu bar be recomputed. The adverse effect on
8213 the rest of the redisplay algorithm is about the same as
8214 windows_or_buffers_changed anyway. */
8215 if (windows_or_buffers_changed
8216 /* This used to test w->update_mode_line, but we believe
8217 there is no need to recompute the menu in that case. */
8218 || update_mode_lines
8219 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8220 < BUF_MODIFF (XBUFFER (w->buffer)))
8221 != !NILP (w->last_had_star))
8222 || ((!NILP (Vtransient_mark_mode)
8223 && !NILP (XBUFFER (w->buffer)->mark_active))
8224 != !NILP (w->region_showing)))
8225 {
8226 struct buffer *prev = current_buffer;
8227 int count = SPECPDL_INDEX ();
8228
8229 specbind (Qinhibit_menubar_update, Qt);
8230
8231 set_buffer_internal_1 (XBUFFER (w->buffer));
8232 if (save_match_data)
8233 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8234 if (NILP (Voverriding_local_map_menu_flag))
8235 {
8236 specbind (Qoverriding_terminal_local_map, Qnil);
8237 specbind (Qoverriding_local_map, Qnil);
8238 }
8239
8240 /* Run the Lucid hook. */
8241 safe_run_hooks (Qactivate_menubar_hook);
8242
8243 /* If it has changed current-menubar from previous value,
8244 really recompute the menu-bar from the value. */
8245 if (! NILP (Vlucid_menu_bar_dirty_flag))
8246 call0 (Qrecompute_lucid_menubar);
8247
8248 safe_run_hooks (Qmenu_bar_update_hook);
8249 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8250
8251 /* Redisplay the menu bar in case we changed it. */
8252 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8253 || defined (USE_GTK)
8254 if (FRAME_WINDOW_P (f)
8255 #if defined (MAC_OS)
8256 /* All frames on Mac OS share the same menubar. So only the
8257 selected frame should be allowed to set it. */
8258 && f == SELECTED_FRAME ()
8259 #endif
8260 )
8261 set_frame_menubar (f, 0, 0);
8262 else
8263 /* On a terminal screen, the menu bar is an ordinary screen
8264 line, and this makes it get updated. */
8265 w->update_mode_line = Qt;
8266 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8267 /* In the non-toolkit version, the menu bar is an ordinary screen
8268 line, and this makes it get updated. */
8269 w->update_mode_line = Qt;
8270 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8271
8272 unbind_to (count, Qnil);
8273 set_buffer_internal_1 (prev);
8274 }
8275 }
8276 }
8277
8278
8279 \f
8280 /***********************************************************************
8281 Output Cursor
8282 ***********************************************************************/
8283
8284 #ifdef HAVE_WINDOW_SYSTEM
8285
8286 /* EXPORT:
8287 Nominal cursor position -- where to draw output.
8288 HPOS and VPOS are window relative glyph matrix coordinates.
8289 X and Y are window relative pixel coordinates. */
8290
8291 struct cursor_pos output_cursor;
8292
8293
8294 /* EXPORT:
8295 Set the global variable output_cursor to CURSOR. All cursor
8296 positions are relative to updated_window. */
8297
8298 void
8299 set_output_cursor (cursor)
8300 struct cursor_pos *cursor;
8301 {
8302 output_cursor.hpos = cursor->hpos;
8303 output_cursor.vpos = cursor->vpos;
8304 output_cursor.x = cursor->x;
8305 output_cursor.y = cursor->y;
8306 }
8307
8308
8309 /* EXPORT for RIF:
8310 Set a nominal cursor position.
8311
8312 HPOS and VPOS are column/row positions in a window glyph matrix. X
8313 and Y are window text area relative pixel positions.
8314
8315 If this is done during an update, updated_window will contain the
8316 window that is being updated and the position is the future output
8317 cursor position for that window. If updated_window is null, use
8318 selected_window and display the cursor at the given position. */
8319
8320 void
8321 x_cursor_to (vpos, hpos, y, x)
8322 int vpos, hpos, y, x;
8323 {
8324 struct window *w;
8325
8326 /* If updated_window is not set, work on selected_window. */
8327 if (updated_window)
8328 w = updated_window;
8329 else
8330 w = XWINDOW (selected_window);
8331
8332 /* Set the output cursor. */
8333 output_cursor.hpos = hpos;
8334 output_cursor.vpos = vpos;
8335 output_cursor.x = x;
8336 output_cursor.y = y;
8337
8338 /* If not called as part of an update, really display the cursor.
8339 This will also set the cursor position of W. */
8340 if (updated_window == NULL)
8341 {
8342 BLOCK_INPUT;
8343 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8344 if (rif->flush_display_optional)
8345 rif->flush_display_optional (SELECTED_FRAME ());
8346 UNBLOCK_INPUT;
8347 }
8348 }
8349
8350 #endif /* HAVE_WINDOW_SYSTEM */
8351
8352 \f
8353 /***********************************************************************
8354 Tool-bars
8355 ***********************************************************************/
8356
8357 #ifdef HAVE_WINDOW_SYSTEM
8358
8359 /* Where the mouse was last time we reported a mouse event. */
8360
8361 FRAME_PTR last_mouse_frame;
8362
8363 /* Tool-bar item index of the item on which a mouse button was pressed
8364 or -1. */
8365
8366 int last_tool_bar_item;
8367
8368
8369 /* Update the tool-bar item list for frame F. This has to be done
8370 before we start to fill in any display lines. Called from
8371 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8372 and restore it here. */
8373
8374 static void
8375 update_tool_bar (f, save_match_data)
8376 struct frame *f;
8377 int save_match_data;
8378 {
8379 #ifdef USE_GTK
8380 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8381 #else
8382 int do_update = WINDOWP (f->tool_bar_window)
8383 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8384 #endif
8385
8386 if (do_update)
8387 {
8388 Lisp_Object window;
8389 struct window *w;
8390
8391 window = FRAME_SELECTED_WINDOW (f);
8392 w = XWINDOW (window);
8393
8394 /* If the user has switched buffers or windows, we need to
8395 recompute to reflect the new bindings. But we'll
8396 recompute when update_mode_lines is set too; that means
8397 that people can use force-mode-line-update to request
8398 that the menu bar be recomputed. The adverse effect on
8399 the rest of the redisplay algorithm is about the same as
8400 windows_or_buffers_changed anyway. */
8401 if (windows_or_buffers_changed
8402 || !NILP (w->update_mode_line)
8403 || update_mode_lines
8404 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8405 < BUF_MODIFF (XBUFFER (w->buffer)))
8406 != !NILP (w->last_had_star))
8407 || ((!NILP (Vtransient_mark_mode)
8408 && !NILP (XBUFFER (w->buffer)->mark_active))
8409 != !NILP (w->region_showing)))
8410 {
8411 struct buffer *prev = current_buffer;
8412 int count = SPECPDL_INDEX ();
8413 Lisp_Object old_tool_bar;
8414 struct gcpro gcpro1;
8415
8416 /* Set current_buffer to the buffer of the selected
8417 window of the frame, so that we get the right local
8418 keymaps. */
8419 set_buffer_internal_1 (XBUFFER (w->buffer));
8420
8421 /* Save match data, if we must. */
8422 if (save_match_data)
8423 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8424
8425 /* Make sure that we don't accidentally use bogus keymaps. */
8426 if (NILP (Voverriding_local_map_menu_flag))
8427 {
8428 specbind (Qoverriding_terminal_local_map, Qnil);
8429 specbind (Qoverriding_local_map, Qnil);
8430 }
8431
8432 old_tool_bar = f->tool_bar_items;
8433 GCPRO1 (old_tool_bar);
8434
8435 /* Build desired tool-bar items from keymaps. */
8436 BLOCK_INPUT;
8437 f->tool_bar_items
8438 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8439 UNBLOCK_INPUT;
8440
8441 /* Redisplay the tool-bar if we changed it. */
8442 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8443 w->update_mode_line = Qt;
8444
8445 UNGCPRO;
8446
8447 unbind_to (count, Qnil);
8448 set_buffer_internal_1 (prev);
8449 }
8450 }
8451 }
8452
8453
8454 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8455 F's desired tool-bar contents. F->tool_bar_items must have
8456 been set up previously by calling prepare_menu_bars. */
8457
8458 static void
8459 build_desired_tool_bar_string (f)
8460 struct frame *f;
8461 {
8462 int i, size, size_needed;
8463 struct gcpro gcpro1, gcpro2, gcpro3;
8464 Lisp_Object image, plist, props;
8465
8466 image = plist = props = Qnil;
8467 GCPRO3 (image, plist, props);
8468
8469 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8470 Otherwise, make a new string. */
8471
8472 /* The size of the string we might be able to reuse. */
8473 size = (STRINGP (f->desired_tool_bar_string)
8474 ? SCHARS (f->desired_tool_bar_string)
8475 : 0);
8476
8477 /* We need one space in the string for each image. */
8478 size_needed = f->n_tool_bar_items;
8479
8480 /* Reuse f->desired_tool_bar_string, if possible. */
8481 if (size < size_needed || NILP (f->desired_tool_bar_string))
8482 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8483 make_number (' '));
8484 else
8485 {
8486 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8487 Fremove_text_properties (make_number (0), make_number (size),
8488 props, f->desired_tool_bar_string);
8489 }
8490
8491 /* Put a `display' property on the string for the images to display,
8492 put a `menu_item' property on tool-bar items with a value that
8493 is the index of the item in F's tool-bar item vector. */
8494 for (i = 0; i < f->n_tool_bar_items; ++i)
8495 {
8496 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8497
8498 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8499 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8500 int hmargin, vmargin, relief, idx, end;
8501 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8502
8503 /* If image is a vector, choose the image according to the
8504 button state. */
8505 image = PROP (TOOL_BAR_ITEM_IMAGES);
8506 if (VECTORP (image))
8507 {
8508 if (enabled_p)
8509 idx = (selected_p
8510 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8511 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8512 else
8513 idx = (selected_p
8514 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8515 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8516
8517 xassert (ASIZE (image) >= idx);
8518 image = AREF (image, idx);
8519 }
8520 else
8521 idx = -1;
8522
8523 /* Ignore invalid image specifications. */
8524 if (!valid_image_p (image))
8525 continue;
8526
8527 /* Display the tool-bar button pressed, or depressed. */
8528 plist = Fcopy_sequence (XCDR (image));
8529
8530 /* Compute margin and relief to draw. */
8531 relief = (tool_bar_button_relief >= 0
8532 ? tool_bar_button_relief
8533 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8534 hmargin = vmargin = relief;
8535
8536 if (INTEGERP (Vtool_bar_button_margin)
8537 && XINT (Vtool_bar_button_margin) > 0)
8538 {
8539 hmargin += XFASTINT (Vtool_bar_button_margin);
8540 vmargin += XFASTINT (Vtool_bar_button_margin);
8541 }
8542 else if (CONSP (Vtool_bar_button_margin))
8543 {
8544 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8545 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8546 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8547
8548 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8549 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8550 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8551 }
8552
8553 if (auto_raise_tool_bar_buttons_p)
8554 {
8555 /* Add a `:relief' property to the image spec if the item is
8556 selected. */
8557 if (selected_p)
8558 {
8559 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8560 hmargin -= relief;
8561 vmargin -= relief;
8562 }
8563 }
8564 else
8565 {
8566 /* If image is selected, display it pressed, i.e. with a
8567 negative relief. If it's not selected, display it with a
8568 raised relief. */
8569 plist = Fplist_put (plist, QCrelief,
8570 (selected_p
8571 ? make_number (-relief)
8572 : make_number (relief)));
8573 hmargin -= relief;
8574 vmargin -= relief;
8575 }
8576
8577 /* Put a margin around the image. */
8578 if (hmargin || vmargin)
8579 {
8580 if (hmargin == vmargin)
8581 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8582 else
8583 plist = Fplist_put (plist, QCmargin,
8584 Fcons (make_number (hmargin),
8585 make_number (vmargin)));
8586 }
8587
8588 /* If button is not enabled, and we don't have special images
8589 for the disabled state, make the image appear disabled by
8590 applying an appropriate algorithm to it. */
8591 if (!enabled_p && idx < 0)
8592 plist = Fplist_put (plist, QCconversion, Qdisabled);
8593
8594 /* Put a `display' text property on the string for the image to
8595 display. Put a `menu-item' property on the string that gives
8596 the start of this item's properties in the tool-bar items
8597 vector. */
8598 image = Fcons (Qimage, plist);
8599 props = list4 (Qdisplay, image,
8600 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8601
8602 /* Let the last image hide all remaining spaces in the tool bar
8603 string. The string can be longer than needed when we reuse a
8604 previous string. */
8605 if (i + 1 == f->n_tool_bar_items)
8606 end = SCHARS (f->desired_tool_bar_string);
8607 else
8608 end = i + 1;
8609 Fadd_text_properties (make_number (i), make_number (end),
8610 props, f->desired_tool_bar_string);
8611 #undef PROP
8612 }
8613
8614 UNGCPRO;
8615 }
8616
8617
8618 /* Display one line of the tool-bar of frame IT->f. */
8619
8620 static void
8621 display_tool_bar_line (it)
8622 struct it *it;
8623 {
8624 struct glyph_row *row = it->glyph_row;
8625 int max_x = it->last_visible_x;
8626 struct glyph *last;
8627
8628 prepare_desired_row (row);
8629 row->y = it->current_y;
8630
8631 /* Note that this isn't made use of if the face hasn't a box,
8632 so there's no need to check the face here. */
8633 it->start_of_box_run_p = 1;
8634
8635 while (it->current_x < max_x)
8636 {
8637 int x_before, x, n_glyphs_before, i, nglyphs;
8638
8639 /* Get the next display element. */
8640 if (!get_next_display_element (it))
8641 break;
8642
8643 /* Produce glyphs. */
8644 x_before = it->current_x;
8645 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8646 PRODUCE_GLYPHS (it);
8647
8648 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8649 i = 0;
8650 x = x_before;
8651 while (i < nglyphs)
8652 {
8653 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8654
8655 if (x + glyph->pixel_width > max_x)
8656 {
8657 /* Glyph doesn't fit on line. */
8658 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8659 it->current_x = x;
8660 goto out;
8661 }
8662
8663 ++it->hpos;
8664 x += glyph->pixel_width;
8665 ++i;
8666 }
8667
8668 /* Stop at line ends. */
8669 if (ITERATOR_AT_END_OF_LINE_P (it))
8670 break;
8671
8672 set_iterator_to_next (it, 1);
8673 }
8674
8675 out:;
8676
8677 row->displays_text_p = row->used[TEXT_AREA] != 0;
8678 extend_face_to_end_of_line (it);
8679 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8680 last->right_box_line_p = 1;
8681 if (last == row->glyphs[TEXT_AREA])
8682 last->left_box_line_p = 1;
8683 compute_line_metrics (it);
8684
8685 /* If line is empty, make it occupy the rest of the tool-bar. */
8686 if (!row->displays_text_p)
8687 {
8688 row->height = row->phys_height = it->last_visible_y - row->y;
8689 row->ascent = row->phys_ascent = 0;
8690 }
8691
8692 row->full_width_p = 1;
8693 row->continued_p = 0;
8694 row->truncated_on_left_p = 0;
8695 row->truncated_on_right_p = 0;
8696
8697 it->current_x = it->hpos = 0;
8698 it->current_y += row->height;
8699 ++it->vpos;
8700 ++it->glyph_row;
8701 }
8702
8703
8704 /* Value is the number of screen lines needed to make all tool-bar
8705 items of frame F visible. */
8706
8707 static int
8708 tool_bar_lines_needed (f)
8709 struct frame *f;
8710 {
8711 struct window *w = XWINDOW (f->tool_bar_window);
8712 struct it it;
8713
8714 /* Initialize an iterator for iteration over
8715 F->desired_tool_bar_string in the tool-bar window of frame F. */
8716 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8717 it.first_visible_x = 0;
8718 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8719 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8720
8721 while (!ITERATOR_AT_END_P (&it))
8722 {
8723 it.glyph_row = w->desired_matrix->rows;
8724 clear_glyph_row (it.glyph_row);
8725 display_tool_bar_line (&it);
8726 }
8727
8728 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8729 }
8730
8731
8732 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8733 0, 1, 0,
8734 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8735 (frame)
8736 Lisp_Object frame;
8737 {
8738 struct frame *f;
8739 struct window *w;
8740 int nlines = 0;
8741
8742 if (NILP (frame))
8743 frame = selected_frame;
8744 else
8745 CHECK_FRAME (frame);
8746 f = XFRAME (frame);
8747
8748 if (WINDOWP (f->tool_bar_window)
8749 || (w = XWINDOW (f->tool_bar_window),
8750 WINDOW_TOTAL_LINES (w) > 0))
8751 {
8752 update_tool_bar (f, 1);
8753 if (f->n_tool_bar_items)
8754 {
8755 build_desired_tool_bar_string (f);
8756 nlines = tool_bar_lines_needed (f);
8757 }
8758 }
8759
8760 return make_number (nlines);
8761 }
8762
8763
8764 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8765 height should be changed. */
8766
8767 static int
8768 redisplay_tool_bar (f)
8769 struct frame *f;
8770 {
8771 struct window *w;
8772 struct it it;
8773 struct glyph_row *row;
8774 int change_height_p = 0;
8775
8776 #ifdef USE_GTK
8777 if (FRAME_EXTERNAL_TOOL_BAR (f))
8778 update_frame_tool_bar (f);
8779 return 0;
8780 #endif
8781
8782 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8783 do anything. This means you must start with tool-bar-lines
8784 non-zero to get the auto-sizing effect. Or in other words, you
8785 can turn off tool-bars by specifying tool-bar-lines zero. */
8786 if (!WINDOWP (f->tool_bar_window)
8787 || (w = XWINDOW (f->tool_bar_window),
8788 WINDOW_TOTAL_LINES (w) == 0))
8789 return 0;
8790
8791 /* Set up an iterator for the tool-bar window. */
8792 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8793 it.first_visible_x = 0;
8794 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8795 row = it.glyph_row;
8796
8797 /* Build a string that represents the contents of the tool-bar. */
8798 build_desired_tool_bar_string (f);
8799 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8800
8801 /* Display as many lines as needed to display all tool-bar items. */
8802 while (it.current_y < it.last_visible_y)
8803 display_tool_bar_line (&it);
8804
8805 /* It doesn't make much sense to try scrolling in the tool-bar
8806 window, so don't do it. */
8807 w->desired_matrix->no_scrolling_p = 1;
8808 w->must_be_updated_p = 1;
8809
8810 if (auto_resize_tool_bars_p)
8811 {
8812 int nlines;
8813
8814 /* If we couldn't display everything, change the tool-bar's
8815 height. */
8816 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8817 change_height_p = 1;
8818
8819 /* If there are blank lines at the end, except for a partially
8820 visible blank line at the end that is smaller than
8821 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8822 row = it.glyph_row - 1;
8823 if (!row->displays_text_p
8824 && row->height >= FRAME_LINE_HEIGHT (f))
8825 change_height_p = 1;
8826
8827 /* If row displays tool-bar items, but is partially visible,
8828 change the tool-bar's height. */
8829 if (row->displays_text_p
8830 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8831 change_height_p = 1;
8832
8833 /* Resize windows as needed by changing the `tool-bar-lines'
8834 frame parameter. */
8835 if (change_height_p
8836 && (nlines = tool_bar_lines_needed (f),
8837 nlines != WINDOW_TOTAL_LINES (w)))
8838 {
8839 extern Lisp_Object Qtool_bar_lines;
8840 Lisp_Object frame;
8841 int old_height = WINDOW_TOTAL_LINES (w);
8842
8843 XSETFRAME (frame, f);
8844 clear_glyph_matrix (w->desired_matrix);
8845 Fmodify_frame_parameters (frame,
8846 Fcons (Fcons (Qtool_bar_lines,
8847 make_number (nlines)),
8848 Qnil));
8849 if (WINDOW_TOTAL_LINES (w) != old_height)
8850 fonts_changed_p = 1;
8851 }
8852 }
8853
8854 return change_height_p;
8855 }
8856
8857
8858 /* Get information about the tool-bar item which is displayed in GLYPH
8859 on frame F. Return in *PROP_IDX the index where tool-bar item
8860 properties start in F->tool_bar_items. Value is zero if
8861 GLYPH doesn't display a tool-bar item. */
8862
8863 static int
8864 tool_bar_item_info (f, glyph, prop_idx)
8865 struct frame *f;
8866 struct glyph *glyph;
8867 int *prop_idx;
8868 {
8869 Lisp_Object prop;
8870 int success_p;
8871 int charpos;
8872
8873 /* This function can be called asynchronously, which means we must
8874 exclude any possibility that Fget_text_property signals an
8875 error. */
8876 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8877 charpos = max (0, charpos);
8878
8879 /* Get the text property `menu-item' at pos. The value of that
8880 property is the start index of this item's properties in
8881 F->tool_bar_items. */
8882 prop = Fget_text_property (make_number (charpos),
8883 Qmenu_item, f->current_tool_bar_string);
8884 if (INTEGERP (prop))
8885 {
8886 *prop_idx = XINT (prop);
8887 success_p = 1;
8888 }
8889 else
8890 success_p = 0;
8891
8892 return success_p;
8893 }
8894
8895 \f
8896 /* Get information about the tool-bar item at position X/Y on frame F.
8897 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8898 the current matrix of the tool-bar window of F, or NULL if not
8899 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8900 item in F->tool_bar_items. Value is
8901
8902 -1 if X/Y is not on a tool-bar item
8903 0 if X/Y is on the same item that was highlighted before.
8904 1 otherwise. */
8905
8906 static int
8907 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8908 struct frame *f;
8909 int x, y;
8910 struct glyph **glyph;
8911 int *hpos, *vpos, *prop_idx;
8912 {
8913 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8914 struct window *w = XWINDOW (f->tool_bar_window);
8915 int area;
8916
8917 /* Find the glyph under X/Y. */
8918 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8919 if (*glyph == NULL)
8920 return -1;
8921
8922 /* Get the start of this tool-bar item's properties in
8923 f->tool_bar_items. */
8924 if (!tool_bar_item_info (f, *glyph, prop_idx))
8925 return -1;
8926
8927 /* Is mouse on the highlighted item? */
8928 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8929 && *vpos >= dpyinfo->mouse_face_beg_row
8930 && *vpos <= dpyinfo->mouse_face_end_row
8931 && (*vpos > dpyinfo->mouse_face_beg_row
8932 || *hpos >= dpyinfo->mouse_face_beg_col)
8933 && (*vpos < dpyinfo->mouse_face_end_row
8934 || *hpos < dpyinfo->mouse_face_end_col
8935 || dpyinfo->mouse_face_past_end))
8936 return 0;
8937
8938 return 1;
8939 }
8940
8941
8942 /* EXPORT:
8943 Handle mouse button event on the tool-bar of frame F, at
8944 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8945 0 for button release. MODIFIERS is event modifiers for button
8946 release. */
8947
8948 void
8949 handle_tool_bar_click (f, x, y, down_p, modifiers)
8950 struct frame *f;
8951 int x, y, down_p;
8952 unsigned int modifiers;
8953 {
8954 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8955 struct window *w = XWINDOW (f->tool_bar_window);
8956 int hpos, vpos, prop_idx;
8957 struct glyph *glyph;
8958 Lisp_Object enabled_p;
8959
8960 /* If not on the highlighted tool-bar item, return. */
8961 frame_to_window_pixel_xy (w, &x, &y);
8962 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8963 return;
8964
8965 /* If item is disabled, do nothing. */
8966 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8967 if (NILP (enabled_p))
8968 return;
8969
8970 if (down_p)
8971 {
8972 /* Show item in pressed state. */
8973 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8974 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8975 last_tool_bar_item = prop_idx;
8976 }
8977 else
8978 {
8979 Lisp_Object key, frame;
8980 struct input_event event;
8981 EVENT_INIT (event);
8982
8983 /* Show item in released state. */
8984 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8985 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8986
8987 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8988
8989 XSETFRAME (frame, f);
8990 event.kind = TOOL_BAR_EVENT;
8991 event.frame_or_window = frame;
8992 event.arg = frame;
8993 kbd_buffer_store_event (&event);
8994
8995 event.kind = TOOL_BAR_EVENT;
8996 event.frame_or_window = frame;
8997 event.arg = key;
8998 event.modifiers = modifiers;
8999 kbd_buffer_store_event (&event);
9000 last_tool_bar_item = -1;
9001 }
9002 }
9003
9004
9005 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9006 tool-bar window-relative coordinates X/Y. Called from
9007 note_mouse_highlight. */
9008
9009 static void
9010 note_tool_bar_highlight (f, x, y)
9011 struct frame *f;
9012 int x, y;
9013 {
9014 Lisp_Object window = f->tool_bar_window;
9015 struct window *w = XWINDOW (window);
9016 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9017 int hpos, vpos;
9018 struct glyph *glyph;
9019 struct glyph_row *row;
9020 int i;
9021 Lisp_Object enabled_p;
9022 int prop_idx;
9023 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9024 int mouse_down_p, rc;
9025
9026 /* Function note_mouse_highlight is called with negative x(y
9027 values when mouse moves outside of the frame. */
9028 if (x <= 0 || y <= 0)
9029 {
9030 clear_mouse_face (dpyinfo);
9031 return;
9032 }
9033
9034 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9035 if (rc < 0)
9036 {
9037 /* Not on tool-bar item. */
9038 clear_mouse_face (dpyinfo);
9039 return;
9040 }
9041 else if (rc == 0)
9042 /* On same tool-bar item as before. */
9043 goto set_help_echo;
9044
9045 clear_mouse_face (dpyinfo);
9046
9047 /* Mouse is down, but on different tool-bar item? */
9048 mouse_down_p = (dpyinfo->grabbed
9049 && f == last_mouse_frame
9050 && FRAME_LIVE_P (f));
9051 if (mouse_down_p
9052 && last_tool_bar_item != prop_idx)
9053 return;
9054
9055 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9056 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9057
9058 /* If tool-bar item is not enabled, don't highlight it. */
9059 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9060 if (!NILP (enabled_p))
9061 {
9062 /* Compute the x-position of the glyph. In front and past the
9063 image is a space. We include this in the highlighted area. */
9064 row = MATRIX_ROW (w->current_matrix, vpos);
9065 for (i = x = 0; i < hpos; ++i)
9066 x += row->glyphs[TEXT_AREA][i].pixel_width;
9067
9068 /* Record this as the current active region. */
9069 dpyinfo->mouse_face_beg_col = hpos;
9070 dpyinfo->mouse_face_beg_row = vpos;
9071 dpyinfo->mouse_face_beg_x = x;
9072 dpyinfo->mouse_face_beg_y = row->y;
9073 dpyinfo->mouse_face_past_end = 0;
9074
9075 dpyinfo->mouse_face_end_col = hpos + 1;
9076 dpyinfo->mouse_face_end_row = vpos;
9077 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9078 dpyinfo->mouse_face_end_y = row->y;
9079 dpyinfo->mouse_face_window = window;
9080 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9081
9082 /* Display it as active. */
9083 show_mouse_face (dpyinfo, draw);
9084 dpyinfo->mouse_face_image_state = draw;
9085 }
9086
9087 set_help_echo:
9088
9089 /* Set help_echo_string to a help string to display for this tool-bar item.
9090 XTread_socket does the rest. */
9091 help_echo_object = help_echo_window = Qnil;
9092 help_echo_pos = -1;
9093 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9094 if (NILP (help_echo_string))
9095 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9096 }
9097
9098 #endif /* HAVE_WINDOW_SYSTEM */
9099
9100
9101 \f
9102 /************************************************************************
9103 Horizontal scrolling
9104 ************************************************************************/
9105
9106 static int hscroll_window_tree P_ ((Lisp_Object));
9107 static int hscroll_windows P_ ((Lisp_Object));
9108
9109 /* For all leaf windows in the window tree rooted at WINDOW, set their
9110 hscroll value so that PT is (i) visible in the window, and (ii) so
9111 that it is not within a certain margin at the window's left and
9112 right border. Value is non-zero if any window's hscroll has been
9113 changed. */
9114
9115 static int
9116 hscroll_window_tree (window)
9117 Lisp_Object window;
9118 {
9119 int hscrolled_p = 0;
9120 int hscroll_relative_p = FLOATP (Vhscroll_step);
9121 int hscroll_step_abs = 0;
9122 double hscroll_step_rel = 0;
9123
9124 if (hscroll_relative_p)
9125 {
9126 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9127 if (hscroll_step_rel < 0)
9128 {
9129 hscroll_relative_p = 0;
9130 hscroll_step_abs = 0;
9131 }
9132 }
9133 else if (INTEGERP (Vhscroll_step))
9134 {
9135 hscroll_step_abs = XINT (Vhscroll_step);
9136 if (hscroll_step_abs < 0)
9137 hscroll_step_abs = 0;
9138 }
9139 else
9140 hscroll_step_abs = 0;
9141
9142 while (WINDOWP (window))
9143 {
9144 struct window *w = XWINDOW (window);
9145
9146 if (WINDOWP (w->hchild))
9147 hscrolled_p |= hscroll_window_tree (w->hchild);
9148 else if (WINDOWP (w->vchild))
9149 hscrolled_p |= hscroll_window_tree (w->vchild);
9150 else if (w->cursor.vpos >= 0)
9151 {
9152 int h_margin;
9153 int text_area_width;
9154 struct glyph_row *current_cursor_row
9155 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9156 struct glyph_row *desired_cursor_row
9157 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9158 struct glyph_row *cursor_row
9159 = (desired_cursor_row->enabled_p
9160 ? desired_cursor_row
9161 : current_cursor_row);
9162
9163 text_area_width = window_box_width (w, TEXT_AREA);
9164
9165 /* Scroll when cursor is inside this scroll margin. */
9166 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9167
9168 if ((XFASTINT (w->hscroll)
9169 && w->cursor.x <= h_margin)
9170 || (cursor_row->enabled_p
9171 && cursor_row->truncated_on_right_p
9172 && (w->cursor.x >= text_area_width - h_margin)))
9173 {
9174 struct it it;
9175 int hscroll;
9176 struct buffer *saved_current_buffer;
9177 int pt;
9178 int wanted_x;
9179
9180 /* Find point in a display of infinite width. */
9181 saved_current_buffer = current_buffer;
9182 current_buffer = XBUFFER (w->buffer);
9183
9184 if (w == XWINDOW (selected_window))
9185 pt = BUF_PT (current_buffer);
9186 else
9187 {
9188 pt = marker_position (w->pointm);
9189 pt = max (BEGV, pt);
9190 pt = min (ZV, pt);
9191 }
9192
9193 /* Move iterator to pt starting at cursor_row->start in
9194 a line with infinite width. */
9195 init_to_row_start (&it, w, cursor_row);
9196 it.last_visible_x = INFINITY;
9197 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9198 current_buffer = saved_current_buffer;
9199
9200 /* Position cursor in window. */
9201 if (!hscroll_relative_p && hscroll_step_abs == 0)
9202 hscroll = max (0, (it.current_x
9203 - (ITERATOR_AT_END_OF_LINE_P (&it)
9204 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9205 : (text_area_width / 2))))
9206 / FRAME_COLUMN_WIDTH (it.f);
9207 else if (w->cursor.x >= text_area_width - h_margin)
9208 {
9209 if (hscroll_relative_p)
9210 wanted_x = text_area_width * (1 - hscroll_step_rel)
9211 - h_margin;
9212 else
9213 wanted_x = text_area_width
9214 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9215 - h_margin;
9216 hscroll
9217 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9218 }
9219 else
9220 {
9221 if (hscroll_relative_p)
9222 wanted_x = text_area_width * hscroll_step_rel
9223 + h_margin;
9224 else
9225 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9226 + h_margin;
9227 hscroll
9228 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9229 }
9230 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9231
9232 /* Don't call Fset_window_hscroll if value hasn't
9233 changed because it will prevent redisplay
9234 optimizations. */
9235 if (XFASTINT (w->hscroll) != hscroll)
9236 {
9237 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9238 w->hscroll = make_number (hscroll);
9239 hscrolled_p = 1;
9240 }
9241 }
9242 }
9243
9244 window = w->next;
9245 }
9246
9247 /* Value is non-zero if hscroll of any leaf window has been changed. */
9248 return hscrolled_p;
9249 }
9250
9251
9252 /* Set hscroll so that cursor is visible and not inside horizontal
9253 scroll margins for all windows in the tree rooted at WINDOW. See
9254 also hscroll_window_tree above. Value is non-zero if any window's
9255 hscroll has been changed. If it has, desired matrices on the frame
9256 of WINDOW are cleared. */
9257
9258 static int
9259 hscroll_windows (window)
9260 Lisp_Object window;
9261 {
9262 int hscrolled_p;
9263
9264 if (automatic_hscrolling_p)
9265 {
9266 hscrolled_p = hscroll_window_tree (window);
9267 if (hscrolled_p)
9268 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9269 }
9270 else
9271 hscrolled_p = 0;
9272 return hscrolled_p;
9273 }
9274
9275
9276 \f
9277 /************************************************************************
9278 Redisplay
9279 ************************************************************************/
9280
9281 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9282 to a non-zero value. This is sometimes handy to have in a debugger
9283 session. */
9284
9285 #if GLYPH_DEBUG
9286
9287 /* First and last unchanged row for try_window_id. */
9288
9289 int debug_first_unchanged_at_end_vpos;
9290 int debug_last_unchanged_at_beg_vpos;
9291
9292 /* Delta vpos and y. */
9293
9294 int debug_dvpos, debug_dy;
9295
9296 /* Delta in characters and bytes for try_window_id. */
9297
9298 int debug_delta, debug_delta_bytes;
9299
9300 /* Values of window_end_pos and window_end_vpos at the end of
9301 try_window_id. */
9302
9303 EMACS_INT debug_end_pos, debug_end_vpos;
9304
9305 /* Append a string to W->desired_matrix->method. FMT is a printf
9306 format string. A1...A9 are a supplement for a variable-length
9307 argument list. If trace_redisplay_p is non-zero also printf the
9308 resulting string to stderr. */
9309
9310 static void
9311 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9312 struct window *w;
9313 char *fmt;
9314 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9315 {
9316 char buffer[512];
9317 char *method = w->desired_matrix->method;
9318 int len = strlen (method);
9319 int size = sizeof w->desired_matrix->method;
9320 int remaining = size - len - 1;
9321
9322 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9323 if (len && remaining)
9324 {
9325 method[len] = '|';
9326 --remaining, ++len;
9327 }
9328
9329 strncpy (method + len, buffer, remaining);
9330
9331 if (trace_redisplay_p)
9332 fprintf (stderr, "%p (%s): %s\n",
9333 w,
9334 ((BUFFERP (w->buffer)
9335 && STRINGP (XBUFFER (w->buffer)->name))
9336 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9337 : "no buffer"),
9338 buffer);
9339 }
9340
9341 #endif /* GLYPH_DEBUG */
9342
9343
9344 /* Value is non-zero if all changes in window W, which displays
9345 current_buffer, are in the text between START and END. START is a
9346 buffer position, END is given as a distance from Z. Used in
9347 redisplay_internal for display optimization. */
9348
9349 static INLINE int
9350 text_outside_line_unchanged_p (w, start, end)
9351 struct window *w;
9352 int start, end;
9353 {
9354 int unchanged_p = 1;
9355
9356 /* If text or overlays have changed, see where. */
9357 if (XFASTINT (w->last_modified) < MODIFF
9358 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9359 {
9360 /* Gap in the line? */
9361 if (GPT < start || Z - GPT < end)
9362 unchanged_p = 0;
9363
9364 /* Changes start in front of the line, or end after it? */
9365 if (unchanged_p
9366 && (BEG_UNCHANGED < start - 1
9367 || END_UNCHANGED < end))
9368 unchanged_p = 0;
9369
9370 /* If selective display, can't optimize if changes start at the
9371 beginning of the line. */
9372 if (unchanged_p
9373 && INTEGERP (current_buffer->selective_display)
9374 && XINT (current_buffer->selective_display) > 0
9375 && (BEG_UNCHANGED < start || GPT <= start))
9376 unchanged_p = 0;
9377
9378 /* If there are overlays at the start or end of the line, these
9379 may have overlay strings with newlines in them. A change at
9380 START, for instance, may actually concern the display of such
9381 overlay strings as well, and they are displayed on different
9382 lines. So, quickly rule out this case. (For the future, it
9383 might be desirable to implement something more telling than
9384 just BEG/END_UNCHANGED.) */
9385 if (unchanged_p)
9386 {
9387 if (BEG + BEG_UNCHANGED == start
9388 && overlay_touches_p (start))
9389 unchanged_p = 0;
9390 if (END_UNCHANGED == end
9391 && overlay_touches_p (Z - end))
9392 unchanged_p = 0;
9393 }
9394 }
9395
9396 return unchanged_p;
9397 }
9398
9399
9400 /* Do a frame update, taking possible shortcuts into account. This is
9401 the main external entry point for redisplay.
9402
9403 If the last redisplay displayed an echo area message and that message
9404 is no longer requested, we clear the echo area or bring back the
9405 mini-buffer if that is in use. */
9406
9407 void
9408 redisplay ()
9409 {
9410 redisplay_internal (0);
9411 }
9412
9413
9414 static Lisp_Object
9415 overlay_arrow_string_or_property (var, pbitmap)
9416 Lisp_Object var;
9417 int *pbitmap;
9418 {
9419 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9420 Lisp_Object bitmap;
9421
9422 if (pbitmap)
9423 {
9424 *pbitmap = 0;
9425 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9426 *pbitmap = XINT (bitmap);
9427 }
9428
9429 if (!NILP (pstr))
9430 return pstr;
9431 return Voverlay_arrow_string;
9432 }
9433
9434 /* Return 1 if there are any overlay-arrows in current_buffer. */
9435 static int
9436 overlay_arrow_in_current_buffer_p ()
9437 {
9438 Lisp_Object vlist;
9439
9440 for (vlist = Voverlay_arrow_variable_list;
9441 CONSP (vlist);
9442 vlist = XCDR (vlist))
9443 {
9444 Lisp_Object var = XCAR (vlist);
9445 Lisp_Object val;
9446
9447 if (!SYMBOLP (var))
9448 continue;
9449 val = find_symbol_value (var);
9450 if (MARKERP (val)
9451 && current_buffer == XMARKER (val)->buffer)
9452 return 1;
9453 }
9454 return 0;
9455 }
9456
9457
9458 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9459 has changed. */
9460
9461 static int
9462 overlay_arrows_changed_p ()
9463 {
9464 Lisp_Object vlist;
9465
9466 for (vlist = Voverlay_arrow_variable_list;
9467 CONSP (vlist);
9468 vlist = XCDR (vlist))
9469 {
9470 Lisp_Object var = XCAR (vlist);
9471 Lisp_Object val, pstr;
9472
9473 if (!SYMBOLP (var))
9474 continue;
9475 val = find_symbol_value (var);
9476 if (!MARKERP (val))
9477 continue;
9478 if (! EQ (COERCE_MARKER (val),
9479 Fget (var, Qlast_arrow_position))
9480 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9481 EQ (pstr, Fget (var, Qlast_arrow_string))))
9482 return 1;
9483 }
9484 return 0;
9485 }
9486
9487 /* Mark overlay arrows to be updated on next redisplay. */
9488
9489 static void
9490 update_overlay_arrows (up_to_date)
9491 int up_to_date;
9492 {
9493 Lisp_Object vlist;
9494
9495 for (vlist = Voverlay_arrow_variable_list;
9496 CONSP (vlist);
9497 vlist = XCDR (vlist))
9498 {
9499 Lisp_Object var = XCAR (vlist);
9500
9501 if (!SYMBOLP (var))
9502 continue;
9503
9504 if (up_to_date > 0)
9505 {
9506 Lisp_Object val = find_symbol_value (var);
9507 Fput (var, Qlast_arrow_position,
9508 COERCE_MARKER (val));
9509 Fput (var, Qlast_arrow_string,
9510 overlay_arrow_string_or_property (var, 0));
9511 }
9512 else if (up_to_date < 0
9513 || !NILP (Fget (var, Qlast_arrow_position)))
9514 {
9515 Fput (var, Qlast_arrow_position, Qt);
9516 Fput (var, Qlast_arrow_string, Qt);
9517 }
9518 }
9519 }
9520
9521
9522 /* Return overlay arrow string at row, or nil. */
9523
9524 static Lisp_Object
9525 overlay_arrow_at_row (f, row, pbitmap)
9526 struct frame *f;
9527 struct glyph_row *row;
9528 int *pbitmap;
9529 {
9530 Lisp_Object vlist;
9531
9532 for (vlist = Voverlay_arrow_variable_list;
9533 CONSP (vlist);
9534 vlist = XCDR (vlist))
9535 {
9536 Lisp_Object var = XCAR (vlist);
9537 Lisp_Object val;
9538
9539 if (!SYMBOLP (var))
9540 continue;
9541
9542 val = find_symbol_value (var);
9543
9544 if (MARKERP (val)
9545 && current_buffer == XMARKER (val)->buffer
9546 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9547 {
9548 val = overlay_arrow_string_or_property (var, pbitmap);
9549 if (FRAME_WINDOW_P (f))
9550 return Qt;
9551 else if (STRINGP (val))
9552 return val;
9553 break;
9554 }
9555 }
9556
9557 *pbitmap = 0;
9558 return Qnil;
9559 }
9560
9561 /* Return 1 if point moved out of or into a composition. Otherwise
9562 return 0. PREV_BUF and PREV_PT are the last point buffer and
9563 position. BUF and PT are the current point buffer and position. */
9564
9565 int
9566 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9567 struct buffer *prev_buf, *buf;
9568 int prev_pt, pt;
9569 {
9570 int start, end;
9571 Lisp_Object prop;
9572 Lisp_Object buffer;
9573
9574 XSETBUFFER (buffer, buf);
9575 /* Check a composition at the last point if point moved within the
9576 same buffer. */
9577 if (prev_buf == buf)
9578 {
9579 if (prev_pt == pt)
9580 /* Point didn't move. */
9581 return 0;
9582
9583 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9584 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9585 && COMPOSITION_VALID_P (start, end, prop)
9586 && start < prev_pt && end > prev_pt)
9587 /* The last point was within the composition. Return 1 iff
9588 point moved out of the composition. */
9589 return (pt <= start || pt >= end);
9590 }
9591
9592 /* Check a composition at the current point. */
9593 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9594 && find_composition (pt, -1, &start, &end, &prop, buffer)
9595 && COMPOSITION_VALID_P (start, end, prop)
9596 && start < pt && end > pt);
9597 }
9598
9599
9600 /* Reconsider the setting of B->clip_changed which is displayed
9601 in window W. */
9602
9603 static INLINE void
9604 reconsider_clip_changes (w, b)
9605 struct window *w;
9606 struct buffer *b;
9607 {
9608 if (b->clip_changed
9609 && !NILP (w->window_end_valid)
9610 && w->current_matrix->buffer == b
9611 && w->current_matrix->zv == BUF_ZV (b)
9612 && w->current_matrix->begv == BUF_BEGV (b))
9613 b->clip_changed = 0;
9614
9615 /* If display wasn't paused, and W is not a tool bar window, see if
9616 point has been moved into or out of a composition. In that case,
9617 we set b->clip_changed to 1 to force updating the screen. If
9618 b->clip_changed has already been set to 1, we can skip this
9619 check. */
9620 if (!b->clip_changed
9621 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9622 {
9623 int pt;
9624
9625 if (w == XWINDOW (selected_window))
9626 pt = BUF_PT (current_buffer);
9627 else
9628 pt = marker_position (w->pointm);
9629
9630 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9631 || pt != XINT (w->last_point))
9632 && check_point_in_composition (w->current_matrix->buffer,
9633 XINT (w->last_point),
9634 XBUFFER (w->buffer), pt))
9635 b->clip_changed = 1;
9636 }
9637 }
9638 \f
9639
9640 /* Select FRAME to forward the values of frame-local variables into C
9641 variables so that the redisplay routines can access those values
9642 directly. */
9643
9644 static void
9645 select_frame_for_redisplay (frame)
9646 Lisp_Object frame;
9647 {
9648 Lisp_Object tail, sym, val;
9649 Lisp_Object old = selected_frame;
9650
9651 selected_frame = frame;
9652
9653 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9654 if (CONSP (XCAR (tail))
9655 && (sym = XCAR (XCAR (tail)),
9656 SYMBOLP (sym))
9657 && (sym = indirect_variable (sym),
9658 val = SYMBOL_VALUE (sym),
9659 (BUFFER_LOCAL_VALUEP (val)
9660 || SOME_BUFFER_LOCAL_VALUEP (val)))
9661 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9662 Fsymbol_value (sym);
9663
9664 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9665 if (CONSP (XCAR (tail))
9666 && (sym = XCAR (XCAR (tail)),
9667 SYMBOLP (sym))
9668 && (sym = indirect_variable (sym),
9669 val = SYMBOL_VALUE (sym),
9670 (BUFFER_LOCAL_VALUEP (val)
9671 || SOME_BUFFER_LOCAL_VALUEP (val)))
9672 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9673 Fsymbol_value (sym);
9674 }
9675
9676
9677 #define STOP_POLLING \
9678 do { if (! polling_stopped_here) stop_polling (); \
9679 polling_stopped_here = 1; } while (0)
9680
9681 #define RESUME_POLLING \
9682 do { if (polling_stopped_here) start_polling (); \
9683 polling_stopped_here = 0; } while (0)
9684
9685
9686 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9687 response to any user action; therefore, we should preserve the echo
9688 area. (Actually, our caller does that job.) Perhaps in the future
9689 avoid recentering windows if it is not necessary; currently that
9690 causes some problems. */
9691
9692 static void
9693 redisplay_internal (preserve_echo_area)
9694 int preserve_echo_area;
9695 {
9696 struct window *w = XWINDOW (selected_window);
9697 struct frame *f = XFRAME (w->frame);
9698 int pause;
9699 int must_finish = 0;
9700 struct text_pos tlbufpos, tlendpos;
9701 int number_of_visible_frames;
9702 int count;
9703 struct frame *sf = SELECTED_FRAME ();
9704 int polling_stopped_here = 0;
9705
9706 /* Non-zero means redisplay has to consider all windows on all
9707 frames. Zero means, only selected_window is considered. */
9708 int consider_all_windows_p;
9709
9710 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9711
9712 /* No redisplay if running in batch mode or frame is not yet fully
9713 initialized, or redisplay is explicitly turned off by setting
9714 Vinhibit_redisplay. */
9715 if (noninteractive
9716 || !NILP (Vinhibit_redisplay)
9717 || !f->glyphs_initialized_p)
9718 return;
9719
9720 /* The flag redisplay_performed_directly_p is set by
9721 direct_output_for_insert when it already did the whole screen
9722 update necessary. */
9723 if (redisplay_performed_directly_p)
9724 {
9725 redisplay_performed_directly_p = 0;
9726 if (!hscroll_windows (selected_window))
9727 return;
9728 }
9729
9730 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9731 if (popup_activated ())
9732 return;
9733 #endif
9734
9735 /* I don't think this happens but let's be paranoid. */
9736 if (redisplaying_p)
9737 return;
9738
9739 /* Record a function that resets redisplaying_p to its old value
9740 when we leave this function. */
9741 count = SPECPDL_INDEX ();
9742 record_unwind_protect (unwind_redisplay,
9743 Fcons (make_number (redisplaying_p), selected_frame));
9744 ++redisplaying_p;
9745 specbind (Qinhibit_free_realized_faces, Qnil);
9746
9747 retry:
9748 pause = 0;
9749 reconsider_clip_changes (w, current_buffer);
9750
9751 /* If new fonts have been loaded that make a glyph matrix adjustment
9752 necessary, do it. */
9753 if (fonts_changed_p)
9754 {
9755 adjust_glyphs (NULL);
9756 ++windows_or_buffers_changed;
9757 fonts_changed_p = 0;
9758 }
9759
9760 /* If face_change_count is non-zero, init_iterator will free all
9761 realized faces, which includes the faces referenced from current
9762 matrices. So, we can't reuse current matrices in this case. */
9763 if (face_change_count)
9764 ++windows_or_buffers_changed;
9765
9766 if (! FRAME_WINDOW_P (sf)
9767 && previous_terminal_frame != sf)
9768 {
9769 /* Since frames on an ASCII terminal share the same display
9770 area, displaying a different frame means redisplay the whole
9771 thing. */
9772 windows_or_buffers_changed++;
9773 SET_FRAME_GARBAGED (sf);
9774 XSETFRAME (Vterminal_frame, sf);
9775 }
9776 previous_terminal_frame = sf;
9777
9778 /* Set the visible flags for all frames. Do this before checking
9779 for resized or garbaged frames; they want to know if their frames
9780 are visible. See the comment in frame.h for
9781 FRAME_SAMPLE_VISIBILITY. */
9782 {
9783 Lisp_Object tail, frame;
9784
9785 number_of_visible_frames = 0;
9786
9787 FOR_EACH_FRAME (tail, frame)
9788 {
9789 struct frame *f = XFRAME (frame);
9790
9791 FRAME_SAMPLE_VISIBILITY (f);
9792 if (FRAME_VISIBLE_P (f))
9793 ++number_of_visible_frames;
9794 clear_desired_matrices (f);
9795 }
9796 }
9797
9798 /* Notice any pending interrupt request to change frame size. */
9799 do_pending_window_change (1);
9800
9801 /* Clear frames marked as garbaged. */
9802 if (frame_garbaged)
9803 clear_garbaged_frames ();
9804
9805 /* Build menubar and tool-bar items. */
9806 prepare_menu_bars ();
9807
9808 if (windows_or_buffers_changed)
9809 update_mode_lines++;
9810
9811 /* Detect case that we need to write or remove a star in the mode line. */
9812 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9813 {
9814 w->update_mode_line = Qt;
9815 if (buffer_shared > 1)
9816 update_mode_lines++;
9817 }
9818
9819 /* If %c is in the mode line, update it if needed. */
9820 if (!NILP (w->column_number_displayed)
9821 /* This alternative quickly identifies a common case
9822 where no change is needed. */
9823 && !(PT == XFASTINT (w->last_point)
9824 && XFASTINT (w->last_modified) >= MODIFF
9825 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9826 && (XFASTINT (w->column_number_displayed)
9827 != (int) current_column ())) /* iftc */
9828 w->update_mode_line = Qt;
9829
9830 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9831
9832 /* The variable buffer_shared is set in redisplay_window and
9833 indicates that we redisplay a buffer in different windows. See
9834 there. */
9835 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9836 || cursor_type_changed);
9837
9838 /* If specs for an arrow have changed, do thorough redisplay
9839 to ensure we remove any arrow that should no longer exist. */
9840 if (overlay_arrows_changed_p ())
9841 consider_all_windows_p = windows_or_buffers_changed = 1;
9842
9843 /* Normally the message* functions will have already displayed and
9844 updated the echo area, but the frame may have been trashed, or
9845 the update may have been preempted, so display the echo area
9846 again here. Checking message_cleared_p captures the case that
9847 the echo area should be cleared. */
9848 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9849 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9850 || (message_cleared_p
9851 && minibuf_level == 0
9852 /* If the mini-window is currently selected, this means the
9853 echo-area doesn't show through. */
9854 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9855 {
9856 int window_height_changed_p = echo_area_display (0);
9857 must_finish = 1;
9858
9859 /* If we don't display the current message, don't clear the
9860 message_cleared_p flag, because, if we did, we wouldn't clear
9861 the echo area in the next redisplay which doesn't preserve
9862 the echo area. */
9863 if (!display_last_displayed_message_p)
9864 message_cleared_p = 0;
9865
9866 if (fonts_changed_p)
9867 goto retry;
9868 else if (window_height_changed_p)
9869 {
9870 consider_all_windows_p = 1;
9871 ++update_mode_lines;
9872 ++windows_or_buffers_changed;
9873
9874 /* If window configuration was changed, frames may have been
9875 marked garbaged. Clear them or we will experience
9876 surprises wrt scrolling. */
9877 if (frame_garbaged)
9878 clear_garbaged_frames ();
9879 }
9880 }
9881 else if (EQ (selected_window, minibuf_window)
9882 && (current_buffer->clip_changed
9883 || XFASTINT (w->last_modified) < MODIFF
9884 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9885 && resize_mini_window (w, 0))
9886 {
9887 /* Resized active mini-window to fit the size of what it is
9888 showing if its contents might have changed. */
9889 must_finish = 1;
9890 consider_all_windows_p = 1;
9891 ++windows_or_buffers_changed;
9892 ++update_mode_lines;
9893
9894 /* If window configuration was changed, frames may have been
9895 marked garbaged. Clear them or we will experience
9896 surprises wrt scrolling. */
9897 if (frame_garbaged)
9898 clear_garbaged_frames ();
9899 }
9900
9901
9902 /* If showing the region, and mark has changed, we must redisplay
9903 the whole window. The assignment to this_line_start_pos prevents
9904 the optimization directly below this if-statement. */
9905 if (((!NILP (Vtransient_mark_mode)
9906 && !NILP (XBUFFER (w->buffer)->mark_active))
9907 != !NILP (w->region_showing))
9908 || (!NILP (w->region_showing)
9909 && !EQ (w->region_showing,
9910 Fmarker_position (XBUFFER (w->buffer)->mark))))
9911 CHARPOS (this_line_start_pos) = 0;
9912
9913 /* Optimize the case that only the line containing the cursor in the
9914 selected window has changed. Variables starting with this_ are
9915 set in display_line and record information about the line
9916 containing the cursor. */
9917 tlbufpos = this_line_start_pos;
9918 tlendpos = this_line_end_pos;
9919 if (!consider_all_windows_p
9920 && CHARPOS (tlbufpos) > 0
9921 && NILP (w->update_mode_line)
9922 && !current_buffer->clip_changed
9923 && !current_buffer->prevent_redisplay_optimizations_p
9924 && FRAME_VISIBLE_P (XFRAME (w->frame))
9925 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9926 /* Make sure recorded data applies to current buffer, etc. */
9927 && this_line_buffer == current_buffer
9928 && current_buffer == XBUFFER (w->buffer)
9929 && NILP (w->force_start)
9930 && NILP (w->optional_new_start)
9931 /* Point must be on the line that we have info recorded about. */
9932 && PT >= CHARPOS (tlbufpos)
9933 && PT <= Z - CHARPOS (tlendpos)
9934 /* All text outside that line, including its final newline,
9935 must be unchanged */
9936 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9937 CHARPOS (tlendpos)))
9938 {
9939 if (CHARPOS (tlbufpos) > BEGV
9940 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9941 && (CHARPOS (tlbufpos) == ZV
9942 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9943 /* Former continuation line has disappeared by becoming empty */
9944 goto cancel;
9945 else if (XFASTINT (w->last_modified) < MODIFF
9946 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9947 || MINI_WINDOW_P (w))
9948 {
9949 /* We have to handle the case of continuation around a
9950 wide-column character (See the comment in indent.c around
9951 line 885).
9952
9953 For instance, in the following case:
9954
9955 -------- Insert --------
9956 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9957 J_I_ ==> J_I_ `^^' are cursors.
9958 ^^ ^^
9959 -------- --------
9960
9961 As we have to redraw the line above, we should goto cancel. */
9962
9963 struct it it;
9964 int line_height_before = this_line_pixel_height;
9965
9966 /* Note that start_display will handle the case that the
9967 line starting at tlbufpos is a continuation lines. */
9968 start_display (&it, w, tlbufpos);
9969
9970 /* Implementation note: It this still necessary? */
9971 if (it.current_x != this_line_start_x)
9972 goto cancel;
9973
9974 TRACE ((stderr, "trying display optimization 1\n"));
9975 w->cursor.vpos = -1;
9976 overlay_arrow_seen = 0;
9977 it.vpos = this_line_vpos;
9978 it.current_y = this_line_y;
9979 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9980 display_line (&it);
9981
9982 /* If line contains point, is not continued,
9983 and ends at same distance from eob as before, we win */
9984 if (w->cursor.vpos >= 0
9985 /* Line is not continued, otherwise this_line_start_pos
9986 would have been set to 0 in display_line. */
9987 && CHARPOS (this_line_start_pos)
9988 /* Line ends as before. */
9989 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9990 /* Line has same height as before. Otherwise other lines
9991 would have to be shifted up or down. */
9992 && this_line_pixel_height == line_height_before)
9993 {
9994 /* If this is not the window's last line, we must adjust
9995 the charstarts of the lines below. */
9996 if (it.current_y < it.last_visible_y)
9997 {
9998 struct glyph_row *row
9999 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10000 int delta, delta_bytes;
10001
10002 if (Z - CHARPOS (tlendpos) == ZV)
10003 {
10004 /* This line ends at end of (accessible part of)
10005 buffer. There is no newline to count. */
10006 delta = (Z
10007 - CHARPOS (tlendpos)
10008 - MATRIX_ROW_START_CHARPOS (row));
10009 delta_bytes = (Z_BYTE
10010 - BYTEPOS (tlendpos)
10011 - MATRIX_ROW_START_BYTEPOS (row));
10012 }
10013 else
10014 {
10015 /* This line ends in a newline. Must take
10016 account of the newline and the rest of the
10017 text that follows. */
10018 delta = (Z
10019 - CHARPOS (tlendpos)
10020 - MATRIX_ROW_START_CHARPOS (row));
10021 delta_bytes = (Z_BYTE
10022 - BYTEPOS (tlendpos)
10023 - MATRIX_ROW_START_BYTEPOS (row));
10024 }
10025
10026 increment_matrix_positions (w->current_matrix,
10027 this_line_vpos + 1,
10028 w->current_matrix->nrows,
10029 delta, delta_bytes);
10030 }
10031
10032 /* If this row displays text now but previously didn't,
10033 or vice versa, w->window_end_vpos may have to be
10034 adjusted. */
10035 if ((it.glyph_row - 1)->displays_text_p)
10036 {
10037 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10038 XSETINT (w->window_end_vpos, this_line_vpos);
10039 }
10040 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10041 && this_line_vpos > 0)
10042 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10043 w->window_end_valid = Qnil;
10044
10045 /* Update hint: No need to try to scroll in update_window. */
10046 w->desired_matrix->no_scrolling_p = 1;
10047
10048 #if GLYPH_DEBUG
10049 *w->desired_matrix->method = 0;
10050 debug_method_add (w, "optimization 1");
10051 #endif
10052 #ifdef HAVE_WINDOW_SYSTEM
10053 update_window_fringes (w, 0);
10054 #endif
10055 goto update;
10056 }
10057 else
10058 goto cancel;
10059 }
10060 else if (/* Cursor position hasn't changed. */
10061 PT == XFASTINT (w->last_point)
10062 /* Make sure the cursor was last displayed
10063 in this window. Otherwise we have to reposition it. */
10064 && 0 <= w->cursor.vpos
10065 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10066 {
10067 if (!must_finish)
10068 {
10069 do_pending_window_change (1);
10070
10071 /* We used to always goto end_of_redisplay here, but this
10072 isn't enough if we have a blinking cursor. */
10073 if (w->cursor_off_p == w->last_cursor_off_p)
10074 goto end_of_redisplay;
10075 }
10076 goto update;
10077 }
10078 /* If highlighting the region, or if the cursor is in the echo area,
10079 then we can't just move the cursor. */
10080 else if (! (!NILP (Vtransient_mark_mode)
10081 && !NILP (current_buffer->mark_active))
10082 && (EQ (selected_window, current_buffer->last_selected_window)
10083 || highlight_nonselected_windows)
10084 && NILP (w->region_showing)
10085 && NILP (Vshow_trailing_whitespace)
10086 && !cursor_in_echo_area)
10087 {
10088 struct it it;
10089 struct glyph_row *row;
10090
10091 /* Skip from tlbufpos to PT and see where it is. Note that
10092 PT may be in invisible text. If so, we will end at the
10093 next visible position. */
10094 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10095 NULL, DEFAULT_FACE_ID);
10096 it.current_x = this_line_start_x;
10097 it.current_y = this_line_y;
10098 it.vpos = this_line_vpos;
10099
10100 /* The call to move_it_to stops in front of PT, but
10101 moves over before-strings. */
10102 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10103
10104 if (it.vpos == this_line_vpos
10105 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10106 row->enabled_p))
10107 {
10108 xassert (this_line_vpos == it.vpos);
10109 xassert (this_line_y == it.current_y);
10110 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10111 #if GLYPH_DEBUG
10112 *w->desired_matrix->method = 0;
10113 debug_method_add (w, "optimization 3");
10114 #endif
10115 goto update;
10116 }
10117 else
10118 goto cancel;
10119 }
10120
10121 cancel:
10122 /* Text changed drastically or point moved off of line. */
10123 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10124 }
10125
10126 CHARPOS (this_line_start_pos) = 0;
10127 consider_all_windows_p |= buffer_shared > 1;
10128 ++clear_face_cache_count;
10129
10130
10131 /* Build desired matrices, and update the display. If
10132 consider_all_windows_p is non-zero, do it for all windows on all
10133 frames. Otherwise do it for selected_window, only. */
10134
10135 if (consider_all_windows_p)
10136 {
10137 Lisp_Object tail, frame;
10138 int i, n = 0, size = 50;
10139 struct frame **updated
10140 = (struct frame **) alloca (size * sizeof *updated);
10141
10142 /* Clear the face cache eventually. */
10143 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10144 {
10145 clear_face_cache (0);
10146 clear_face_cache_count = 0;
10147 }
10148
10149 /* Recompute # windows showing selected buffer. This will be
10150 incremented each time such a window is displayed. */
10151 buffer_shared = 0;
10152
10153 FOR_EACH_FRAME (tail, frame)
10154 {
10155 struct frame *f = XFRAME (frame);
10156
10157 if (FRAME_WINDOW_P (f) || f == sf)
10158 {
10159 if (! EQ (frame, selected_frame))
10160 /* Select the frame, for the sake of frame-local
10161 variables. */
10162 select_frame_for_redisplay (frame);
10163
10164 #ifdef HAVE_WINDOW_SYSTEM
10165 if (clear_face_cache_count % 50 == 0
10166 && FRAME_WINDOW_P (f))
10167 clear_image_cache (f, 0);
10168 #endif /* HAVE_WINDOW_SYSTEM */
10169
10170 /* Mark all the scroll bars to be removed; we'll redeem
10171 the ones we want when we redisplay their windows. */
10172 if (condemn_scroll_bars_hook)
10173 condemn_scroll_bars_hook (f);
10174
10175 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10176 redisplay_windows (FRAME_ROOT_WINDOW (f));
10177
10178 /* Any scroll bars which redisplay_windows should have
10179 nuked should now go away. */
10180 if (judge_scroll_bars_hook)
10181 judge_scroll_bars_hook (f);
10182
10183 /* If fonts changed, display again. */
10184 /* ??? rms: I suspect it is a mistake to jump all the way
10185 back to retry here. It should just retry this frame. */
10186 if (fonts_changed_p)
10187 goto retry;
10188
10189 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10190 {
10191 /* See if we have to hscroll. */
10192 if (hscroll_windows (f->root_window))
10193 goto retry;
10194
10195 /* Prevent various kinds of signals during display
10196 update. stdio is not robust about handling
10197 signals, which can cause an apparent I/O
10198 error. */
10199 if (interrupt_input)
10200 unrequest_sigio ();
10201 STOP_POLLING;
10202
10203 /* Update the display. */
10204 set_window_update_flags (XWINDOW (f->root_window), 1);
10205 pause |= update_frame (f, 0, 0);
10206 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10207 if (pause)
10208 break;
10209 #endif
10210
10211 if (n == size)
10212 {
10213 int nbytes = size * sizeof *updated;
10214 struct frame **p = (struct frame **) alloca (2 * nbytes);
10215 bcopy (updated, p, nbytes);
10216 size *= 2;
10217 }
10218
10219 updated[n++] = f;
10220 }
10221 }
10222 }
10223
10224 if (!pause)
10225 {
10226 /* Do the mark_window_display_accurate after all windows have
10227 been redisplayed because this call resets flags in buffers
10228 which are needed for proper redisplay. */
10229 for (i = 0; i < n; ++i)
10230 {
10231 struct frame *f = updated[i];
10232 mark_window_display_accurate (f->root_window, 1);
10233 if (frame_up_to_date_hook)
10234 frame_up_to_date_hook (f);
10235 }
10236 }
10237 }
10238 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10239 {
10240 Lisp_Object mini_window;
10241 struct frame *mini_frame;
10242
10243 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10244 /* Use list_of_error, not Qerror, so that
10245 we catch only errors and don't run the debugger. */
10246 internal_condition_case_1 (redisplay_window_1, selected_window,
10247 list_of_error,
10248 redisplay_window_error);
10249
10250 /* Compare desired and current matrices, perform output. */
10251
10252 update:
10253 /* If fonts changed, display again. */
10254 if (fonts_changed_p)
10255 goto retry;
10256
10257 /* Prevent various kinds of signals during display update.
10258 stdio is not robust about handling signals,
10259 which can cause an apparent I/O error. */
10260 if (interrupt_input)
10261 unrequest_sigio ();
10262 STOP_POLLING;
10263
10264 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10265 {
10266 if (hscroll_windows (selected_window))
10267 goto retry;
10268
10269 XWINDOW (selected_window)->must_be_updated_p = 1;
10270 pause = update_frame (sf, 0, 0);
10271 }
10272
10273 /* We may have called echo_area_display at the top of this
10274 function. If the echo area is on another frame, that may
10275 have put text on a frame other than the selected one, so the
10276 above call to update_frame would not have caught it. Catch
10277 it here. */
10278 mini_window = FRAME_MINIBUF_WINDOW (sf);
10279 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10280
10281 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10282 {
10283 XWINDOW (mini_window)->must_be_updated_p = 1;
10284 pause |= update_frame (mini_frame, 0, 0);
10285 if (!pause && hscroll_windows (mini_window))
10286 goto retry;
10287 }
10288 }
10289
10290 /* If display was paused because of pending input, make sure we do a
10291 thorough update the next time. */
10292 if (pause)
10293 {
10294 /* Prevent the optimization at the beginning of
10295 redisplay_internal that tries a single-line update of the
10296 line containing the cursor in the selected window. */
10297 CHARPOS (this_line_start_pos) = 0;
10298
10299 /* Let the overlay arrow be updated the next time. */
10300 update_overlay_arrows (0);
10301
10302 /* If we pause after scrolling, some rows in the current
10303 matrices of some windows are not valid. */
10304 if (!WINDOW_FULL_WIDTH_P (w)
10305 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10306 update_mode_lines = 1;
10307 }
10308 else
10309 {
10310 if (!consider_all_windows_p)
10311 {
10312 /* This has already been done above if
10313 consider_all_windows_p is set. */
10314 mark_window_display_accurate_1 (w, 1);
10315
10316 /* Say overlay arrows are up to date. */
10317 update_overlay_arrows (1);
10318
10319 if (frame_up_to_date_hook != 0)
10320 frame_up_to_date_hook (sf);
10321 }
10322
10323 update_mode_lines = 0;
10324 windows_or_buffers_changed = 0;
10325 cursor_type_changed = 0;
10326 }
10327
10328 /* Start SIGIO interrupts coming again. Having them off during the
10329 code above makes it less likely one will discard output, but not
10330 impossible, since there might be stuff in the system buffer here.
10331 But it is much hairier to try to do anything about that. */
10332 if (interrupt_input)
10333 request_sigio ();
10334 RESUME_POLLING;
10335
10336 /* If a frame has become visible which was not before, redisplay
10337 again, so that we display it. Expose events for such a frame
10338 (which it gets when becoming visible) don't call the parts of
10339 redisplay constructing glyphs, so simply exposing a frame won't
10340 display anything in this case. So, we have to display these
10341 frames here explicitly. */
10342 if (!pause)
10343 {
10344 Lisp_Object tail, frame;
10345 int new_count = 0;
10346
10347 FOR_EACH_FRAME (tail, frame)
10348 {
10349 int this_is_visible = 0;
10350
10351 if (XFRAME (frame)->visible)
10352 this_is_visible = 1;
10353 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10354 if (XFRAME (frame)->visible)
10355 this_is_visible = 1;
10356
10357 if (this_is_visible)
10358 new_count++;
10359 }
10360
10361 if (new_count != number_of_visible_frames)
10362 windows_or_buffers_changed++;
10363 }
10364
10365 /* Change frame size now if a change is pending. */
10366 do_pending_window_change (1);
10367
10368 /* If we just did a pending size change, or have additional
10369 visible frames, redisplay again. */
10370 if (windows_or_buffers_changed && !pause)
10371 goto retry;
10372
10373 end_of_redisplay:
10374 unbind_to (count, Qnil);
10375 RESUME_POLLING;
10376 }
10377
10378
10379 /* Redisplay, but leave alone any recent echo area message unless
10380 another message has been requested in its place.
10381
10382 This is useful in situations where you need to redisplay but no
10383 user action has occurred, making it inappropriate for the message
10384 area to be cleared. See tracking_off and
10385 wait_reading_process_output for examples of these situations.
10386
10387 FROM_WHERE is an integer saying from where this function was
10388 called. This is useful for debugging. */
10389
10390 void
10391 redisplay_preserve_echo_area (from_where)
10392 int from_where;
10393 {
10394 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10395
10396 if (!NILP (echo_area_buffer[1]))
10397 {
10398 /* We have a previously displayed message, but no current
10399 message. Redisplay the previous message. */
10400 display_last_displayed_message_p = 1;
10401 redisplay_internal (1);
10402 display_last_displayed_message_p = 0;
10403 }
10404 else
10405 redisplay_internal (1);
10406 }
10407
10408
10409 /* Function registered with record_unwind_protect in
10410 redisplay_internal. Reset redisplaying_p to the value it had
10411 before redisplay_internal was called, and clear
10412 prevent_freeing_realized_faces_p. It also selects the previously
10413 selected frame. */
10414
10415 static Lisp_Object
10416 unwind_redisplay (val)
10417 Lisp_Object val;
10418 {
10419 Lisp_Object old_redisplaying_p, old_frame;
10420
10421 old_redisplaying_p = XCAR (val);
10422 redisplaying_p = XFASTINT (old_redisplaying_p);
10423 old_frame = XCDR (val);
10424 if (! EQ (old_frame, selected_frame))
10425 select_frame_for_redisplay (old_frame);
10426 return Qnil;
10427 }
10428
10429
10430 /* Mark the display of window W as accurate or inaccurate. If
10431 ACCURATE_P is non-zero mark display of W as accurate. If
10432 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10433 redisplay_internal is called. */
10434
10435 static void
10436 mark_window_display_accurate_1 (w, accurate_p)
10437 struct window *w;
10438 int accurate_p;
10439 {
10440 if (BUFFERP (w->buffer))
10441 {
10442 struct buffer *b = XBUFFER (w->buffer);
10443
10444 w->last_modified
10445 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10446 w->last_overlay_modified
10447 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10448 w->last_had_star
10449 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10450
10451 if (accurate_p)
10452 {
10453 b->clip_changed = 0;
10454 b->prevent_redisplay_optimizations_p = 0;
10455
10456 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10457 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10458 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10459 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10460
10461 w->current_matrix->buffer = b;
10462 w->current_matrix->begv = BUF_BEGV (b);
10463 w->current_matrix->zv = BUF_ZV (b);
10464
10465 w->last_cursor = w->cursor;
10466 w->last_cursor_off_p = w->cursor_off_p;
10467
10468 if (w == XWINDOW (selected_window))
10469 w->last_point = make_number (BUF_PT (b));
10470 else
10471 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10472 }
10473 }
10474
10475 if (accurate_p)
10476 {
10477 w->window_end_valid = w->buffer;
10478 #if 0 /* This is incorrect with variable-height lines. */
10479 xassert (XINT (w->window_end_vpos)
10480 < (WINDOW_TOTAL_LINES (w)
10481 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10482 #endif
10483 w->update_mode_line = Qnil;
10484 }
10485 }
10486
10487
10488 /* Mark the display of windows in the window tree rooted at WINDOW as
10489 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10490 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10491 be redisplayed the next time redisplay_internal is called. */
10492
10493 void
10494 mark_window_display_accurate (window, accurate_p)
10495 Lisp_Object window;
10496 int accurate_p;
10497 {
10498 struct window *w;
10499
10500 for (; !NILP (window); window = w->next)
10501 {
10502 w = XWINDOW (window);
10503 mark_window_display_accurate_1 (w, accurate_p);
10504
10505 if (!NILP (w->vchild))
10506 mark_window_display_accurate (w->vchild, accurate_p);
10507 if (!NILP (w->hchild))
10508 mark_window_display_accurate (w->hchild, accurate_p);
10509 }
10510
10511 if (accurate_p)
10512 {
10513 update_overlay_arrows (1);
10514 }
10515 else
10516 {
10517 /* Force a thorough redisplay the next time by setting
10518 last_arrow_position and last_arrow_string to t, which is
10519 unequal to any useful value of Voverlay_arrow_... */
10520 update_overlay_arrows (-1);
10521 }
10522 }
10523
10524
10525 /* Return value in display table DP (Lisp_Char_Table *) for character
10526 C. Since a display table doesn't have any parent, we don't have to
10527 follow parent. Do not call this function directly but use the
10528 macro DISP_CHAR_VECTOR. */
10529
10530 Lisp_Object
10531 disp_char_vector (dp, c)
10532 struct Lisp_Char_Table *dp;
10533 int c;
10534 {
10535 int code[4], i;
10536 Lisp_Object val;
10537
10538 if (SINGLE_BYTE_CHAR_P (c))
10539 return (dp->contents[c]);
10540
10541 SPLIT_CHAR (c, code[0], code[1], code[2]);
10542 if (code[1] < 32)
10543 code[1] = -1;
10544 else if (code[2] < 32)
10545 code[2] = -1;
10546
10547 /* Here, the possible range of code[0] (== charset ID) is
10548 128..max_charset. Since the top level char table contains data
10549 for multibyte characters after 256th element, we must increment
10550 code[0] by 128 to get a correct index. */
10551 code[0] += 128;
10552 code[3] = -1; /* anchor */
10553
10554 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10555 {
10556 val = dp->contents[code[i]];
10557 if (!SUB_CHAR_TABLE_P (val))
10558 return (NILP (val) ? dp->defalt : val);
10559 }
10560
10561 /* Here, val is a sub char table. We return the default value of
10562 it. */
10563 return (dp->defalt);
10564 }
10565
10566
10567 \f
10568 /***********************************************************************
10569 Window Redisplay
10570 ***********************************************************************/
10571
10572 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10573
10574 static void
10575 redisplay_windows (window)
10576 Lisp_Object window;
10577 {
10578 while (!NILP (window))
10579 {
10580 struct window *w = XWINDOW (window);
10581
10582 if (!NILP (w->hchild))
10583 redisplay_windows (w->hchild);
10584 else if (!NILP (w->vchild))
10585 redisplay_windows (w->vchild);
10586 else
10587 {
10588 displayed_buffer = XBUFFER (w->buffer);
10589 /* Use list_of_error, not Qerror, so that
10590 we catch only errors and don't run the debugger. */
10591 internal_condition_case_1 (redisplay_window_0, window,
10592 list_of_error,
10593 redisplay_window_error);
10594 }
10595
10596 window = w->next;
10597 }
10598 }
10599
10600 static Lisp_Object
10601 redisplay_window_error ()
10602 {
10603 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10604 return Qnil;
10605 }
10606
10607 static Lisp_Object
10608 redisplay_window_0 (window)
10609 Lisp_Object window;
10610 {
10611 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10612 redisplay_window (window, 0);
10613 return Qnil;
10614 }
10615
10616 static Lisp_Object
10617 redisplay_window_1 (window)
10618 Lisp_Object window;
10619 {
10620 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10621 redisplay_window (window, 1);
10622 return Qnil;
10623 }
10624 \f
10625
10626 /* Increment GLYPH until it reaches END or CONDITION fails while
10627 adding (GLYPH)->pixel_width to X. */
10628
10629 #define SKIP_GLYPHS(glyph, end, x, condition) \
10630 do \
10631 { \
10632 (x) += (glyph)->pixel_width; \
10633 ++(glyph); \
10634 } \
10635 while ((glyph) < (end) && (condition))
10636
10637
10638 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10639 DELTA is the number of bytes by which positions recorded in ROW
10640 differ from current buffer positions. */
10641
10642 void
10643 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10644 struct window *w;
10645 struct glyph_row *row;
10646 struct glyph_matrix *matrix;
10647 int delta, delta_bytes, dy, dvpos;
10648 {
10649 struct glyph *glyph = row->glyphs[TEXT_AREA];
10650 struct glyph *end = glyph + row->used[TEXT_AREA];
10651 struct glyph *cursor = NULL;
10652 /* The first glyph that starts a sequence of glyphs from string. */
10653 struct glyph *string_start;
10654 /* The X coordinate of string_start. */
10655 int string_start_x;
10656 /* The last known character position. */
10657 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10658 /* The last known character position before string_start. */
10659 int string_before_pos;
10660 int x = row->x;
10661 int cursor_x = x;
10662 int cursor_from_overlay_pos = 0;
10663 int pt_old = PT - delta;
10664
10665 /* Skip over glyphs not having an object at the start of the row.
10666 These are special glyphs like truncation marks on terminal
10667 frames. */
10668 if (row->displays_text_p)
10669 while (glyph < end
10670 && INTEGERP (glyph->object)
10671 && glyph->charpos < 0)
10672 {
10673 x += glyph->pixel_width;
10674 ++glyph;
10675 }
10676
10677 string_start = NULL;
10678 while (glyph < end
10679 && !INTEGERP (glyph->object)
10680 && (!BUFFERP (glyph->object)
10681 || (last_pos = glyph->charpos) < pt_old))
10682 {
10683 if (! STRINGP (glyph->object))
10684 {
10685 string_start = NULL;
10686 x += glyph->pixel_width;
10687 ++glyph;
10688 if (cursor_from_overlay_pos
10689 && last_pos > cursor_from_overlay_pos)
10690 {
10691 cursor_from_overlay_pos = 0;
10692 cursor = 0;
10693 }
10694 }
10695 else
10696 {
10697 string_before_pos = last_pos;
10698 string_start = glyph;
10699 string_start_x = x;
10700 /* Skip all glyphs from string. */
10701 do
10702 {
10703 int pos;
10704 if ((cursor == NULL || glyph > cursor)
10705 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10706 Qcursor, (glyph)->object))
10707 && (pos = string_buffer_position (w, glyph->object,
10708 string_before_pos),
10709 (pos == 0 /* From overlay */
10710 || pos == pt_old)))
10711 {
10712 /* Estimate overlay buffer position from the buffer
10713 positions of the glyphs before and after the overlay.
10714 Add 1 to last_pos so that if point corresponds to the
10715 glyph right after the overlay, we still use a 'cursor'
10716 property found in that overlay. */
10717 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10718 cursor = glyph;
10719 cursor_x = x;
10720 }
10721 x += glyph->pixel_width;
10722 ++glyph;
10723 }
10724 while (glyph < end && STRINGP (glyph->object));
10725 }
10726 }
10727
10728 if (cursor != NULL)
10729 {
10730 glyph = cursor;
10731 x = cursor_x;
10732 }
10733 else if (string_start
10734 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10735 {
10736 /* We may have skipped over point because the previous glyphs
10737 are from string. As there's no easy way to know the
10738 character position of the current glyph, find the correct
10739 glyph on point by scanning from string_start again. */
10740 Lisp_Object limit;
10741 Lisp_Object string;
10742 int pos;
10743
10744 limit = make_number (pt_old + 1);
10745 end = glyph;
10746 glyph = string_start;
10747 x = string_start_x;
10748 string = glyph->object;
10749 pos = string_buffer_position (w, string, string_before_pos);
10750 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10751 because we always put cursor after overlay strings. */
10752 while (pos == 0 && glyph < end)
10753 {
10754 string = glyph->object;
10755 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10756 if (glyph < end)
10757 pos = string_buffer_position (w, glyph->object, string_before_pos);
10758 }
10759
10760 while (glyph < end)
10761 {
10762 pos = XINT (Fnext_single_char_property_change
10763 (make_number (pos), Qdisplay, Qnil, limit));
10764 if (pos > pt_old)
10765 break;
10766 /* Skip glyphs from the same string. */
10767 string = glyph->object;
10768 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10769 /* Skip glyphs from an overlay. */
10770 while (glyph < end
10771 && ! string_buffer_position (w, glyph->object, pos))
10772 {
10773 string = glyph->object;
10774 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10775 }
10776 }
10777 }
10778
10779 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10780 w->cursor.x = x;
10781 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10782 w->cursor.y = row->y + dy;
10783
10784 if (w == XWINDOW (selected_window))
10785 {
10786 if (!row->continued_p
10787 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10788 && row->x == 0)
10789 {
10790 this_line_buffer = XBUFFER (w->buffer);
10791
10792 CHARPOS (this_line_start_pos)
10793 = MATRIX_ROW_START_CHARPOS (row) + delta;
10794 BYTEPOS (this_line_start_pos)
10795 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10796
10797 CHARPOS (this_line_end_pos)
10798 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10799 BYTEPOS (this_line_end_pos)
10800 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10801
10802 this_line_y = w->cursor.y;
10803 this_line_pixel_height = row->height;
10804 this_line_vpos = w->cursor.vpos;
10805 this_line_start_x = row->x;
10806 }
10807 else
10808 CHARPOS (this_line_start_pos) = 0;
10809 }
10810 }
10811
10812
10813 /* Run window scroll functions, if any, for WINDOW with new window
10814 start STARTP. Sets the window start of WINDOW to that position.
10815
10816 We assume that the window's buffer is really current. */
10817
10818 static INLINE struct text_pos
10819 run_window_scroll_functions (window, startp)
10820 Lisp_Object window;
10821 struct text_pos startp;
10822 {
10823 struct window *w = XWINDOW (window);
10824 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10825
10826 if (current_buffer != XBUFFER (w->buffer))
10827 abort ();
10828
10829 if (!NILP (Vwindow_scroll_functions))
10830 {
10831 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10832 make_number (CHARPOS (startp)));
10833 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10834 /* In case the hook functions switch buffers. */
10835 if (current_buffer != XBUFFER (w->buffer))
10836 set_buffer_internal_1 (XBUFFER (w->buffer));
10837 }
10838
10839 return startp;
10840 }
10841
10842
10843 /* Make sure the line containing the cursor is fully visible.
10844 A value of 1 means there is nothing to be done.
10845 (Either the line is fully visible, or it cannot be made so,
10846 or we cannot tell.)
10847
10848 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10849 is higher than window.
10850
10851 A value of 0 means the caller should do scrolling
10852 as if point had gone off the screen. */
10853
10854 static int
10855 make_cursor_line_fully_visible (w, force_p)
10856 struct window *w;
10857 int force_p;
10858 {
10859 struct glyph_matrix *matrix;
10860 struct glyph_row *row;
10861 int window_height;
10862
10863 /* It's not always possible to find the cursor, e.g, when a window
10864 is full of overlay strings. Don't do anything in that case. */
10865 if (w->cursor.vpos < 0)
10866 return 1;
10867
10868 matrix = w->desired_matrix;
10869 row = MATRIX_ROW (matrix, w->cursor.vpos);
10870
10871 /* If the cursor row is not partially visible, there's nothing to do. */
10872 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10873 return 1;
10874
10875 /* If the row the cursor is in is taller than the window's height,
10876 it's not clear what to do, so do nothing. */
10877 window_height = window_box_height (w);
10878 if (row->height >= window_height)
10879 {
10880 if (!force_p || w->vscroll)
10881 return 1;
10882 }
10883 return 0;
10884
10885 #if 0
10886 /* This code used to try to scroll the window just enough to make
10887 the line visible. It returned 0 to say that the caller should
10888 allocate larger glyph matrices. */
10889
10890 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10891 {
10892 int dy = row->height - row->visible_height;
10893 w->vscroll = 0;
10894 w->cursor.y += dy;
10895 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10896 }
10897 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10898 {
10899 int dy = - (row->height - row->visible_height);
10900 w->vscroll = dy;
10901 w->cursor.y += dy;
10902 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10903 }
10904
10905 /* When we change the cursor y-position of the selected window,
10906 change this_line_y as well so that the display optimization for
10907 the cursor line of the selected window in redisplay_internal uses
10908 the correct y-position. */
10909 if (w == XWINDOW (selected_window))
10910 this_line_y = w->cursor.y;
10911
10912 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10913 redisplay with larger matrices. */
10914 if (matrix->nrows < required_matrix_height (w))
10915 {
10916 fonts_changed_p = 1;
10917 return 0;
10918 }
10919
10920 return 1;
10921 #endif /* 0 */
10922 }
10923
10924
10925 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10926 non-zero means only WINDOW is redisplayed in redisplay_internal.
10927 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10928 in redisplay_window to bring a partially visible line into view in
10929 the case that only the cursor has moved.
10930
10931 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10932 last screen line's vertical height extends past the end of the screen.
10933
10934 Value is
10935
10936 1 if scrolling succeeded
10937
10938 0 if scrolling didn't find point.
10939
10940 -1 if new fonts have been loaded so that we must interrupt
10941 redisplay, adjust glyph matrices, and try again. */
10942
10943 enum
10944 {
10945 SCROLLING_SUCCESS,
10946 SCROLLING_FAILED,
10947 SCROLLING_NEED_LARGER_MATRICES
10948 };
10949
10950 static int
10951 try_scrolling (window, just_this_one_p, scroll_conservatively,
10952 scroll_step, temp_scroll_step, last_line_misfit)
10953 Lisp_Object window;
10954 int just_this_one_p;
10955 EMACS_INT scroll_conservatively, scroll_step;
10956 int temp_scroll_step;
10957 int last_line_misfit;
10958 {
10959 struct window *w = XWINDOW (window);
10960 struct frame *f = XFRAME (w->frame);
10961 struct text_pos scroll_margin_pos;
10962 struct text_pos pos;
10963 struct text_pos startp;
10964 struct it it;
10965 Lisp_Object window_end;
10966 int this_scroll_margin;
10967 int dy = 0;
10968 int scroll_max;
10969 int rc;
10970 int amount_to_scroll = 0;
10971 Lisp_Object aggressive;
10972 int height;
10973 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10974
10975 #if GLYPH_DEBUG
10976 debug_method_add (w, "try_scrolling");
10977 #endif
10978
10979 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10980
10981 /* Compute scroll margin height in pixels. We scroll when point is
10982 within this distance from the top or bottom of the window. */
10983 if (scroll_margin > 0)
10984 {
10985 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10986 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10987 }
10988 else
10989 this_scroll_margin = 0;
10990
10991 /* Force scroll_conservatively to have a reasonable value so it doesn't
10992 cause an overflow while computing how much to scroll. */
10993 if (scroll_conservatively)
10994 scroll_conservatively = min (scroll_conservatively,
10995 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
10996
10997 /* Compute how much we should try to scroll maximally to bring point
10998 into view. */
10999 if (scroll_step || scroll_conservatively || temp_scroll_step)
11000 scroll_max = max (scroll_step,
11001 max (scroll_conservatively, temp_scroll_step));
11002 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11003 || NUMBERP (current_buffer->scroll_up_aggressively))
11004 /* We're trying to scroll because of aggressive scrolling
11005 but no scroll_step is set. Choose an arbitrary one. Maybe
11006 there should be a variable for this. */
11007 scroll_max = 10;
11008 else
11009 scroll_max = 0;
11010 scroll_max *= FRAME_LINE_HEIGHT (f);
11011
11012 /* Decide whether we have to scroll down. Start at the window end
11013 and move this_scroll_margin up to find the position of the scroll
11014 margin. */
11015 window_end = Fwindow_end (window, Qt);
11016
11017 too_near_end:
11018
11019 CHARPOS (scroll_margin_pos) = XINT (window_end);
11020 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11021
11022 if (this_scroll_margin || extra_scroll_margin_lines)
11023 {
11024 start_display (&it, w, scroll_margin_pos);
11025 if (this_scroll_margin)
11026 move_it_vertically (&it, - this_scroll_margin);
11027 if (extra_scroll_margin_lines)
11028 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11029 scroll_margin_pos = it.current.pos;
11030 }
11031
11032 if (PT >= CHARPOS (scroll_margin_pos))
11033 {
11034 int y0;
11035
11036 /* Point is in the scroll margin at the bottom of the window, or
11037 below. Compute a new window start that makes point visible. */
11038
11039 /* Compute the distance from the scroll margin to PT.
11040 Give up if the distance is greater than scroll_max. */
11041 start_display (&it, w, scroll_margin_pos);
11042 y0 = it.current_y;
11043 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11044 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11045
11046 /* To make point visible, we have to move the window start
11047 down so that the line the cursor is in is visible, which
11048 means we have to add in the height of the cursor line. */
11049 dy = line_bottom_y (&it) - y0;
11050
11051 if (dy > scroll_max)
11052 return SCROLLING_FAILED;
11053
11054 /* Move the window start down. If scrolling conservatively,
11055 move it just enough down to make point visible. If
11056 scroll_step is set, move it down by scroll_step. */
11057 start_display (&it, w, startp);
11058
11059 if (scroll_conservatively)
11060 /* Set AMOUNT_TO_SCROLL to at least one line,
11061 and at most scroll_conservatively lines. */
11062 amount_to_scroll
11063 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11064 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11065 else if (scroll_step || temp_scroll_step)
11066 amount_to_scroll = scroll_max;
11067 else
11068 {
11069 aggressive = current_buffer->scroll_up_aggressively;
11070 height = WINDOW_BOX_TEXT_HEIGHT (w);
11071 if (NUMBERP (aggressive))
11072 {
11073 double float_amount = XFLOATINT (aggressive) * height;
11074 amount_to_scroll = float_amount;
11075 if (amount_to_scroll == 0 && float_amount > 0)
11076 amount_to_scroll = 1;
11077 }
11078 }
11079
11080 if (amount_to_scroll <= 0)
11081 return SCROLLING_FAILED;
11082
11083 /* If moving by amount_to_scroll leaves STARTP unchanged,
11084 move it down one screen line. */
11085
11086 move_it_vertically (&it, amount_to_scroll);
11087 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11088 move_it_by_lines (&it, 1, 1);
11089 startp = it.current.pos;
11090 }
11091 else
11092 {
11093 /* See if point is inside the scroll margin at the top of the
11094 window. */
11095 scroll_margin_pos = startp;
11096 if (this_scroll_margin)
11097 {
11098 start_display (&it, w, startp);
11099 move_it_vertically (&it, this_scroll_margin);
11100 scroll_margin_pos = it.current.pos;
11101 }
11102
11103 if (PT < CHARPOS (scroll_margin_pos))
11104 {
11105 /* Point is in the scroll margin at the top of the window or
11106 above what is displayed in the window. */
11107 int y0;
11108
11109 /* Compute the vertical distance from PT to the scroll
11110 margin position. Give up if distance is greater than
11111 scroll_max. */
11112 SET_TEXT_POS (pos, PT, PT_BYTE);
11113 start_display (&it, w, pos);
11114 y0 = it.current_y;
11115 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11116 it.last_visible_y, -1,
11117 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11118 dy = it.current_y - y0;
11119 if (dy > scroll_max)
11120 return SCROLLING_FAILED;
11121
11122 /* Compute new window start. */
11123 start_display (&it, w, startp);
11124
11125 if (scroll_conservatively)
11126 amount_to_scroll
11127 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11128 else if (scroll_step || temp_scroll_step)
11129 amount_to_scroll = scroll_max;
11130 else
11131 {
11132 aggressive = current_buffer->scroll_down_aggressively;
11133 height = WINDOW_BOX_TEXT_HEIGHT (w);
11134 if (NUMBERP (aggressive))
11135 {
11136 double float_amount = XFLOATINT (aggressive) * height;
11137 amount_to_scroll = float_amount;
11138 if (amount_to_scroll == 0 && float_amount > 0)
11139 amount_to_scroll = 1;
11140 }
11141 }
11142
11143 if (amount_to_scroll <= 0)
11144 return SCROLLING_FAILED;
11145
11146 move_it_vertically (&it, - amount_to_scroll);
11147 startp = it.current.pos;
11148 }
11149 }
11150
11151 /* Run window scroll functions. */
11152 startp = run_window_scroll_functions (window, startp);
11153
11154 /* Display the window. Give up if new fonts are loaded, or if point
11155 doesn't appear. */
11156 if (!try_window (window, startp))
11157 rc = SCROLLING_NEED_LARGER_MATRICES;
11158 else if (w->cursor.vpos < 0)
11159 {
11160 clear_glyph_matrix (w->desired_matrix);
11161 rc = SCROLLING_FAILED;
11162 }
11163 else
11164 {
11165 /* Maybe forget recorded base line for line number display. */
11166 if (!just_this_one_p
11167 || current_buffer->clip_changed
11168 || BEG_UNCHANGED < CHARPOS (startp))
11169 w->base_line_number = Qnil;
11170
11171 /* If cursor ends up on a partially visible line,
11172 treat that as being off the bottom of the screen. */
11173 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11174 {
11175 clear_glyph_matrix (w->desired_matrix);
11176 ++extra_scroll_margin_lines;
11177 goto too_near_end;
11178 }
11179 rc = SCROLLING_SUCCESS;
11180 }
11181
11182 return rc;
11183 }
11184
11185
11186 /* Compute a suitable window start for window W if display of W starts
11187 on a continuation line. Value is non-zero if a new window start
11188 was computed.
11189
11190 The new window start will be computed, based on W's width, starting
11191 from the start of the continued line. It is the start of the
11192 screen line with the minimum distance from the old start W->start. */
11193
11194 static int
11195 compute_window_start_on_continuation_line (w)
11196 struct window *w;
11197 {
11198 struct text_pos pos, start_pos;
11199 int window_start_changed_p = 0;
11200
11201 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11202
11203 /* If window start is on a continuation line... Window start may be
11204 < BEGV in case there's invisible text at the start of the
11205 buffer (M-x rmail, for example). */
11206 if (CHARPOS (start_pos) > BEGV
11207 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11208 {
11209 struct it it;
11210 struct glyph_row *row;
11211
11212 /* Handle the case that the window start is out of range. */
11213 if (CHARPOS (start_pos) < BEGV)
11214 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11215 else if (CHARPOS (start_pos) > ZV)
11216 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11217
11218 /* Find the start of the continued line. This should be fast
11219 because scan_buffer is fast (newline cache). */
11220 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11221 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11222 row, DEFAULT_FACE_ID);
11223 reseat_at_previous_visible_line_start (&it);
11224
11225 /* If the line start is "too far" away from the window start,
11226 say it takes too much time to compute a new window start. */
11227 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11228 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11229 {
11230 int min_distance, distance;
11231
11232 /* Move forward by display lines to find the new window
11233 start. If window width was enlarged, the new start can
11234 be expected to be > the old start. If window width was
11235 decreased, the new window start will be < the old start.
11236 So, we're looking for the display line start with the
11237 minimum distance from the old window start. */
11238 pos = it.current.pos;
11239 min_distance = INFINITY;
11240 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11241 distance < min_distance)
11242 {
11243 min_distance = distance;
11244 pos = it.current.pos;
11245 move_it_by_lines (&it, 1, 0);
11246 }
11247
11248 /* Set the window start there. */
11249 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11250 window_start_changed_p = 1;
11251 }
11252 }
11253
11254 return window_start_changed_p;
11255 }
11256
11257
11258 /* Try cursor movement in case text has not changed in window WINDOW,
11259 with window start STARTP. Value is
11260
11261 CURSOR_MOVEMENT_SUCCESS if successful
11262
11263 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11264
11265 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11266 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11267 we want to scroll as if scroll-step were set to 1. See the code.
11268
11269 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11270 which case we have to abort this redisplay, and adjust matrices
11271 first. */
11272
11273 enum
11274 {
11275 CURSOR_MOVEMENT_SUCCESS,
11276 CURSOR_MOVEMENT_CANNOT_BE_USED,
11277 CURSOR_MOVEMENT_MUST_SCROLL,
11278 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11279 };
11280
11281 static int
11282 try_cursor_movement (window, startp, scroll_step)
11283 Lisp_Object window;
11284 struct text_pos startp;
11285 int *scroll_step;
11286 {
11287 struct window *w = XWINDOW (window);
11288 struct frame *f = XFRAME (w->frame);
11289 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11290
11291 #if GLYPH_DEBUG
11292 if (inhibit_try_cursor_movement)
11293 return rc;
11294 #endif
11295
11296 /* Handle case where text has not changed, only point, and it has
11297 not moved off the frame. */
11298 if (/* Point may be in this window. */
11299 PT >= CHARPOS (startp)
11300 /* Selective display hasn't changed. */
11301 && !current_buffer->clip_changed
11302 /* Function force-mode-line-update is used to force a thorough
11303 redisplay. It sets either windows_or_buffers_changed or
11304 update_mode_lines. So don't take a shortcut here for these
11305 cases. */
11306 && !update_mode_lines
11307 && !windows_or_buffers_changed
11308 && !cursor_type_changed
11309 /* Can't use this case if highlighting a region. When a
11310 region exists, cursor movement has to do more than just
11311 set the cursor. */
11312 && !(!NILP (Vtransient_mark_mode)
11313 && !NILP (current_buffer->mark_active))
11314 && NILP (w->region_showing)
11315 && NILP (Vshow_trailing_whitespace)
11316 /* Right after splitting windows, last_point may be nil. */
11317 && INTEGERP (w->last_point)
11318 /* This code is not used for mini-buffer for the sake of the case
11319 of redisplaying to replace an echo area message; since in
11320 that case the mini-buffer contents per se are usually
11321 unchanged. This code is of no real use in the mini-buffer
11322 since the handling of this_line_start_pos, etc., in redisplay
11323 handles the same cases. */
11324 && !EQ (window, minibuf_window)
11325 /* When splitting windows or for new windows, it happens that
11326 redisplay is called with a nil window_end_vpos or one being
11327 larger than the window. This should really be fixed in
11328 window.c. I don't have this on my list, now, so we do
11329 approximately the same as the old redisplay code. --gerd. */
11330 && INTEGERP (w->window_end_vpos)
11331 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11332 && (FRAME_WINDOW_P (f)
11333 || !overlay_arrow_in_current_buffer_p ()))
11334 {
11335 int this_scroll_margin, top_scroll_margin;
11336 struct glyph_row *row = NULL;
11337
11338 #if GLYPH_DEBUG
11339 debug_method_add (w, "cursor movement");
11340 #endif
11341
11342 /* Scroll if point within this distance from the top or bottom
11343 of the window. This is a pixel value. */
11344 this_scroll_margin = max (0, scroll_margin);
11345 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11346 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11347
11348 top_scroll_margin = this_scroll_margin;
11349 if (WINDOW_WANTS_HEADER_LINE_P (w))
11350 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11351
11352 /* Start with the row the cursor was displayed during the last
11353 not paused redisplay. Give up if that row is not valid. */
11354 if (w->last_cursor.vpos < 0
11355 || w->last_cursor.vpos >= w->current_matrix->nrows)
11356 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11357 else
11358 {
11359 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11360 if (row->mode_line_p)
11361 ++row;
11362 if (!row->enabled_p)
11363 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11364 }
11365
11366 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11367 {
11368 int scroll_p = 0;
11369 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11370
11371 if (PT > XFASTINT (w->last_point))
11372 {
11373 /* Point has moved forward. */
11374 while (MATRIX_ROW_END_CHARPOS (row) < PT
11375 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11376 {
11377 xassert (row->enabled_p);
11378 ++row;
11379 }
11380
11381 /* The end position of a row equals the start position
11382 of the next row. If PT is there, we would rather
11383 display it in the next line. */
11384 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11385 && MATRIX_ROW_END_CHARPOS (row) == PT
11386 && !cursor_row_p (w, row))
11387 ++row;
11388
11389 /* If within the scroll margin, scroll. Note that
11390 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11391 the next line would be drawn, and that
11392 this_scroll_margin can be zero. */
11393 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11394 || PT > MATRIX_ROW_END_CHARPOS (row)
11395 /* Line is completely visible last line in window
11396 and PT is to be set in the next line. */
11397 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11398 && PT == MATRIX_ROW_END_CHARPOS (row)
11399 && !row->ends_at_zv_p
11400 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11401 scroll_p = 1;
11402 }
11403 else if (PT < XFASTINT (w->last_point))
11404 {
11405 /* Cursor has to be moved backward. Note that PT >=
11406 CHARPOS (startp) because of the outer if-statement. */
11407 while (!row->mode_line_p
11408 && (MATRIX_ROW_START_CHARPOS (row) > PT
11409 || (MATRIX_ROW_START_CHARPOS (row) == PT
11410 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11411 && (row->y > top_scroll_margin
11412 || CHARPOS (startp) == BEGV))
11413 {
11414 xassert (row->enabled_p);
11415 --row;
11416 }
11417
11418 /* Consider the following case: Window starts at BEGV,
11419 there is invisible, intangible text at BEGV, so that
11420 display starts at some point START > BEGV. It can
11421 happen that we are called with PT somewhere between
11422 BEGV and START. Try to handle that case. */
11423 if (row < w->current_matrix->rows
11424 || row->mode_line_p)
11425 {
11426 row = w->current_matrix->rows;
11427 if (row->mode_line_p)
11428 ++row;
11429 }
11430
11431 /* Due to newlines in overlay strings, we may have to
11432 skip forward over overlay strings. */
11433 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11434 && MATRIX_ROW_END_CHARPOS (row) == PT
11435 && !cursor_row_p (w, row))
11436 ++row;
11437
11438 /* If within the scroll margin, scroll. */
11439 if (row->y < top_scroll_margin
11440 && CHARPOS (startp) != BEGV)
11441 scroll_p = 1;
11442 }
11443
11444 if (PT < MATRIX_ROW_START_CHARPOS (row)
11445 || PT > MATRIX_ROW_END_CHARPOS (row))
11446 {
11447 /* if PT is not in the glyph row, give up. */
11448 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11449 }
11450 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11451 {
11452 if (PT == MATRIX_ROW_END_CHARPOS (row)
11453 && !row->ends_at_zv_p
11454 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11455 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11456 else if (row->height > window_box_height (w))
11457 {
11458 /* If we end up in a partially visible line, let's
11459 make it fully visible, except when it's taller
11460 than the window, in which case we can't do much
11461 about it. */
11462 *scroll_step = 1;
11463 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11464 }
11465 else
11466 {
11467 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11468 if (!make_cursor_line_fully_visible (w, 0))
11469 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11470 else
11471 rc = CURSOR_MOVEMENT_SUCCESS;
11472 }
11473 }
11474 else if (scroll_p)
11475 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11476 else
11477 {
11478 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11479 rc = CURSOR_MOVEMENT_SUCCESS;
11480 }
11481 }
11482 }
11483
11484 return rc;
11485 }
11486
11487 void
11488 set_vertical_scroll_bar (w)
11489 struct window *w;
11490 {
11491 int start, end, whole;
11492
11493 /* Calculate the start and end positions for the current window.
11494 At some point, it would be nice to choose between scrollbars
11495 which reflect the whole buffer size, with special markers
11496 indicating narrowing, and scrollbars which reflect only the
11497 visible region.
11498
11499 Note that mini-buffers sometimes aren't displaying any text. */
11500 if (!MINI_WINDOW_P (w)
11501 || (w == XWINDOW (minibuf_window)
11502 && NILP (echo_area_buffer[0])))
11503 {
11504 struct buffer *buf = XBUFFER (w->buffer);
11505 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11506 start = marker_position (w->start) - BUF_BEGV (buf);
11507 /* I don't think this is guaranteed to be right. For the
11508 moment, we'll pretend it is. */
11509 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11510
11511 if (end < start)
11512 end = start;
11513 if (whole < (end - start))
11514 whole = end - start;
11515 }
11516 else
11517 start = end = whole = 0;
11518
11519 /* Indicate what this scroll bar ought to be displaying now. */
11520 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11521 }
11522
11523
11524 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11525 selected_window is redisplayed.
11526
11527 We can return without actually redisplaying the window if
11528 fonts_changed_p is nonzero. In that case, redisplay_internal will
11529 retry. */
11530
11531 static void
11532 redisplay_window (window, just_this_one_p)
11533 Lisp_Object window;
11534 int just_this_one_p;
11535 {
11536 struct window *w = XWINDOW (window);
11537 struct frame *f = XFRAME (w->frame);
11538 struct buffer *buffer = XBUFFER (w->buffer);
11539 struct buffer *old = current_buffer;
11540 struct text_pos lpoint, opoint, startp;
11541 int update_mode_line;
11542 int tem;
11543 struct it it;
11544 /* Record it now because it's overwritten. */
11545 int current_matrix_up_to_date_p = 0;
11546 int used_current_matrix_p = 0;
11547 /* This is less strict than current_matrix_up_to_date_p.
11548 It indictes that the buffer contents and narrowing are unchanged. */
11549 int buffer_unchanged_p = 0;
11550 int temp_scroll_step = 0;
11551 int count = SPECPDL_INDEX ();
11552 int rc;
11553 int centering_position;
11554 int last_line_misfit = 0;
11555
11556 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11557 opoint = lpoint;
11558
11559 /* W must be a leaf window here. */
11560 xassert (!NILP (w->buffer));
11561 #if GLYPH_DEBUG
11562 *w->desired_matrix->method = 0;
11563 #endif
11564
11565 specbind (Qinhibit_point_motion_hooks, Qt);
11566
11567 reconsider_clip_changes (w, buffer);
11568
11569 /* Has the mode line to be updated? */
11570 update_mode_line = (!NILP (w->update_mode_line)
11571 || update_mode_lines
11572 || buffer->clip_changed
11573 || buffer->prevent_redisplay_optimizations_p);
11574
11575 if (MINI_WINDOW_P (w))
11576 {
11577 if (w == XWINDOW (echo_area_window)
11578 && !NILP (echo_area_buffer[0]))
11579 {
11580 if (update_mode_line)
11581 /* We may have to update a tty frame's menu bar or a
11582 tool-bar. Example `M-x C-h C-h C-g'. */
11583 goto finish_menu_bars;
11584 else
11585 /* We've already displayed the echo area glyphs in this window. */
11586 goto finish_scroll_bars;
11587 }
11588 else if ((w != XWINDOW (minibuf_window)
11589 || minibuf_level == 0)
11590 /* When buffer is nonempty, redisplay window normally. */
11591 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11592 /* Quail displays non-mini buffers in minibuffer window.
11593 In that case, redisplay the window normally. */
11594 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11595 {
11596 /* W is a mini-buffer window, but it's not active, so clear
11597 it. */
11598 int yb = window_text_bottom_y (w);
11599 struct glyph_row *row;
11600 int y;
11601
11602 for (y = 0, row = w->desired_matrix->rows;
11603 y < yb;
11604 y += row->height, ++row)
11605 blank_row (w, row, y);
11606 goto finish_scroll_bars;
11607 }
11608
11609 clear_glyph_matrix (w->desired_matrix);
11610 }
11611
11612 /* Otherwise set up data on this window; select its buffer and point
11613 value. */
11614 /* Really select the buffer, for the sake of buffer-local
11615 variables. */
11616 set_buffer_internal_1 (XBUFFER (w->buffer));
11617 SET_TEXT_POS (opoint, PT, PT_BYTE);
11618
11619 current_matrix_up_to_date_p
11620 = (!NILP (w->window_end_valid)
11621 && !current_buffer->clip_changed
11622 && !current_buffer->prevent_redisplay_optimizations_p
11623 && XFASTINT (w->last_modified) >= MODIFF
11624 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11625
11626 buffer_unchanged_p
11627 = (!NILP (w->window_end_valid)
11628 && !current_buffer->clip_changed
11629 && XFASTINT (w->last_modified) >= MODIFF
11630 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11631
11632 /* When windows_or_buffers_changed is non-zero, we can't rely on
11633 the window end being valid, so set it to nil there. */
11634 if (windows_or_buffers_changed)
11635 {
11636 /* If window starts on a continuation line, maybe adjust the
11637 window start in case the window's width changed. */
11638 if (XMARKER (w->start)->buffer == current_buffer)
11639 compute_window_start_on_continuation_line (w);
11640
11641 w->window_end_valid = Qnil;
11642 }
11643
11644 /* Some sanity checks. */
11645 CHECK_WINDOW_END (w);
11646 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11647 abort ();
11648 if (BYTEPOS (opoint) < CHARPOS (opoint))
11649 abort ();
11650
11651 /* If %c is in mode line, update it if needed. */
11652 if (!NILP (w->column_number_displayed)
11653 /* This alternative quickly identifies a common case
11654 where no change is needed. */
11655 && !(PT == XFASTINT (w->last_point)
11656 && XFASTINT (w->last_modified) >= MODIFF
11657 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11658 && (XFASTINT (w->column_number_displayed)
11659 != (int) current_column ())) /* iftc */
11660 update_mode_line = 1;
11661
11662 /* Count number of windows showing the selected buffer. An indirect
11663 buffer counts as its base buffer. */
11664 if (!just_this_one_p)
11665 {
11666 struct buffer *current_base, *window_base;
11667 current_base = current_buffer;
11668 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11669 if (current_base->base_buffer)
11670 current_base = current_base->base_buffer;
11671 if (window_base->base_buffer)
11672 window_base = window_base->base_buffer;
11673 if (current_base == window_base)
11674 buffer_shared++;
11675 }
11676
11677 /* Point refers normally to the selected window. For any other
11678 window, set up appropriate value. */
11679 if (!EQ (window, selected_window))
11680 {
11681 int new_pt = XMARKER (w->pointm)->charpos;
11682 int new_pt_byte = marker_byte_position (w->pointm);
11683 if (new_pt < BEGV)
11684 {
11685 new_pt = BEGV;
11686 new_pt_byte = BEGV_BYTE;
11687 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11688 }
11689 else if (new_pt > (ZV - 1))
11690 {
11691 new_pt = ZV;
11692 new_pt_byte = ZV_BYTE;
11693 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11694 }
11695
11696 /* We don't use SET_PT so that the point-motion hooks don't run. */
11697 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11698 }
11699
11700 /* If any of the character widths specified in the display table
11701 have changed, invalidate the width run cache. It's true that
11702 this may be a bit late to catch such changes, but the rest of
11703 redisplay goes (non-fatally) haywire when the display table is
11704 changed, so why should we worry about doing any better? */
11705 if (current_buffer->width_run_cache)
11706 {
11707 struct Lisp_Char_Table *disptab = buffer_display_table ();
11708
11709 if (! disptab_matches_widthtab (disptab,
11710 XVECTOR (current_buffer->width_table)))
11711 {
11712 invalidate_region_cache (current_buffer,
11713 current_buffer->width_run_cache,
11714 BEG, Z);
11715 recompute_width_table (current_buffer, disptab);
11716 }
11717 }
11718
11719 /* If window-start is screwed up, choose a new one. */
11720 if (XMARKER (w->start)->buffer != current_buffer)
11721 goto recenter;
11722
11723 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11724
11725 /* If someone specified a new starting point but did not insist,
11726 check whether it can be used. */
11727 if (!NILP (w->optional_new_start)
11728 && CHARPOS (startp) >= BEGV
11729 && CHARPOS (startp) <= ZV)
11730 {
11731 w->optional_new_start = Qnil;
11732 start_display (&it, w, startp);
11733 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11734 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11735 if (IT_CHARPOS (it) == PT)
11736 w->force_start = Qt;
11737 /* IT may overshoot PT if text at PT is invisible. */
11738 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11739 w->force_start = Qt;
11740
11741
11742 }
11743
11744 /* Handle case where place to start displaying has been specified,
11745 unless the specified location is outside the accessible range. */
11746 if (!NILP (w->force_start)
11747 || w->frozen_window_start_p)
11748 {
11749 /* We set this later on if we have to adjust point. */
11750 int new_vpos = -1;
11751
11752 w->force_start = Qnil;
11753 w->vscroll = 0;
11754 w->window_end_valid = Qnil;
11755
11756 /* Forget any recorded base line for line number display. */
11757 if (!buffer_unchanged_p)
11758 w->base_line_number = Qnil;
11759
11760 /* Redisplay the mode line. Select the buffer properly for that.
11761 Also, run the hook window-scroll-functions
11762 because we have scrolled. */
11763 /* Note, we do this after clearing force_start because
11764 if there's an error, it is better to forget about force_start
11765 than to get into an infinite loop calling the hook functions
11766 and having them get more errors. */
11767 if (!update_mode_line
11768 || ! NILP (Vwindow_scroll_functions))
11769 {
11770 update_mode_line = 1;
11771 w->update_mode_line = Qt;
11772 startp = run_window_scroll_functions (window, startp);
11773 }
11774
11775 w->last_modified = make_number (0);
11776 w->last_overlay_modified = make_number (0);
11777 if (CHARPOS (startp) < BEGV)
11778 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11779 else if (CHARPOS (startp) > ZV)
11780 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11781
11782 /* Redisplay, then check if cursor has been set during the
11783 redisplay. Give up if new fonts were loaded. */
11784 if (!try_window (window, startp))
11785 {
11786 w->force_start = Qt;
11787 clear_glyph_matrix (w->desired_matrix);
11788 goto need_larger_matrices;
11789 }
11790
11791 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11792 {
11793 /* If point does not appear, try to move point so it does
11794 appear. The desired matrix has been built above, so we
11795 can use it here. */
11796 new_vpos = window_box_height (w) / 2;
11797 }
11798
11799 if (!make_cursor_line_fully_visible (w, 0))
11800 {
11801 /* Point does appear, but on a line partly visible at end of window.
11802 Move it back to a fully-visible line. */
11803 new_vpos = window_box_height (w);
11804 }
11805
11806 /* If we need to move point for either of the above reasons,
11807 now actually do it. */
11808 if (new_vpos >= 0)
11809 {
11810 struct glyph_row *row;
11811
11812 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11813 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11814 ++row;
11815
11816 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11817 MATRIX_ROW_START_BYTEPOS (row));
11818
11819 if (w != XWINDOW (selected_window))
11820 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11821 else if (current_buffer == old)
11822 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11823
11824 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11825
11826 /* If we are highlighting the region, then we just changed
11827 the region, so redisplay to show it. */
11828 if (!NILP (Vtransient_mark_mode)
11829 && !NILP (current_buffer->mark_active))
11830 {
11831 clear_glyph_matrix (w->desired_matrix);
11832 if (!try_window (window, startp))
11833 goto need_larger_matrices;
11834 }
11835 }
11836
11837 #if GLYPH_DEBUG
11838 debug_method_add (w, "forced window start");
11839 #endif
11840 goto done;
11841 }
11842
11843 /* Handle case where text has not changed, only point, and it has
11844 not moved off the frame, and we are not retrying after hscroll.
11845 (current_matrix_up_to_date_p is nonzero when retrying.) */
11846 if (current_matrix_up_to_date_p
11847 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11848 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11849 {
11850 switch (rc)
11851 {
11852 case CURSOR_MOVEMENT_SUCCESS:
11853 used_current_matrix_p = 1;
11854 goto done;
11855
11856 #if 0 /* try_cursor_movement never returns this value. */
11857 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11858 goto need_larger_matrices;
11859 #endif
11860
11861 case CURSOR_MOVEMENT_MUST_SCROLL:
11862 goto try_to_scroll;
11863
11864 default:
11865 abort ();
11866 }
11867 }
11868 /* If current starting point was originally the beginning of a line
11869 but no longer is, find a new starting point. */
11870 else if (!NILP (w->start_at_line_beg)
11871 && !(CHARPOS (startp) <= BEGV
11872 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11873 {
11874 #if GLYPH_DEBUG
11875 debug_method_add (w, "recenter 1");
11876 #endif
11877 goto recenter;
11878 }
11879
11880 /* Try scrolling with try_window_id. Value is > 0 if update has
11881 been done, it is -1 if we know that the same window start will
11882 not work. It is 0 if unsuccessful for some other reason. */
11883 else if ((tem = try_window_id (w)) != 0)
11884 {
11885 #if GLYPH_DEBUG
11886 debug_method_add (w, "try_window_id %d", tem);
11887 #endif
11888
11889 if (fonts_changed_p)
11890 goto need_larger_matrices;
11891 if (tem > 0)
11892 goto done;
11893
11894 /* Otherwise try_window_id has returned -1 which means that we
11895 don't want the alternative below this comment to execute. */
11896 }
11897 else if (CHARPOS (startp) >= BEGV
11898 && CHARPOS (startp) <= ZV
11899 && PT >= CHARPOS (startp)
11900 && (CHARPOS (startp) < ZV
11901 /* Avoid starting at end of buffer. */
11902 || CHARPOS (startp) == BEGV
11903 || (XFASTINT (w->last_modified) >= MODIFF
11904 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11905 {
11906 #if GLYPH_DEBUG
11907 debug_method_add (w, "same window start");
11908 #endif
11909
11910 /* Try to redisplay starting at same place as before.
11911 If point has not moved off frame, accept the results. */
11912 if (!current_matrix_up_to_date_p
11913 /* Don't use try_window_reusing_current_matrix in this case
11914 because a window scroll function can have changed the
11915 buffer. */
11916 || !NILP (Vwindow_scroll_functions)
11917 || MINI_WINDOW_P (w)
11918 || !(used_current_matrix_p
11919 = try_window_reusing_current_matrix (w)))
11920 {
11921 IF_DEBUG (debug_method_add (w, "1"));
11922 try_window (window, startp);
11923 }
11924
11925 if (fonts_changed_p)
11926 goto need_larger_matrices;
11927
11928 if (w->cursor.vpos >= 0)
11929 {
11930 if (!just_this_one_p
11931 || current_buffer->clip_changed
11932 || BEG_UNCHANGED < CHARPOS (startp))
11933 /* Forget any recorded base line for line number display. */
11934 w->base_line_number = Qnil;
11935
11936 if (!make_cursor_line_fully_visible (w, 1))
11937 {
11938 clear_glyph_matrix (w->desired_matrix);
11939 last_line_misfit = 1;
11940 }
11941 /* Drop through and scroll. */
11942 else
11943 goto done;
11944 }
11945 else
11946 clear_glyph_matrix (w->desired_matrix);
11947 }
11948
11949 try_to_scroll:
11950
11951 w->last_modified = make_number (0);
11952 w->last_overlay_modified = make_number (0);
11953
11954 /* Redisplay the mode line. Select the buffer properly for that. */
11955 if (!update_mode_line)
11956 {
11957 update_mode_line = 1;
11958 w->update_mode_line = Qt;
11959 }
11960
11961 /* Try to scroll by specified few lines. */
11962 if ((scroll_conservatively
11963 || scroll_step
11964 || temp_scroll_step
11965 || NUMBERP (current_buffer->scroll_up_aggressively)
11966 || NUMBERP (current_buffer->scroll_down_aggressively))
11967 && !current_buffer->clip_changed
11968 && CHARPOS (startp) >= BEGV
11969 && CHARPOS (startp) <= ZV)
11970 {
11971 /* The function returns -1 if new fonts were loaded, 1 if
11972 successful, 0 if not successful. */
11973 int rc = try_scrolling (window, just_this_one_p,
11974 scroll_conservatively,
11975 scroll_step,
11976 temp_scroll_step, last_line_misfit);
11977 switch (rc)
11978 {
11979 case SCROLLING_SUCCESS:
11980 goto done;
11981
11982 case SCROLLING_NEED_LARGER_MATRICES:
11983 goto need_larger_matrices;
11984
11985 case SCROLLING_FAILED:
11986 break;
11987
11988 default:
11989 abort ();
11990 }
11991 }
11992
11993 /* Finally, just choose place to start which centers point */
11994
11995 recenter:
11996 centering_position = window_box_height (w) / 2;
11997
11998 point_at_top:
11999 /* Jump here with centering_position already set to 0. */
12000
12001 #if GLYPH_DEBUG
12002 debug_method_add (w, "recenter");
12003 #endif
12004
12005 /* w->vscroll = 0; */
12006
12007 /* Forget any previously recorded base line for line number display. */
12008 if (!buffer_unchanged_p)
12009 w->base_line_number = Qnil;
12010
12011 /* Move backward half the height of the window. */
12012 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12013 it.current_y = it.last_visible_y;
12014 move_it_vertically_backward (&it, centering_position);
12015 xassert (IT_CHARPOS (it) >= BEGV);
12016
12017 /* The function move_it_vertically_backward may move over more
12018 than the specified y-distance. If it->w is small, e.g. a
12019 mini-buffer window, we may end up in front of the window's
12020 display area. Start displaying at the start of the line
12021 containing PT in this case. */
12022 if (it.current_y <= 0)
12023 {
12024 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12025 move_it_vertically (&it, 0);
12026 xassert (IT_CHARPOS (it) <= PT);
12027 it.current_y = 0;
12028 }
12029
12030 it.current_x = it.hpos = 0;
12031
12032 /* Set startp here explicitly in case that helps avoid an infinite loop
12033 in case the window-scroll-functions functions get errors. */
12034 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12035
12036 /* Run scroll hooks. */
12037 startp = run_window_scroll_functions (window, it.current.pos);
12038
12039 /* Redisplay the window. */
12040 if (!current_matrix_up_to_date_p
12041 || windows_or_buffers_changed
12042 || cursor_type_changed
12043 /* Don't use try_window_reusing_current_matrix in this case
12044 because it can have changed the buffer. */
12045 || !NILP (Vwindow_scroll_functions)
12046 || !just_this_one_p
12047 || MINI_WINDOW_P (w)
12048 || !(used_current_matrix_p
12049 = try_window_reusing_current_matrix (w)))
12050 try_window (window, startp);
12051
12052 /* If new fonts have been loaded (due to fontsets), give up. We
12053 have to start a new redisplay since we need to re-adjust glyph
12054 matrices. */
12055 if (fonts_changed_p)
12056 goto need_larger_matrices;
12057
12058 /* If cursor did not appear assume that the middle of the window is
12059 in the first line of the window. Do it again with the next line.
12060 (Imagine a window of height 100, displaying two lines of height
12061 60. Moving back 50 from it->last_visible_y will end in the first
12062 line.) */
12063 if (w->cursor.vpos < 0)
12064 {
12065 if (!NILP (w->window_end_valid)
12066 && PT >= Z - XFASTINT (w->window_end_pos))
12067 {
12068 clear_glyph_matrix (w->desired_matrix);
12069 move_it_by_lines (&it, 1, 0);
12070 try_window (window, it.current.pos);
12071 }
12072 else if (PT < IT_CHARPOS (it))
12073 {
12074 clear_glyph_matrix (w->desired_matrix);
12075 move_it_by_lines (&it, -1, 0);
12076 try_window (window, it.current.pos);
12077 }
12078 else
12079 {
12080 /* Not much we can do about it. */
12081 }
12082 }
12083
12084 /* Consider the following case: Window starts at BEGV, there is
12085 invisible, intangible text at BEGV, so that display starts at
12086 some point START > BEGV. It can happen that we are called with
12087 PT somewhere between BEGV and START. Try to handle that case. */
12088 if (w->cursor.vpos < 0)
12089 {
12090 struct glyph_row *row = w->current_matrix->rows;
12091 if (row->mode_line_p)
12092 ++row;
12093 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12094 }
12095
12096 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12097 {
12098 /* If vscroll is enabled, disable it and try again. */
12099 if (w->vscroll)
12100 {
12101 w->vscroll = 0;
12102 clear_glyph_matrix (w->desired_matrix);
12103 goto recenter;
12104 }
12105
12106 /* If centering point failed to make the whole line visible,
12107 put point at the top instead. That has to make the whole line
12108 visible, if it can be done. */
12109 clear_glyph_matrix (w->desired_matrix);
12110 centering_position = 0;
12111 goto point_at_top;
12112 }
12113
12114 done:
12115
12116 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12117 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12118 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12119 ? Qt : Qnil);
12120
12121 /* Display the mode line, if we must. */
12122 if ((update_mode_line
12123 /* If window not full width, must redo its mode line
12124 if (a) the window to its side is being redone and
12125 (b) we do a frame-based redisplay. This is a consequence
12126 of how inverted lines are drawn in frame-based redisplay. */
12127 || (!just_this_one_p
12128 && !FRAME_WINDOW_P (f)
12129 && !WINDOW_FULL_WIDTH_P (w))
12130 /* Line number to display. */
12131 || INTEGERP (w->base_line_pos)
12132 /* Column number is displayed and different from the one displayed. */
12133 || (!NILP (w->column_number_displayed)
12134 && (XFASTINT (w->column_number_displayed)
12135 != (int) current_column ()))) /* iftc */
12136 /* This means that the window has a mode line. */
12137 && (WINDOW_WANTS_MODELINE_P (w)
12138 || WINDOW_WANTS_HEADER_LINE_P (w)))
12139 {
12140 display_mode_lines (w);
12141
12142 /* If mode line height has changed, arrange for a thorough
12143 immediate redisplay using the correct mode line height. */
12144 if (WINDOW_WANTS_MODELINE_P (w)
12145 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12146 {
12147 fonts_changed_p = 1;
12148 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12149 = DESIRED_MODE_LINE_HEIGHT (w);
12150 }
12151
12152 /* If top line height has changed, arrange for a thorough
12153 immediate redisplay using the correct mode line height. */
12154 if (WINDOW_WANTS_HEADER_LINE_P (w)
12155 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12156 {
12157 fonts_changed_p = 1;
12158 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12159 = DESIRED_HEADER_LINE_HEIGHT (w);
12160 }
12161
12162 if (fonts_changed_p)
12163 goto need_larger_matrices;
12164 }
12165
12166 if (!line_number_displayed
12167 && !BUFFERP (w->base_line_pos))
12168 {
12169 w->base_line_pos = Qnil;
12170 w->base_line_number = Qnil;
12171 }
12172
12173 finish_menu_bars:
12174
12175 /* When we reach a frame's selected window, redo the frame's menu bar. */
12176 if (update_mode_line
12177 && EQ (FRAME_SELECTED_WINDOW (f), window))
12178 {
12179 int redisplay_menu_p = 0;
12180 int redisplay_tool_bar_p = 0;
12181
12182 if (FRAME_WINDOW_P (f))
12183 {
12184 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12185 || defined (USE_GTK)
12186 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12187 #else
12188 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12189 #endif
12190 }
12191 else
12192 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12193
12194 if (redisplay_menu_p)
12195 display_menu_bar (w);
12196
12197 #ifdef HAVE_WINDOW_SYSTEM
12198 #ifdef USE_GTK
12199 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12200 #else
12201 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12202 && (FRAME_TOOL_BAR_LINES (f) > 0
12203 || auto_resize_tool_bars_p);
12204
12205 #endif
12206
12207 if (redisplay_tool_bar_p)
12208 redisplay_tool_bar (f);
12209 #endif
12210 }
12211
12212 #ifdef HAVE_WINDOW_SYSTEM
12213 if (update_window_fringes (w, 0)
12214 && !just_this_one_p
12215 && (used_current_matrix_p || overlay_arrow_seen)
12216 && !w->pseudo_window_p)
12217 {
12218 update_begin (f);
12219 BLOCK_INPUT;
12220 draw_window_fringes (w);
12221 UNBLOCK_INPUT;
12222 update_end (f);
12223 }
12224 #endif /* HAVE_WINDOW_SYSTEM */
12225
12226 /* We go to this label, with fonts_changed_p nonzero,
12227 if it is necessary to try again using larger glyph matrices.
12228 We have to redeem the scroll bar even in this case,
12229 because the loop in redisplay_internal expects that. */
12230 need_larger_matrices:
12231 ;
12232 finish_scroll_bars:
12233
12234 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12235 {
12236 /* Set the thumb's position and size. */
12237 set_vertical_scroll_bar (w);
12238
12239 /* Note that we actually used the scroll bar attached to this
12240 window, so it shouldn't be deleted at the end of redisplay. */
12241 redeem_scroll_bar_hook (w);
12242 }
12243
12244 /* Restore current_buffer and value of point in it. */
12245 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12246 set_buffer_internal_1 (old);
12247 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12248
12249 unbind_to (count, Qnil);
12250 }
12251
12252
12253 /* Build the complete desired matrix of WINDOW with a window start
12254 buffer position POS. Value is non-zero if successful. It is zero
12255 if fonts were loaded during redisplay which makes re-adjusting
12256 glyph matrices necessary. */
12257
12258 int
12259 try_window (window, pos)
12260 Lisp_Object window;
12261 struct text_pos pos;
12262 {
12263 struct window *w = XWINDOW (window);
12264 struct it it;
12265 struct glyph_row *last_text_row = NULL;
12266
12267 /* Make POS the new window start. */
12268 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12269
12270 /* Mark cursor position as unknown. No overlay arrow seen. */
12271 w->cursor.vpos = -1;
12272 overlay_arrow_seen = 0;
12273
12274 /* Initialize iterator and info to start at POS. */
12275 start_display (&it, w, pos);
12276
12277 /* Display all lines of W. */
12278 while (it.current_y < it.last_visible_y)
12279 {
12280 if (display_line (&it))
12281 last_text_row = it.glyph_row - 1;
12282 if (fonts_changed_p)
12283 return 0;
12284 }
12285
12286 /* If bottom moved off end of frame, change mode line percentage. */
12287 if (XFASTINT (w->window_end_pos) <= 0
12288 && Z != IT_CHARPOS (it))
12289 w->update_mode_line = Qt;
12290
12291 /* Set window_end_pos to the offset of the last character displayed
12292 on the window from the end of current_buffer. Set
12293 window_end_vpos to its row number. */
12294 if (last_text_row)
12295 {
12296 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12297 w->window_end_bytepos
12298 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12299 w->window_end_pos
12300 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12301 w->window_end_vpos
12302 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12303 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12304 ->displays_text_p);
12305 }
12306 else
12307 {
12308 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12309 w->window_end_pos = make_number (Z - ZV);
12310 w->window_end_vpos = make_number (0);
12311 }
12312
12313 /* But that is not valid info until redisplay finishes. */
12314 w->window_end_valid = Qnil;
12315 return 1;
12316 }
12317
12318
12319 \f
12320 /************************************************************************
12321 Window redisplay reusing current matrix when buffer has not changed
12322 ************************************************************************/
12323
12324 /* Try redisplay of window W showing an unchanged buffer with a
12325 different window start than the last time it was displayed by
12326 reusing its current matrix. Value is non-zero if successful.
12327 W->start is the new window start. */
12328
12329 static int
12330 try_window_reusing_current_matrix (w)
12331 struct window *w;
12332 {
12333 struct frame *f = XFRAME (w->frame);
12334 struct glyph_row *row, *bottom_row;
12335 struct it it;
12336 struct run run;
12337 struct text_pos start, new_start;
12338 int nrows_scrolled, i;
12339 struct glyph_row *last_text_row;
12340 struct glyph_row *last_reused_text_row;
12341 struct glyph_row *start_row;
12342 int start_vpos, min_y, max_y;
12343
12344 #if GLYPH_DEBUG
12345 if (inhibit_try_window_reusing)
12346 return 0;
12347 #endif
12348
12349 if (/* This function doesn't handle terminal frames. */
12350 !FRAME_WINDOW_P (f)
12351 /* Don't try to reuse the display if windows have been split
12352 or such. */
12353 || windows_or_buffers_changed
12354 || cursor_type_changed)
12355 return 0;
12356
12357 /* Can't do this if region may have changed. */
12358 if ((!NILP (Vtransient_mark_mode)
12359 && !NILP (current_buffer->mark_active))
12360 || !NILP (w->region_showing)
12361 || !NILP (Vshow_trailing_whitespace))
12362 return 0;
12363
12364 /* If top-line visibility has changed, give up. */
12365 if (WINDOW_WANTS_HEADER_LINE_P (w)
12366 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12367 return 0;
12368
12369 /* Give up if old or new display is scrolled vertically. We could
12370 make this function handle this, but right now it doesn't. */
12371 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12372 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12373 return 0;
12374
12375 /* The variable new_start now holds the new window start. The old
12376 start `start' can be determined from the current matrix. */
12377 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12378 start = start_row->start.pos;
12379 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12380
12381 /* Clear the desired matrix for the display below. */
12382 clear_glyph_matrix (w->desired_matrix);
12383
12384 if (CHARPOS (new_start) <= CHARPOS (start))
12385 {
12386 int first_row_y;
12387
12388 /* Don't use this method if the display starts with an ellipsis
12389 displayed for invisible text. It's not easy to handle that case
12390 below, and it's certainly not worth the effort since this is
12391 not a frequent case. */
12392 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12393 return 0;
12394
12395 IF_DEBUG (debug_method_add (w, "twu1"));
12396
12397 /* Display up to a row that can be reused. The variable
12398 last_text_row is set to the last row displayed that displays
12399 text. Note that it.vpos == 0 if or if not there is a
12400 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12401 start_display (&it, w, new_start);
12402 first_row_y = it.current_y;
12403 w->cursor.vpos = -1;
12404 last_text_row = last_reused_text_row = NULL;
12405
12406 while (it.current_y < it.last_visible_y
12407 && IT_CHARPOS (it) < CHARPOS (start)
12408 && !fonts_changed_p)
12409 if (display_line (&it))
12410 last_text_row = it.glyph_row - 1;
12411
12412 /* A value of current_y < last_visible_y means that we stopped
12413 at the previous window start, which in turn means that we
12414 have at least one reusable row. */
12415 if (it.current_y < it.last_visible_y)
12416 {
12417 /* IT.vpos always starts from 0; it counts text lines. */
12418 nrows_scrolled = it.vpos;
12419
12420 /* Find PT if not already found in the lines displayed. */
12421 if (w->cursor.vpos < 0)
12422 {
12423 int dy = it.current_y - first_row_y;
12424
12425 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12426 row = row_containing_pos (w, PT, row, NULL, dy);
12427 if (row)
12428 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12429 dy, nrows_scrolled);
12430 else
12431 {
12432 clear_glyph_matrix (w->desired_matrix);
12433 return 0;
12434 }
12435 }
12436
12437 /* Scroll the display. Do it before the current matrix is
12438 changed. The problem here is that update has not yet
12439 run, i.e. part of the current matrix is not up to date.
12440 scroll_run_hook will clear the cursor, and use the
12441 current matrix to get the height of the row the cursor is
12442 in. */
12443 run.current_y = first_row_y;
12444 run.desired_y = it.current_y;
12445 run.height = it.last_visible_y - it.current_y;
12446
12447 if (run.height > 0 && run.current_y != run.desired_y)
12448 {
12449 update_begin (f);
12450 rif->update_window_begin_hook (w);
12451 rif->clear_window_mouse_face (w);
12452 rif->scroll_run_hook (w, &run);
12453 rif->update_window_end_hook (w, 0, 0);
12454 update_end (f);
12455 }
12456
12457 /* Shift current matrix down by nrows_scrolled lines. */
12458 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12459 rotate_matrix (w->current_matrix,
12460 start_vpos,
12461 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12462 nrows_scrolled);
12463
12464 /* Disable lines that must be updated. */
12465 for (i = 0; i < it.vpos; ++i)
12466 (start_row + i)->enabled_p = 0;
12467
12468 /* Re-compute Y positions. */
12469 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12470 max_y = it.last_visible_y;
12471 for (row = start_row + nrows_scrolled;
12472 row < bottom_row;
12473 ++row)
12474 {
12475 row->y = it.current_y;
12476 row->visible_height = row->height;
12477
12478 if (row->y < min_y)
12479 row->visible_height -= min_y - row->y;
12480 if (row->y + row->height > max_y)
12481 row->visible_height -= row->y + row->height - max_y;
12482 row->redraw_fringe_bitmaps_p = 1;
12483
12484 it.current_y += row->height;
12485
12486 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12487 last_reused_text_row = row;
12488 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12489 break;
12490 }
12491
12492 /* Disable lines in the current matrix which are now
12493 below the window. */
12494 for (++row; row < bottom_row; ++row)
12495 row->enabled_p = 0;
12496 }
12497
12498 /* Update window_end_pos etc.; last_reused_text_row is the last
12499 reused row from the current matrix containing text, if any.
12500 The value of last_text_row is the last displayed line
12501 containing text. */
12502 if (last_reused_text_row)
12503 {
12504 w->window_end_bytepos
12505 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12506 w->window_end_pos
12507 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12508 w->window_end_vpos
12509 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12510 w->current_matrix));
12511 }
12512 else if (last_text_row)
12513 {
12514 w->window_end_bytepos
12515 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12516 w->window_end_pos
12517 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12518 w->window_end_vpos
12519 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12520 }
12521 else
12522 {
12523 /* This window must be completely empty. */
12524 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12525 w->window_end_pos = make_number (Z - ZV);
12526 w->window_end_vpos = make_number (0);
12527 }
12528 w->window_end_valid = Qnil;
12529
12530 /* Update hint: don't try scrolling again in update_window. */
12531 w->desired_matrix->no_scrolling_p = 1;
12532
12533 #if GLYPH_DEBUG
12534 debug_method_add (w, "try_window_reusing_current_matrix 1");
12535 #endif
12536 return 1;
12537 }
12538 else if (CHARPOS (new_start) > CHARPOS (start))
12539 {
12540 struct glyph_row *pt_row, *row;
12541 struct glyph_row *first_reusable_row;
12542 struct glyph_row *first_row_to_display;
12543 int dy;
12544 int yb = window_text_bottom_y (w);
12545
12546 /* Find the row starting at new_start, if there is one. Don't
12547 reuse a partially visible line at the end. */
12548 first_reusable_row = start_row;
12549 while (first_reusable_row->enabled_p
12550 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12551 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12552 < CHARPOS (new_start)))
12553 ++first_reusable_row;
12554
12555 /* Give up if there is no row to reuse. */
12556 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12557 || !first_reusable_row->enabled_p
12558 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12559 != CHARPOS (new_start)))
12560 return 0;
12561
12562 /* We can reuse fully visible rows beginning with
12563 first_reusable_row to the end of the window. Set
12564 first_row_to_display to the first row that cannot be reused.
12565 Set pt_row to the row containing point, if there is any. */
12566 pt_row = NULL;
12567 for (first_row_to_display = first_reusable_row;
12568 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12569 ++first_row_to_display)
12570 {
12571 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12572 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12573 pt_row = first_row_to_display;
12574 }
12575
12576 /* Start displaying at the start of first_row_to_display. */
12577 xassert (first_row_to_display->y < yb);
12578 init_to_row_start (&it, w, first_row_to_display);
12579
12580 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12581 - start_vpos);
12582 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12583 - nrows_scrolled);
12584 it.current_y = (first_row_to_display->y - first_reusable_row->y
12585 + WINDOW_HEADER_LINE_HEIGHT (w));
12586
12587 /* Display lines beginning with first_row_to_display in the
12588 desired matrix. Set last_text_row to the last row displayed
12589 that displays text. */
12590 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12591 if (pt_row == NULL)
12592 w->cursor.vpos = -1;
12593 last_text_row = NULL;
12594 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12595 if (display_line (&it))
12596 last_text_row = it.glyph_row - 1;
12597
12598 /* Give up If point isn't in a row displayed or reused. */
12599 if (w->cursor.vpos < 0)
12600 {
12601 clear_glyph_matrix (w->desired_matrix);
12602 return 0;
12603 }
12604
12605 /* If point is in a reused row, adjust y and vpos of the cursor
12606 position. */
12607 if (pt_row)
12608 {
12609 w->cursor.vpos -= nrows_scrolled;
12610 w->cursor.y -= first_reusable_row->y - start_row->y;
12611 }
12612
12613 /* Scroll the display. */
12614 run.current_y = first_reusable_row->y;
12615 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12616 run.height = it.last_visible_y - run.current_y;
12617 dy = run.current_y - run.desired_y;
12618
12619 if (run.height)
12620 {
12621 update_begin (f);
12622 rif->update_window_begin_hook (w);
12623 rif->clear_window_mouse_face (w);
12624 rif->scroll_run_hook (w, &run);
12625 rif->update_window_end_hook (w, 0, 0);
12626 update_end (f);
12627 }
12628
12629 /* Adjust Y positions of reused rows. */
12630 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12631 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12632 max_y = it.last_visible_y;
12633 for (row = first_reusable_row; row < first_row_to_display; ++row)
12634 {
12635 row->y -= dy;
12636 row->visible_height = row->height;
12637 if (row->y < min_y)
12638 row->visible_height -= min_y - row->y;
12639 if (row->y + row->height > max_y)
12640 row->visible_height -= row->y + row->height - max_y;
12641 row->redraw_fringe_bitmaps_p = 1;
12642 }
12643
12644 /* Scroll the current matrix. */
12645 xassert (nrows_scrolled > 0);
12646 rotate_matrix (w->current_matrix,
12647 start_vpos,
12648 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12649 -nrows_scrolled);
12650
12651 /* Disable rows not reused. */
12652 for (row -= nrows_scrolled; row < bottom_row; ++row)
12653 row->enabled_p = 0;
12654
12655 /* Point may have moved to a different line, so we cannot assume that
12656 the previous cursor position is valid; locate the correct row. */
12657 if (pt_row)
12658 {
12659 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12660 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12661 row++)
12662 {
12663 w->cursor.vpos++;
12664 w->cursor.y = row->y;
12665 }
12666 if (row < bottom_row)
12667 {
12668 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12669 while (glyph->charpos < PT)
12670 {
12671 w->cursor.hpos++;
12672 w->cursor.x += glyph->pixel_width;
12673 glyph++;
12674 }
12675 }
12676 }
12677
12678 /* Adjust window end. A null value of last_text_row means that
12679 the window end is in reused rows which in turn means that
12680 only its vpos can have changed. */
12681 if (last_text_row)
12682 {
12683 w->window_end_bytepos
12684 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12685 w->window_end_pos
12686 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12687 w->window_end_vpos
12688 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12689 }
12690 else
12691 {
12692 w->window_end_vpos
12693 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12694 }
12695
12696 w->window_end_valid = Qnil;
12697 w->desired_matrix->no_scrolling_p = 1;
12698
12699 #if GLYPH_DEBUG
12700 debug_method_add (w, "try_window_reusing_current_matrix 2");
12701 #endif
12702 return 1;
12703 }
12704
12705 return 0;
12706 }
12707
12708
12709 \f
12710 /************************************************************************
12711 Window redisplay reusing current matrix when buffer has changed
12712 ************************************************************************/
12713
12714 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12715 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12716 int *, int *));
12717 static struct glyph_row *
12718 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12719 struct glyph_row *));
12720
12721
12722 /* Return the last row in MATRIX displaying text. If row START is
12723 non-null, start searching with that row. IT gives the dimensions
12724 of the display. Value is null if matrix is empty; otherwise it is
12725 a pointer to the row found. */
12726
12727 static struct glyph_row *
12728 find_last_row_displaying_text (matrix, it, start)
12729 struct glyph_matrix *matrix;
12730 struct it *it;
12731 struct glyph_row *start;
12732 {
12733 struct glyph_row *row, *row_found;
12734
12735 /* Set row_found to the last row in IT->w's current matrix
12736 displaying text. The loop looks funny but think of partially
12737 visible lines. */
12738 row_found = NULL;
12739 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12740 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12741 {
12742 xassert (row->enabled_p);
12743 row_found = row;
12744 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12745 break;
12746 ++row;
12747 }
12748
12749 return row_found;
12750 }
12751
12752
12753 /* Return the last row in the current matrix of W that is not affected
12754 by changes at the start of current_buffer that occurred since W's
12755 current matrix was built. Value is null if no such row exists.
12756
12757 BEG_UNCHANGED us the number of characters unchanged at the start of
12758 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12759 first changed character in current_buffer. Characters at positions <
12760 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12761 when the current matrix was built. */
12762
12763 static struct glyph_row *
12764 find_last_unchanged_at_beg_row (w)
12765 struct window *w;
12766 {
12767 int first_changed_pos = BEG + BEG_UNCHANGED;
12768 struct glyph_row *row;
12769 struct glyph_row *row_found = NULL;
12770 int yb = window_text_bottom_y (w);
12771
12772 /* Find the last row displaying unchanged text. */
12773 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12774 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12775 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12776 {
12777 if (/* If row ends before first_changed_pos, it is unchanged,
12778 except in some case. */
12779 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12780 /* When row ends in ZV and we write at ZV it is not
12781 unchanged. */
12782 && !row->ends_at_zv_p
12783 /* When first_changed_pos is the end of a continued line,
12784 row is not unchanged because it may be no longer
12785 continued. */
12786 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12787 && (row->continued_p
12788 || row->exact_window_width_line_p)))
12789 row_found = row;
12790
12791 /* Stop if last visible row. */
12792 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12793 break;
12794
12795 ++row;
12796 }
12797
12798 return row_found;
12799 }
12800
12801
12802 /* Find the first glyph row in the current matrix of W that is not
12803 affected by changes at the end of current_buffer since the
12804 time W's current matrix was built.
12805
12806 Return in *DELTA the number of chars by which buffer positions in
12807 unchanged text at the end of current_buffer must be adjusted.
12808
12809 Return in *DELTA_BYTES the corresponding number of bytes.
12810
12811 Value is null if no such row exists, i.e. all rows are affected by
12812 changes. */
12813
12814 static struct glyph_row *
12815 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12816 struct window *w;
12817 int *delta, *delta_bytes;
12818 {
12819 struct glyph_row *row;
12820 struct glyph_row *row_found = NULL;
12821
12822 *delta = *delta_bytes = 0;
12823
12824 /* Display must not have been paused, otherwise the current matrix
12825 is not up to date. */
12826 if (NILP (w->window_end_valid))
12827 abort ();
12828
12829 /* A value of window_end_pos >= END_UNCHANGED means that the window
12830 end is in the range of changed text. If so, there is no
12831 unchanged row at the end of W's current matrix. */
12832 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12833 return NULL;
12834
12835 /* Set row to the last row in W's current matrix displaying text. */
12836 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12837
12838 /* If matrix is entirely empty, no unchanged row exists. */
12839 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12840 {
12841 /* The value of row is the last glyph row in the matrix having a
12842 meaningful buffer position in it. The end position of row
12843 corresponds to window_end_pos. This allows us to translate
12844 buffer positions in the current matrix to current buffer
12845 positions for characters not in changed text. */
12846 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12847 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12848 int last_unchanged_pos, last_unchanged_pos_old;
12849 struct glyph_row *first_text_row
12850 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12851
12852 *delta = Z - Z_old;
12853 *delta_bytes = Z_BYTE - Z_BYTE_old;
12854
12855 /* Set last_unchanged_pos to the buffer position of the last
12856 character in the buffer that has not been changed. Z is the
12857 index + 1 of the last character in current_buffer, i.e. by
12858 subtracting END_UNCHANGED we get the index of the last
12859 unchanged character, and we have to add BEG to get its buffer
12860 position. */
12861 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12862 last_unchanged_pos_old = last_unchanged_pos - *delta;
12863
12864 /* Search backward from ROW for a row displaying a line that
12865 starts at a minimum position >= last_unchanged_pos_old. */
12866 for (; row > first_text_row; --row)
12867 {
12868 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12869 abort ();
12870
12871 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12872 row_found = row;
12873 }
12874 }
12875
12876 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12877 abort ();
12878
12879 return row_found;
12880 }
12881
12882
12883 /* Make sure that glyph rows in the current matrix of window W
12884 reference the same glyph memory as corresponding rows in the
12885 frame's frame matrix. This function is called after scrolling W's
12886 current matrix on a terminal frame in try_window_id and
12887 try_window_reusing_current_matrix. */
12888
12889 static void
12890 sync_frame_with_window_matrix_rows (w)
12891 struct window *w;
12892 {
12893 struct frame *f = XFRAME (w->frame);
12894 struct glyph_row *window_row, *window_row_end, *frame_row;
12895
12896 /* Preconditions: W must be a leaf window and full-width. Its frame
12897 must have a frame matrix. */
12898 xassert (NILP (w->hchild) && NILP (w->vchild));
12899 xassert (WINDOW_FULL_WIDTH_P (w));
12900 xassert (!FRAME_WINDOW_P (f));
12901
12902 /* If W is a full-width window, glyph pointers in W's current matrix
12903 have, by definition, to be the same as glyph pointers in the
12904 corresponding frame matrix. Note that frame matrices have no
12905 marginal areas (see build_frame_matrix). */
12906 window_row = w->current_matrix->rows;
12907 window_row_end = window_row + w->current_matrix->nrows;
12908 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12909 while (window_row < window_row_end)
12910 {
12911 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12912 struct glyph *end = window_row->glyphs[LAST_AREA];
12913
12914 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12915 frame_row->glyphs[TEXT_AREA] = start;
12916 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12917 frame_row->glyphs[LAST_AREA] = end;
12918
12919 /* Disable frame rows whose corresponding window rows have
12920 been disabled in try_window_id. */
12921 if (!window_row->enabled_p)
12922 frame_row->enabled_p = 0;
12923
12924 ++window_row, ++frame_row;
12925 }
12926 }
12927
12928
12929 /* Find the glyph row in window W containing CHARPOS. Consider all
12930 rows between START and END (not inclusive). END null means search
12931 all rows to the end of the display area of W. Value is the row
12932 containing CHARPOS or null. */
12933
12934 struct glyph_row *
12935 row_containing_pos (w, charpos, start, end, dy)
12936 struct window *w;
12937 int charpos;
12938 struct glyph_row *start, *end;
12939 int dy;
12940 {
12941 struct glyph_row *row = start;
12942 int last_y;
12943
12944 /* If we happen to start on a header-line, skip that. */
12945 if (row->mode_line_p)
12946 ++row;
12947
12948 if ((end && row >= end) || !row->enabled_p)
12949 return NULL;
12950
12951 last_y = window_text_bottom_y (w) - dy;
12952
12953 while (1)
12954 {
12955 /* Give up if we have gone too far. */
12956 if (end && row >= end)
12957 return NULL;
12958 /* This formerly returned if they were equal.
12959 I think that both quantities are of a "last plus one" type;
12960 if so, when they are equal, the row is within the screen. -- rms. */
12961 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12962 return NULL;
12963
12964 /* If it is in this row, return this row. */
12965 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12966 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12967 /* The end position of a row equals the start
12968 position of the next row. If CHARPOS is there, we
12969 would rather display it in the next line, except
12970 when this line ends in ZV. */
12971 && !row->ends_at_zv_p
12972 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12973 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12974 return row;
12975 ++row;
12976 }
12977 }
12978
12979
12980 /* Try to redisplay window W by reusing its existing display. W's
12981 current matrix must be up to date when this function is called,
12982 i.e. window_end_valid must not be nil.
12983
12984 Value is
12985
12986 1 if display has been updated
12987 0 if otherwise unsuccessful
12988 -1 if redisplay with same window start is known not to succeed
12989
12990 The following steps are performed:
12991
12992 1. Find the last row in the current matrix of W that is not
12993 affected by changes at the start of current_buffer. If no such row
12994 is found, give up.
12995
12996 2. Find the first row in W's current matrix that is not affected by
12997 changes at the end of current_buffer. Maybe there is no such row.
12998
12999 3. Display lines beginning with the row + 1 found in step 1 to the
13000 row found in step 2 or, if step 2 didn't find a row, to the end of
13001 the window.
13002
13003 4. If cursor is not known to appear on the window, give up.
13004
13005 5. If display stopped at the row found in step 2, scroll the
13006 display and current matrix as needed.
13007
13008 6. Maybe display some lines at the end of W, if we must. This can
13009 happen under various circumstances, like a partially visible line
13010 becoming fully visible, or because newly displayed lines are displayed
13011 in smaller font sizes.
13012
13013 7. Update W's window end information. */
13014
13015 static int
13016 try_window_id (w)
13017 struct window *w;
13018 {
13019 struct frame *f = XFRAME (w->frame);
13020 struct glyph_matrix *current_matrix = w->current_matrix;
13021 struct glyph_matrix *desired_matrix = w->desired_matrix;
13022 struct glyph_row *last_unchanged_at_beg_row;
13023 struct glyph_row *first_unchanged_at_end_row;
13024 struct glyph_row *row;
13025 struct glyph_row *bottom_row;
13026 int bottom_vpos;
13027 struct it it;
13028 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13029 struct text_pos start_pos;
13030 struct run run;
13031 int first_unchanged_at_end_vpos = 0;
13032 struct glyph_row *last_text_row, *last_text_row_at_end;
13033 struct text_pos start;
13034 int first_changed_charpos, last_changed_charpos;
13035
13036 #if GLYPH_DEBUG
13037 if (inhibit_try_window_id)
13038 return 0;
13039 #endif
13040
13041 /* This is handy for debugging. */
13042 #if 0
13043 #define GIVE_UP(X) \
13044 do { \
13045 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13046 return 0; \
13047 } while (0)
13048 #else
13049 #define GIVE_UP(X) return 0
13050 #endif
13051
13052 SET_TEXT_POS_FROM_MARKER (start, w->start);
13053
13054 /* Don't use this for mini-windows because these can show
13055 messages and mini-buffers, and we don't handle that here. */
13056 if (MINI_WINDOW_P (w))
13057 GIVE_UP (1);
13058
13059 /* This flag is used to prevent redisplay optimizations. */
13060 if (windows_or_buffers_changed || cursor_type_changed)
13061 GIVE_UP (2);
13062
13063 /* Verify that narrowing has not changed.
13064 Also verify that we were not told to prevent redisplay optimizations.
13065 It would be nice to further
13066 reduce the number of cases where this prevents try_window_id. */
13067 if (current_buffer->clip_changed
13068 || current_buffer->prevent_redisplay_optimizations_p)
13069 GIVE_UP (3);
13070
13071 /* Window must either use window-based redisplay or be full width. */
13072 if (!FRAME_WINDOW_P (f)
13073 && (!line_ins_del_ok
13074 || !WINDOW_FULL_WIDTH_P (w)))
13075 GIVE_UP (4);
13076
13077 /* Give up if point is not known NOT to appear in W. */
13078 if (PT < CHARPOS (start))
13079 GIVE_UP (5);
13080
13081 /* Another way to prevent redisplay optimizations. */
13082 if (XFASTINT (w->last_modified) == 0)
13083 GIVE_UP (6);
13084
13085 /* Verify that window is not hscrolled. */
13086 if (XFASTINT (w->hscroll) != 0)
13087 GIVE_UP (7);
13088
13089 /* Verify that display wasn't paused. */
13090 if (NILP (w->window_end_valid))
13091 GIVE_UP (8);
13092
13093 /* Can't use this if highlighting a region because a cursor movement
13094 will do more than just set the cursor. */
13095 if (!NILP (Vtransient_mark_mode)
13096 && !NILP (current_buffer->mark_active))
13097 GIVE_UP (9);
13098
13099 /* Likewise if highlighting trailing whitespace. */
13100 if (!NILP (Vshow_trailing_whitespace))
13101 GIVE_UP (11);
13102
13103 /* Likewise if showing a region. */
13104 if (!NILP (w->region_showing))
13105 GIVE_UP (10);
13106
13107 /* Can use this if overlay arrow position and or string have changed. */
13108 if (overlay_arrows_changed_p ())
13109 GIVE_UP (12);
13110
13111
13112 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13113 only if buffer has really changed. The reason is that the gap is
13114 initially at Z for freshly visited files. The code below would
13115 set end_unchanged to 0 in that case. */
13116 if (MODIFF > SAVE_MODIFF
13117 /* This seems to happen sometimes after saving a buffer. */
13118 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13119 {
13120 if (GPT - BEG < BEG_UNCHANGED)
13121 BEG_UNCHANGED = GPT - BEG;
13122 if (Z - GPT < END_UNCHANGED)
13123 END_UNCHANGED = Z - GPT;
13124 }
13125
13126 /* The position of the first and last character that has been changed. */
13127 first_changed_charpos = BEG + BEG_UNCHANGED;
13128 last_changed_charpos = Z - END_UNCHANGED;
13129
13130 /* If window starts after a line end, and the last change is in
13131 front of that newline, then changes don't affect the display.
13132 This case happens with stealth-fontification. Note that although
13133 the display is unchanged, glyph positions in the matrix have to
13134 be adjusted, of course. */
13135 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13136 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13137 && ((last_changed_charpos < CHARPOS (start)
13138 && CHARPOS (start) == BEGV)
13139 || (last_changed_charpos < CHARPOS (start) - 1
13140 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13141 {
13142 int Z_old, delta, Z_BYTE_old, delta_bytes;
13143 struct glyph_row *r0;
13144
13145 /* Compute how many chars/bytes have been added to or removed
13146 from the buffer. */
13147 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13148 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13149 delta = Z - Z_old;
13150 delta_bytes = Z_BYTE - Z_BYTE_old;
13151
13152 /* Give up if PT is not in the window. Note that it already has
13153 been checked at the start of try_window_id that PT is not in
13154 front of the window start. */
13155 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13156 GIVE_UP (13);
13157
13158 /* If window start is unchanged, we can reuse the whole matrix
13159 as is, after adjusting glyph positions. No need to compute
13160 the window end again, since its offset from Z hasn't changed. */
13161 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13162 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13163 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13164 /* PT must not be in a partially visible line. */
13165 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13166 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13167 {
13168 /* Adjust positions in the glyph matrix. */
13169 if (delta || delta_bytes)
13170 {
13171 struct glyph_row *r1
13172 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13173 increment_matrix_positions (w->current_matrix,
13174 MATRIX_ROW_VPOS (r0, current_matrix),
13175 MATRIX_ROW_VPOS (r1, current_matrix),
13176 delta, delta_bytes);
13177 }
13178
13179 /* Set the cursor. */
13180 row = row_containing_pos (w, PT, r0, NULL, 0);
13181 if (row)
13182 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13183 else
13184 abort ();
13185 return 1;
13186 }
13187 }
13188
13189 /* Handle the case that changes are all below what is displayed in
13190 the window, and that PT is in the window. This shortcut cannot
13191 be taken if ZV is visible in the window, and text has been added
13192 there that is visible in the window. */
13193 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13194 /* ZV is not visible in the window, or there are no
13195 changes at ZV, actually. */
13196 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13197 || first_changed_charpos == last_changed_charpos))
13198 {
13199 struct glyph_row *r0;
13200
13201 /* Give up if PT is not in the window. Note that it already has
13202 been checked at the start of try_window_id that PT is not in
13203 front of the window start. */
13204 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13205 GIVE_UP (14);
13206
13207 /* If window start is unchanged, we can reuse the whole matrix
13208 as is, without changing glyph positions since no text has
13209 been added/removed in front of the window end. */
13210 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13211 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13212 /* PT must not be in a partially visible line. */
13213 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13214 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13215 {
13216 /* We have to compute the window end anew since text
13217 can have been added/removed after it. */
13218 w->window_end_pos
13219 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13220 w->window_end_bytepos
13221 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13222
13223 /* Set the cursor. */
13224 row = row_containing_pos (w, PT, r0, NULL, 0);
13225 if (row)
13226 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13227 else
13228 abort ();
13229 return 2;
13230 }
13231 }
13232
13233 /* Give up if window start is in the changed area.
13234
13235 The condition used to read
13236
13237 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13238
13239 but why that was tested escapes me at the moment. */
13240 if (CHARPOS (start) >= first_changed_charpos
13241 && CHARPOS (start) <= last_changed_charpos)
13242 GIVE_UP (15);
13243
13244 /* Check that window start agrees with the start of the first glyph
13245 row in its current matrix. Check this after we know the window
13246 start is not in changed text, otherwise positions would not be
13247 comparable. */
13248 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13249 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13250 GIVE_UP (16);
13251
13252 /* Give up if the window ends in strings. Overlay strings
13253 at the end are difficult to handle, so don't try. */
13254 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13255 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13256 GIVE_UP (20);
13257
13258 /* Compute the position at which we have to start displaying new
13259 lines. Some of the lines at the top of the window might be
13260 reusable because they are not displaying changed text. Find the
13261 last row in W's current matrix not affected by changes at the
13262 start of current_buffer. Value is null if changes start in the
13263 first line of window. */
13264 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13265 if (last_unchanged_at_beg_row)
13266 {
13267 /* Avoid starting to display in the moddle of a character, a TAB
13268 for instance. This is easier than to set up the iterator
13269 exactly, and it's not a frequent case, so the additional
13270 effort wouldn't really pay off. */
13271 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13272 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13273 && last_unchanged_at_beg_row > w->current_matrix->rows)
13274 --last_unchanged_at_beg_row;
13275
13276 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13277 GIVE_UP (17);
13278
13279 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13280 GIVE_UP (18);
13281 start_pos = it.current.pos;
13282
13283 /* Start displaying new lines in the desired matrix at the same
13284 vpos we would use in the current matrix, i.e. below
13285 last_unchanged_at_beg_row. */
13286 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13287 current_matrix);
13288 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13289 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13290
13291 xassert (it.hpos == 0 && it.current_x == 0);
13292 }
13293 else
13294 {
13295 /* There are no reusable lines at the start of the window.
13296 Start displaying in the first text line. */
13297 start_display (&it, w, start);
13298 it.vpos = it.first_vpos;
13299 start_pos = it.current.pos;
13300 }
13301
13302 /* Find the first row that is not affected by changes at the end of
13303 the buffer. Value will be null if there is no unchanged row, in
13304 which case we must redisplay to the end of the window. delta
13305 will be set to the value by which buffer positions beginning with
13306 first_unchanged_at_end_row have to be adjusted due to text
13307 changes. */
13308 first_unchanged_at_end_row
13309 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13310 IF_DEBUG (debug_delta = delta);
13311 IF_DEBUG (debug_delta_bytes = delta_bytes);
13312
13313 /* Set stop_pos to the buffer position up to which we will have to
13314 display new lines. If first_unchanged_at_end_row != NULL, this
13315 is the buffer position of the start of the line displayed in that
13316 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13317 that we don't stop at a buffer position. */
13318 stop_pos = 0;
13319 if (first_unchanged_at_end_row)
13320 {
13321 xassert (last_unchanged_at_beg_row == NULL
13322 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13323
13324 /* If this is a continuation line, move forward to the next one
13325 that isn't. Changes in lines above affect this line.
13326 Caution: this may move first_unchanged_at_end_row to a row
13327 not displaying text. */
13328 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13329 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13330 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13331 < it.last_visible_y))
13332 ++first_unchanged_at_end_row;
13333
13334 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13335 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13336 >= it.last_visible_y))
13337 first_unchanged_at_end_row = NULL;
13338 else
13339 {
13340 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13341 + delta);
13342 first_unchanged_at_end_vpos
13343 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13344 xassert (stop_pos >= Z - END_UNCHANGED);
13345 }
13346 }
13347 else if (last_unchanged_at_beg_row == NULL)
13348 GIVE_UP (19);
13349
13350
13351 #if GLYPH_DEBUG
13352
13353 /* Either there is no unchanged row at the end, or the one we have
13354 now displays text. This is a necessary condition for the window
13355 end pos calculation at the end of this function. */
13356 xassert (first_unchanged_at_end_row == NULL
13357 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13358
13359 debug_last_unchanged_at_beg_vpos
13360 = (last_unchanged_at_beg_row
13361 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13362 : -1);
13363 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13364
13365 #endif /* GLYPH_DEBUG != 0 */
13366
13367
13368 /* Display new lines. Set last_text_row to the last new line
13369 displayed which has text on it, i.e. might end up as being the
13370 line where the window_end_vpos is. */
13371 w->cursor.vpos = -1;
13372 last_text_row = NULL;
13373 overlay_arrow_seen = 0;
13374 while (it.current_y < it.last_visible_y
13375 && !fonts_changed_p
13376 && (first_unchanged_at_end_row == NULL
13377 || IT_CHARPOS (it) < stop_pos))
13378 {
13379 if (display_line (&it))
13380 last_text_row = it.glyph_row - 1;
13381 }
13382
13383 if (fonts_changed_p)
13384 return -1;
13385
13386
13387 /* Compute differences in buffer positions, y-positions etc. for
13388 lines reused at the bottom of the window. Compute what we can
13389 scroll. */
13390 if (first_unchanged_at_end_row
13391 /* No lines reused because we displayed everything up to the
13392 bottom of the window. */
13393 && it.current_y < it.last_visible_y)
13394 {
13395 dvpos = (it.vpos
13396 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13397 current_matrix));
13398 dy = it.current_y - first_unchanged_at_end_row->y;
13399 run.current_y = first_unchanged_at_end_row->y;
13400 run.desired_y = run.current_y + dy;
13401 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13402 }
13403 else
13404 {
13405 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13406 first_unchanged_at_end_row = NULL;
13407 }
13408 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13409
13410
13411 /* Find the cursor if not already found. We have to decide whether
13412 PT will appear on this window (it sometimes doesn't, but this is
13413 not a very frequent case.) This decision has to be made before
13414 the current matrix is altered. A value of cursor.vpos < 0 means
13415 that PT is either in one of the lines beginning at
13416 first_unchanged_at_end_row or below the window. Don't care for
13417 lines that might be displayed later at the window end; as
13418 mentioned, this is not a frequent case. */
13419 if (w->cursor.vpos < 0)
13420 {
13421 /* Cursor in unchanged rows at the top? */
13422 if (PT < CHARPOS (start_pos)
13423 && last_unchanged_at_beg_row)
13424 {
13425 row = row_containing_pos (w, PT,
13426 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13427 last_unchanged_at_beg_row + 1, 0);
13428 if (row)
13429 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13430 }
13431
13432 /* Start from first_unchanged_at_end_row looking for PT. */
13433 else if (first_unchanged_at_end_row)
13434 {
13435 row = row_containing_pos (w, PT - delta,
13436 first_unchanged_at_end_row, NULL, 0);
13437 if (row)
13438 set_cursor_from_row (w, row, w->current_matrix, delta,
13439 delta_bytes, dy, dvpos);
13440 }
13441
13442 /* Give up if cursor was not found. */
13443 if (w->cursor.vpos < 0)
13444 {
13445 clear_glyph_matrix (w->desired_matrix);
13446 return -1;
13447 }
13448 }
13449
13450 /* Don't let the cursor end in the scroll margins. */
13451 {
13452 int this_scroll_margin, cursor_height;
13453
13454 this_scroll_margin = max (0, scroll_margin);
13455 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13456 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13457 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13458
13459 if ((w->cursor.y < this_scroll_margin
13460 && CHARPOS (start) > BEGV)
13461 /* Old redisplay didn't take scroll margin into account at the bottom,
13462 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13463 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
13464 {
13465 w->cursor.vpos = -1;
13466 clear_glyph_matrix (w->desired_matrix);
13467 return -1;
13468 }
13469 }
13470
13471 /* Scroll the display. Do it before changing the current matrix so
13472 that xterm.c doesn't get confused about where the cursor glyph is
13473 found. */
13474 if (dy && run.height)
13475 {
13476 update_begin (f);
13477
13478 if (FRAME_WINDOW_P (f))
13479 {
13480 rif->update_window_begin_hook (w);
13481 rif->clear_window_mouse_face (w);
13482 rif->scroll_run_hook (w, &run);
13483 rif->update_window_end_hook (w, 0, 0);
13484 }
13485 else
13486 {
13487 /* Terminal frame. In this case, dvpos gives the number of
13488 lines to scroll by; dvpos < 0 means scroll up. */
13489 int first_unchanged_at_end_vpos
13490 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13491 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13492 int end = (WINDOW_TOP_EDGE_LINE (w)
13493 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13494 + window_internal_height (w));
13495
13496 /* Perform the operation on the screen. */
13497 if (dvpos > 0)
13498 {
13499 /* Scroll last_unchanged_at_beg_row to the end of the
13500 window down dvpos lines. */
13501 set_terminal_window (end);
13502
13503 /* On dumb terminals delete dvpos lines at the end
13504 before inserting dvpos empty lines. */
13505 if (!scroll_region_ok)
13506 ins_del_lines (end - dvpos, -dvpos);
13507
13508 /* Insert dvpos empty lines in front of
13509 last_unchanged_at_beg_row. */
13510 ins_del_lines (from, dvpos);
13511 }
13512 else if (dvpos < 0)
13513 {
13514 /* Scroll up last_unchanged_at_beg_vpos to the end of
13515 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13516 set_terminal_window (end);
13517
13518 /* Delete dvpos lines in front of
13519 last_unchanged_at_beg_vpos. ins_del_lines will set
13520 the cursor to the given vpos and emit |dvpos| delete
13521 line sequences. */
13522 ins_del_lines (from + dvpos, dvpos);
13523
13524 /* On a dumb terminal insert dvpos empty lines at the
13525 end. */
13526 if (!scroll_region_ok)
13527 ins_del_lines (end + dvpos, -dvpos);
13528 }
13529
13530 set_terminal_window (0);
13531 }
13532
13533 update_end (f);
13534 }
13535
13536 /* Shift reused rows of the current matrix to the right position.
13537 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13538 text. */
13539 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13540 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13541 if (dvpos < 0)
13542 {
13543 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13544 bottom_vpos, dvpos);
13545 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13546 bottom_vpos, 0);
13547 }
13548 else if (dvpos > 0)
13549 {
13550 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13551 bottom_vpos, dvpos);
13552 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13553 first_unchanged_at_end_vpos + dvpos, 0);
13554 }
13555
13556 /* For frame-based redisplay, make sure that current frame and window
13557 matrix are in sync with respect to glyph memory. */
13558 if (!FRAME_WINDOW_P (f))
13559 sync_frame_with_window_matrix_rows (w);
13560
13561 /* Adjust buffer positions in reused rows. */
13562 if (delta)
13563 increment_matrix_positions (current_matrix,
13564 first_unchanged_at_end_vpos + dvpos,
13565 bottom_vpos, delta, delta_bytes);
13566
13567 /* Adjust Y positions. */
13568 if (dy)
13569 shift_glyph_matrix (w, current_matrix,
13570 first_unchanged_at_end_vpos + dvpos,
13571 bottom_vpos, dy);
13572
13573 if (first_unchanged_at_end_row)
13574 first_unchanged_at_end_row += dvpos;
13575
13576 /* If scrolling up, there may be some lines to display at the end of
13577 the window. */
13578 last_text_row_at_end = NULL;
13579 if (dy < 0)
13580 {
13581 /* Scrolling up can leave for example a partially visible line
13582 at the end of the window to be redisplayed. */
13583 /* Set last_row to the glyph row in the current matrix where the
13584 window end line is found. It has been moved up or down in
13585 the matrix by dvpos. */
13586 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13587 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13588
13589 /* If last_row is the window end line, it should display text. */
13590 xassert (last_row->displays_text_p);
13591
13592 /* If window end line was partially visible before, begin
13593 displaying at that line. Otherwise begin displaying with the
13594 line following it. */
13595 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13596 {
13597 init_to_row_start (&it, w, last_row);
13598 it.vpos = last_vpos;
13599 it.current_y = last_row->y;
13600 }
13601 else
13602 {
13603 init_to_row_end (&it, w, last_row);
13604 it.vpos = 1 + last_vpos;
13605 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13606 ++last_row;
13607 }
13608
13609 /* We may start in a continuation line. If so, we have to
13610 get the right continuation_lines_width and current_x. */
13611 it.continuation_lines_width = last_row->continuation_lines_width;
13612 it.hpos = it.current_x = 0;
13613
13614 /* Display the rest of the lines at the window end. */
13615 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13616 while (it.current_y < it.last_visible_y
13617 && !fonts_changed_p)
13618 {
13619 /* Is it always sure that the display agrees with lines in
13620 the current matrix? I don't think so, so we mark rows
13621 displayed invalid in the current matrix by setting their
13622 enabled_p flag to zero. */
13623 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13624 if (display_line (&it))
13625 last_text_row_at_end = it.glyph_row - 1;
13626 }
13627 }
13628
13629 /* Update window_end_pos and window_end_vpos. */
13630 if (first_unchanged_at_end_row
13631 && first_unchanged_at_end_row->y < it.last_visible_y
13632 && !last_text_row_at_end)
13633 {
13634 /* Window end line if one of the preserved rows from the current
13635 matrix. Set row to the last row displaying text in current
13636 matrix starting at first_unchanged_at_end_row, after
13637 scrolling. */
13638 xassert (first_unchanged_at_end_row->displays_text_p);
13639 row = find_last_row_displaying_text (w->current_matrix, &it,
13640 first_unchanged_at_end_row);
13641 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13642
13643 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13644 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13645 w->window_end_vpos
13646 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13647 xassert (w->window_end_bytepos >= 0);
13648 IF_DEBUG (debug_method_add (w, "A"));
13649 }
13650 else if (last_text_row_at_end)
13651 {
13652 w->window_end_pos
13653 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13654 w->window_end_bytepos
13655 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13656 w->window_end_vpos
13657 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13658 xassert (w->window_end_bytepos >= 0);
13659 IF_DEBUG (debug_method_add (w, "B"));
13660 }
13661 else if (last_text_row)
13662 {
13663 /* We have displayed either to the end of the window or at the
13664 end of the window, i.e. the last row with text is to be found
13665 in the desired matrix. */
13666 w->window_end_pos
13667 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13668 w->window_end_bytepos
13669 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13670 w->window_end_vpos
13671 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13672 xassert (w->window_end_bytepos >= 0);
13673 }
13674 else if (first_unchanged_at_end_row == NULL
13675 && last_text_row == NULL
13676 && last_text_row_at_end == NULL)
13677 {
13678 /* Displayed to end of window, but no line containing text was
13679 displayed. Lines were deleted at the end of the window. */
13680 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13681 int vpos = XFASTINT (w->window_end_vpos);
13682 struct glyph_row *current_row = current_matrix->rows + vpos;
13683 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13684
13685 for (row = NULL;
13686 row == NULL && vpos >= first_vpos;
13687 --vpos, --current_row, --desired_row)
13688 {
13689 if (desired_row->enabled_p)
13690 {
13691 if (desired_row->displays_text_p)
13692 row = desired_row;
13693 }
13694 else if (current_row->displays_text_p)
13695 row = current_row;
13696 }
13697
13698 xassert (row != NULL);
13699 w->window_end_vpos = make_number (vpos + 1);
13700 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13701 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13702 xassert (w->window_end_bytepos >= 0);
13703 IF_DEBUG (debug_method_add (w, "C"));
13704 }
13705 else
13706 abort ();
13707
13708 #if 0 /* This leads to problems, for instance when the cursor is
13709 at ZV, and the cursor line displays no text. */
13710 /* Disable rows below what's displayed in the window. This makes
13711 debugging easier. */
13712 enable_glyph_matrix_rows (current_matrix,
13713 XFASTINT (w->window_end_vpos) + 1,
13714 bottom_vpos, 0);
13715 #endif
13716
13717 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13718 debug_end_vpos = XFASTINT (w->window_end_vpos));
13719
13720 /* Record that display has not been completed. */
13721 w->window_end_valid = Qnil;
13722 w->desired_matrix->no_scrolling_p = 1;
13723 return 3;
13724
13725 #undef GIVE_UP
13726 }
13727
13728
13729 \f
13730 /***********************************************************************
13731 More debugging support
13732 ***********************************************************************/
13733
13734 #if GLYPH_DEBUG
13735
13736 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13737 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13738 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13739
13740
13741 /* Dump the contents of glyph matrix MATRIX on stderr.
13742
13743 GLYPHS 0 means don't show glyph contents.
13744 GLYPHS 1 means show glyphs in short form
13745 GLYPHS > 1 means show glyphs in long form. */
13746
13747 void
13748 dump_glyph_matrix (matrix, glyphs)
13749 struct glyph_matrix *matrix;
13750 int glyphs;
13751 {
13752 int i;
13753 for (i = 0; i < matrix->nrows; ++i)
13754 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13755 }
13756
13757
13758 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13759 the glyph row and area where the glyph comes from. */
13760
13761 void
13762 dump_glyph (row, glyph, area)
13763 struct glyph_row *row;
13764 struct glyph *glyph;
13765 int area;
13766 {
13767 if (glyph->type == CHAR_GLYPH)
13768 {
13769 fprintf (stderr,
13770 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13771 glyph - row->glyphs[TEXT_AREA],
13772 'C',
13773 glyph->charpos,
13774 (BUFFERP (glyph->object)
13775 ? 'B'
13776 : (STRINGP (glyph->object)
13777 ? 'S'
13778 : '-')),
13779 glyph->pixel_width,
13780 glyph->u.ch,
13781 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13782 ? glyph->u.ch
13783 : '.'),
13784 glyph->face_id,
13785 glyph->left_box_line_p,
13786 glyph->right_box_line_p);
13787 }
13788 else if (glyph->type == STRETCH_GLYPH)
13789 {
13790 fprintf (stderr,
13791 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13792 glyph - row->glyphs[TEXT_AREA],
13793 'S',
13794 glyph->charpos,
13795 (BUFFERP (glyph->object)
13796 ? 'B'
13797 : (STRINGP (glyph->object)
13798 ? 'S'
13799 : '-')),
13800 glyph->pixel_width,
13801 0,
13802 '.',
13803 glyph->face_id,
13804 glyph->left_box_line_p,
13805 glyph->right_box_line_p);
13806 }
13807 else if (glyph->type == IMAGE_GLYPH)
13808 {
13809 fprintf (stderr,
13810 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13811 glyph - row->glyphs[TEXT_AREA],
13812 'I',
13813 glyph->charpos,
13814 (BUFFERP (glyph->object)
13815 ? 'B'
13816 : (STRINGP (glyph->object)
13817 ? 'S'
13818 : '-')),
13819 glyph->pixel_width,
13820 glyph->u.img_id,
13821 '.',
13822 glyph->face_id,
13823 glyph->left_box_line_p,
13824 glyph->right_box_line_p);
13825 }
13826 }
13827
13828
13829 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13830 GLYPHS 0 means don't show glyph contents.
13831 GLYPHS 1 means show glyphs in short form
13832 GLYPHS > 1 means show glyphs in long form. */
13833
13834 void
13835 dump_glyph_row (row, vpos, glyphs)
13836 struct glyph_row *row;
13837 int vpos, glyphs;
13838 {
13839 if (glyphs != 1)
13840 {
13841 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13842 fprintf (stderr, "=======================================================================\n");
13843
13844 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13845 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13846 vpos,
13847 MATRIX_ROW_START_CHARPOS (row),
13848 MATRIX_ROW_END_CHARPOS (row),
13849 row->used[TEXT_AREA],
13850 row->contains_overlapping_glyphs_p,
13851 row->enabled_p,
13852 row->truncated_on_left_p,
13853 row->truncated_on_right_p,
13854 row->overlay_arrow_p,
13855 row->continued_p,
13856 MATRIX_ROW_CONTINUATION_LINE_P (row),
13857 row->displays_text_p,
13858 row->ends_at_zv_p,
13859 row->fill_line_p,
13860 row->ends_in_middle_of_char_p,
13861 row->starts_in_middle_of_char_p,
13862 row->mouse_face_p,
13863 row->x,
13864 row->y,
13865 row->pixel_width,
13866 row->height,
13867 row->visible_height,
13868 row->ascent,
13869 row->phys_ascent);
13870 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13871 row->end.overlay_string_index,
13872 row->continuation_lines_width);
13873 fprintf (stderr, "%9d %5d\n",
13874 CHARPOS (row->start.string_pos),
13875 CHARPOS (row->end.string_pos));
13876 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13877 row->end.dpvec_index);
13878 }
13879
13880 if (glyphs > 1)
13881 {
13882 int area;
13883
13884 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13885 {
13886 struct glyph *glyph = row->glyphs[area];
13887 struct glyph *glyph_end = glyph + row->used[area];
13888
13889 /* Glyph for a line end in text. */
13890 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13891 ++glyph_end;
13892
13893 if (glyph < glyph_end)
13894 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13895
13896 for (; glyph < glyph_end; ++glyph)
13897 dump_glyph (row, glyph, area);
13898 }
13899 }
13900 else if (glyphs == 1)
13901 {
13902 int area;
13903
13904 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13905 {
13906 char *s = (char *) alloca (row->used[area] + 1);
13907 int i;
13908
13909 for (i = 0; i < row->used[area]; ++i)
13910 {
13911 struct glyph *glyph = row->glyphs[area] + i;
13912 if (glyph->type == CHAR_GLYPH
13913 && glyph->u.ch < 0x80
13914 && glyph->u.ch >= ' ')
13915 s[i] = glyph->u.ch;
13916 else
13917 s[i] = '.';
13918 }
13919
13920 s[i] = '\0';
13921 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13922 }
13923 }
13924 }
13925
13926
13927 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13928 Sdump_glyph_matrix, 0, 1, "p",
13929 doc: /* Dump the current matrix of the selected window to stderr.
13930 Shows contents of glyph row structures. With non-nil
13931 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13932 glyphs in short form, otherwise show glyphs in long form. */)
13933 (glyphs)
13934 Lisp_Object glyphs;
13935 {
13936 struct window *w = XWINDOW (selected_window);
13937 struct buffer *buffer = XBUFFER (w->buffer);
13938
13939 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13940 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13941 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13942 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13943 fprintf (stderr, "=============================================\n");
13944 dump_glyph_matrix (w->current_matrix,
13945 NILP (glyphs) ? 0 : XINT (glyphs));
13946 return Qnil;
13947 }
13948
13949
13950 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13951 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13952 ()
13953 {
13954 struct frame *f = XFRAME (selected_frame);
13955 dump_glyph_matrix (f->current_matrix, 1);
13956 return Qnil;
13957 }
13958
13959
13960 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13961 doc: /* Dump glyph row ROW to stderr.
13962 GLYPH 0 means don't dump glyphs.
13963 GLYPH 1 means dump glyphs in short form.
13964 GLYPH > 1 or omitted means dump glyphs in long form. */)
13965 (row, glyphs)
13966 Lisp_Object row, glyphs;
13967 {
13968 struct glyph_matrix *matrix;
13969 int vpos;
13970
13971 CHECK_NUMBER (row);
13972 matrix = XWINDOW (selected_window)->current_matrix;
13973 vpos = XINT (row);
13974 if (vpos >= 0 && vpos < matrix->nrows)
13975 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13976 vpos,
13977 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13978 return Qnil;
13979 }
13980
13981
13982 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13983 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13984 GLYPH 0 means don't dump glyphs.
13985 GLYPH 1 means dump glyphs in short form.
13986 GLYPH > 1 or omitted means dump glyphs in long form. */)
13987 (row, glyphs)
13988 Lisp_Object row, glyphs;
13989 {
13990 struct frame *sf = SELECTED_FRAME ();
13991 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13992 int vpos;
13993
13994 CHECK_NUMBER (row);
13995 vpos = XINT (row);
13996 if (vpos >= 0 && vpos < m->nrows)
13997 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13998 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13999 return Qnil;
14000 }
14001
14002
14003 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14004 doc: /* Toggle tracing of redisplay.
14005 With ARG, turn tracing on if and only if ARG is positive. */)
14006 (arg)
14007 Lisp_Object arg;
14008 {
14009 if (NILP (arg))
14010 trace_redisplay_p = !trace_redisplay_p;
14011 else
14012 {
14013 arg = Fprefix_numeric_value (arg);
14014 trace_redisplay_p = XINT (arg) > 0;
14015 }
14016
14017 return Qnil;
14018 }
14019
14020
14021 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14022 doc: /* Like `format', but print result to stderr.
14023 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14024 (nargs, args)
14025 int nargs;
14026 Lisp_Object *args;
14027 {
14028 Lisp_Object s = Fformat (nargs, args);
14029 fprintf (stderr, "%s", SDATA (s));
14030 return Qnil;
14031 }
14032
14033 #endif /* GLYPH_DEBUG */
14034
14035
14036 \f
14037 /***********************************************************************
14038 Building Desired Matrix Rows
14039 ***********************************************************************/
14040
14041 /* Return a temporary glyph row holding the glyphs of an overlay
14042 arrow. Only used for non-window-redisplay windows. */
14043
14044 static struct glyph_row *
14045 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14046 struct window *w;
14047 Lisp_Object overlay_arrow_string;
14048 {
14049 struct frame *f = XFRAME (WINDOW_FRAME (w));
14050 struct buffer *buffer = XBUFFER (w->buffer);
14051 struct buffer *old = current_buffer;
14052 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14053 int arrow_len = SCHARS (overlay_arrow_string);
14054 const unsigned char *arrow_end = arrow_string + arrow_len;
14055 const unsigned char *p;
14056 struct it it;
14057 int multibyte_p;
14058 int n_glyphs_before;
14059
14060 set_buffer_temp (buffer);
14061 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14062 it.glyph_row->used[TEXT_AREA] = 0;
14063 SET_TEXT_POS (it.position, 0, 0);
14064
14065 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14066 p = arrow_string;
14067 while (p < arrow_end)
14068 {
14069 Lisp_Object face, ilisp;
14070
14071 /* Get the next character. */
14072 if (multibyte_p)
14073 it.c = string_char_and_length (p, arrow_len, &it.len);
14074 else
14075 it.c = *p, it.len = 1;
14076 p += it.len;
14077
14078 /* Get its face. */
14079 ilisp = make_number (p - arrow_string);
14080 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14081 it.face_id = compute_char_face (f, it.c, face);
14082
14083 /* Compute its width, get its glyphs. */
14084 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14085 SET_TEXT_POS (it.position, -1, -1);
14086 PRODUCE_GLYPHS (&it);
14087
14088 /* If this character doesn't fit any more in the line, we have
14089 to remove some glyphs. */
14090 if (it.current_x > it.last_visible_x)
14091 {
14092 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14093 break;
14094 }
14095 }
14096
14097 set_buffer_temp (old);
14098 return it.glyph_row;
14099 }
14100
14101
14102 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14103 glyphs are only inserted for terminal frames since we can't really
14104 win with truncation glyphs when partially visible glyphs are
14105 involved. Which glyphs to insert is determined by
14106 produce_special_glyphs. */
14107
14108 static void
14109 insert_left_trunc_glyphs (it)
14110 struct it *it;
14111 {
14112 struct it truncate_it;
14113 struct glyph *from, *end, *to, *toend;
14114
14115 xassert (!FRAME_WINDOW_P (it->f));
14116
14117 /* Get the truncation glyphs. */
14118 truncate_it = *it;
14119 truncate_it.current_x = 0;
14120 truncate_it.face_id = DEFAULT_FACE_ID;
14121 truncate_it.glyph_row = &scratch_glyph_row;
14122 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14123 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14124 truncate_it.object = make_number (0);
14125 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14126
14127 /* Overwrite glyphs from IT with truncation glyphs. */
14128 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14129 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14130 to = it->glyph_row->glyphs[TEXT_AREA];
14131 toend = to + it->glyph_row->used[TEXT_AREA];
14132
14133 while (from < end)
14134 *to++ = *from++;
14135
14136 /* There may be padding glyphs left over. Overwrite them too. */
14137 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14138 {
14139 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14140 while (from < end)
14141 *to++ = *from++;
14142 }
14143
14144 if (to > toend)
14145 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14146 }
14147
14148
14149 /* Compute the pixel height and width of IT->glyph_row.
14150
14151 Most of the time, ascent and height of a display line will be equal
14152 to the max_ascent and max_height values of the display iterator
14153 structure. This is not the case if
14154
14155 1. We hit ZV without displaying anything. In this case, max_ascent
14156 and max_height will be zero.
14157
14158 2. We have some glyphs that don't contribute to the line height.
14159 (The glyph row flag contributes_to_line_height_p is for future
14160 pixmap extensions).
14161
14162 The first case is easily covered by using default values because in
14163 these cases, the line height does not really matter, except that it
14164 must not be zero. */
14165
14166 static void
14167 compute_line_metrics (it)
14168 struct it *it;
14169 {
14170 struct glyph_row *row = it->glyph_row;
14171 int area, i;
14172
14173 if (FRAME_WINDOW_P (it->f))
14174 {
14175 int i, min_y, max_y;
14176
14177 /* The line may consist of one space only, that was added to
14178 place the cursor on it. If so, the row's height hasn't been
14179 computed yet. */
14180 if (row->height == 0)
14181 {
14182 if (it->max_ascent + it->max_descent == 0)
14183 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14184 row->ascent = it->max_ascent;
14185 row->height = it->max_ascent + it->max_descent;
14186 row->phys_ascent = it->max_phys_ascent;
14187 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14188 }
14189
14190 /* Compute the width of this line. */
14191 row->pixel_width = row->x;
14192 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14193 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14194
14195 xassert (row->pixel_width >= 0);
14196 xassert (row->ascent >= 0 && row->height > 0);
14197
14198 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14199 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14200
14201 /* If first line's physical ascent is larger than its logical
14202 ascent, use the physical ascent, and make the row taller.
14203 This makes accented characters fully visible. */
14204 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14205 && row->phys_ascent > row->ascent)
14206 {
14207 row->height += row->phys_ascent - row->ascent;
14208 row->ascent = row->phys_ascent;
14209 }
14210
14211 /* Compute how much of the line is visible. */
14212 row->visible_height = row->height;
14213
14214 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14215 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14216
14217 if (row->y < min_y)
14218 row->visible_height -= min_y - row->y;
14219 if (row->y + row->height > max_y)
14220 row->visible_height -= row->y + row->height - max_y;
14221 }
14222 else
14223 {
14224 row->pixel_width = row->used[TEXT_AREA];
14225 if (row->continued_p)
14226 row->pixel_width -= it->continuation_pixel_width;
14227 else if (row->truncated_on_right_p)
14228 row->pixel_width -= it->truncation_pixel_width;
14229 row->ascent = row->phys_ascent = 0;
14230 row->height = row->phys_height = row->visible_height = 1;
14231 }
14232
14233 /* Compute a hash code for this row. */
14234 row->hash = 0;
14235 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14236 for (i = 0; i < row->used[area]; ++i)
14237 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14238 + row->glyphs[area][i].u.val
14239 + row->glyphs[area][i].face_id
14240 + row->glyphs[area][i].padding_p
14241 + (row->glyphs[area][i].type << 2));
14242
14243 it->max_ascent = it->max_descent = 0;
14244 it->max_phys_ascent = it->max_phys_descent = 0;
14245 }
14246
14247
14248 /* Append one space to the glyph row of iterator IT if doing a
14249 window-based redisplay. The space has the same face as
14250 IT->face_id. Value is non-zero if a space was added.
14251
14252 This function is called to make sure that there is always one glyph
14253 at the end of a glyph row that the cursor can be set on under
14254 window-systems. (If there weren't such a glyph we would not know
14255 how wide and tall a box cursor should be displayed).
14256
14257 At the same time this space let's a nicely handle clearing to the
14258 end of the line if the row ends in italic text. */
14259
14260 static int
14261 append_space_for_newline (it, default_face_p)
14262 struct it *it;
14263 int default_face_p;
14264 {
14265 if (FRAME_WINDOW_P (it->f))
14266 {
14267 int n = it->glyph_row->used[TEXT_AREA];
14268
14269 if (it->glyph_row->glyphs[TEXT_AREA] + n
14270 < it->glyph_row->glyphs[1 + TEXT_AREA])
14271 {
14272 /* Save some values that must not be changed.
14273 Must save IT->c and IT->len because otherwise
14274 ITERATOR_AT_END_P wouldn't work anymore after
14275 append_space_for_newline has been called. */
14276 enum display_element_type saved_what = it->what;
14277 int saved_c = it->c, saved_len = it->len;
14278 int saved_x = it->current_x;
14279 int saved_face_id = it->face_id;
14280 struct text_pos saved_pos;
14281 Lisp_Object saved_object;
14282 struct face *face;
14283
14284 saved_object = it->object;
14285 saved_pos = it->position;
14286
14287 it->what = IT_CHARACTER;
14288 bzero (&it->position, sizeof it->position);
14289 it->object = make_number (0);
14290 it->c = ' ';
14291 it->len = 1;
14292
14293 if (default_face_p)
14294 it->face_id = DEFAULT_FACE_ID;
14295 else if (it->face_before_selective_p)
14296 it->face_id = it->saved_face_id;
14297 face = FACE_FROM_ID (it->f, it->face_id);
14298 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14299
14300 PRODUCE_GLYPHS (it);
14301
14302 it->override_ascent = -1;
14303 it->constrain_row_ascent_descent_p = 0;
14304 it->current_x = saved_x;
14305 it->object = saved_object;
14306 it->position = saved_pos;
14307 it->what = saved_what;
14308 it->face_id = saved_face_id;
14309 it->len = saved_len;
14310 it->c = saved_c;
14311 return 1;
14312 }
14313 }
14314
14315 return 0;
14316 }
14317
14318
14319 /* Extend the face of the last glyph in the text area of IT->glyph_row
14320 to the end of the display line. Called from display_line.
14321 If the glyph row is empty, add a space glyph to it so that we
14322 know the face to draw. Set the glyph row flag fill_line_p. */
14323
14324 static void
14325 extend_face_to_end_of_line (it)
14326 struct it *it;
14327 {
14328 struct face *face;
14329 struct frame *f = it->f;
14330
14331 /* If line is already filled, do nothing. */
14332 if (it->current_x >= it->last_visible_x)
14333 return;
14334
14335 /* Face extension extends the background and box of IT->face_id
14336 to the end of the line. If the background equals the background
14337 of the frame, we don't have to do anything. */
14338 if (it->face_before_selective_p)
14339 face = FACE_FROM_ID (it->f, it->saved_face_id);
14340 else
14341 face = FACE_FROM_ID (f, it->face_id);
14342
14343 if (FRAME_WINDOW_P (f)
14344 && face->box == FACE_NO_BOX
14345 && face->background == FRAME_BACKGROUND_PIXEL (f)
14346 && !face->stipple)
14347 return;
14348
14349 /* Set the glyph row flag indicating that the face of the last glyph
14350 in the text area has to be drawn to the end of the text area. */
14351 it->glyph_row->fill_line_p = 1;
14352
14353 /* If current character of IT is not ASCII, make sure we have the
14354 ASCII face. This will be automatically undone the next time
14355 get_next_display_element returns a multibyte character. Note
14356 that the character will always be single byte in unibyte text. */
14357 if (!SINGLE_BYTE_CHAR_P (it->c))
14358 {
14359 it->face_id = FACE_FOR_CHAR (f, face, 0);
14360 }
14361
14362 if (FRAME_WINDOW_P (f))
14363 {
14364 /* If the row is empty, add a space with the current face of IT,
14365 so that we know which face to draw. */
14366 if (it->glyph_row->used[TEXT_AREA] == 0)
14367 {
14368 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14369 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14370 it->glyph_row->used[TEXT_AREA] = 1;
14371 }
14372 }
14373 else
14374 {
14375 /* Save some values that must not be changed. */
14376 int saved_x = it->current_x;
14377 struct text_pos saved_pos;
14378 Lisp_Object saved_object;
14379 enum display_element_type saved_what = it->what;
14380 int saved_face_id = it->face_id;
14381
14382 saved_object = it->object;
14383 saved_pos = it->position;
14384
14385 it->what = IT_CHARACTER;
14386 bzero (&it->position, sizeof it->position);
14387 it->object = make_number (0);
14388 it->c = ' ';
14389 it->len = 1;
14390 it->face_id = face->id;
14391
14392 PRODUCE_GLYPHS (it);
14393
14394 while (it->current_x <= it->last_visible_x)
14395 PRODUCE_GLYPHS (it);
14396
14397 /* Don't count these blanks really. It would let us insert a left
14398 truncation glyph below and make us set the cursor on them, maybe. */
14399 it->current_x = saved_x;
14400 it->object = saved_object;
14401 it->position = saved_pos;
14402 it->what = saved_what;
14403 it->face_id = saved_face_id;
14404 }
14405 }
14406
14407
14408 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14409 trailing whitespace. */
14410
14411 static int
14412 trailing_whitespace_p (charpos)
14413 int charpos;
14414 {
14415 int bytepos = CHAR_TO_BYTE (charpos);
14416 int c = 0;
14417
14418 while (bytepos < ZV_BYTE
14419 && (c = FETCH_CHAR (bytepos),
14420 c == ' ' || c == '\t'))
14421 ++bytepos;
14422
14423 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14424 {
14425 if (bytepos != PT_BYTE)
14426 return 1;
14427 }
14428 return 0;
14429 }
14430
14431
14432 /* Highlight trailing whitespace, if any, in ROW. */
14433
14434 void
14435 highlight_trailing_whitespace (f, row)
14436 struct frame *f;
14437 struct glyph_row *row;
14438 {
14439 int used = row->used[TEXT_AREA];
14440
14441 if (used)
14442 {
14443 struct glyph *start = row->glyphs[TEXT_AREA];
14444 struct glyph *glyph = start + used - 1;
14445
14446 /* Skip over glyphs inserted to display the cursor at the
14447 end of a line, for extending the face of the last glyph
14448 to the end of the line on terminals, and for truncation
14449 and continuation glyphs. */
14450 while (glyph >= start
14451 && glyph->type == CHAR_GLYPH
14452 && INTEGERP (glyph->object))
14453 --glyph;
14454
14455 /* If last glyph is a space or stretch, and it's trailing
14456 whitespace, set the face of all trailing whitespace glyphs in
14457 IT->glyph_row to `trailing-whitespace'. */
14458 if (glyph >= start
14459 && BUFFERP (glyph->object)
14460 && (glyph->type == STRETCH_GLYPH
14461 || (glyph->type == CHAR_GLYPH
14462 && glyph->u.ch == ' '))
14463 && trailing_whitespace_p (glyph->charpos))
14464 {
14465 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14466
14467 while (glyph >= start
14468 && BUFFERP (glyph->object)
14469 && (glyph->type == STRETCH_GLYPH
14470 || (glyph->type == CHAR_GLYPH
14471 && glyph->u.ch == ' ')))
14472 (glyph--)->face_id = face_id;
14473 }
14474 }
14475 }
14476
14477
14478 /* Value is non-zero if glyph row ROW in window W should be
14479 used to hold the cursor. */
14480
14481 static int
14482 cursor_row_p (w, row)
14483 struct window *w;
14484 struct glyph_row *row;
14485 {
14486 int cursor_row_p = 1;
14487
14488 if (PT == MATRIX_ROW_END_CHARPOS (row))
14489 {
14490 /* If the row ends with a newline from a string, we don't want
14491 the cursor there (if the row is continued it doesn't end in a
14492 newline). */
14493 if (CHARPOS (row->end.string_pos) >= 0
14494 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14495 cursor_row_p = row->continued_p;
14496
14497 /* If the row ends at ZV, display the cursor at the end of that
14498 row instead of at the start of the row below. */
14499 else if (row->ends_at_zv_p)
14500 cursor_row_p = 1;
14501 else
14502 cursor_row_p = 0;
14503 }
14504
14505 return cursor_row_p;
14506 }
14507
14508
14509 /* Construct the glyph row IT->glyph_row in the desired matrix of
14510 IT->w from text at the current position of IT. See dispextern.h
14511 for an overview of struct it. Value is non-zero if
14512 IT->glyph_row displays text, as opposed to a line displaying ZV
14513 only. */
14514
14515 static int
14516 display_line (it)
14517 struct it *it;
14518 {
14519 struct glyph_row *row = it->glyph_row;
14520 int overlay_arrow_bitmap;
14521 Lisp_Object overlay_arrow_string;
14522
14523 /* We always start displaying at hpos zero even if hscrolled. */
14524 xassert (it->hpos == 0 && it->current_x == 0);
14525
14526 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14527 >= it->w->desired_matrix->nrows)
14528 {
14529 it->w->nrows_scale_factor++;
14530 fonts_changed_p = 1;
14531 return 0;
14532 }
14533
14534 /* Is IT->w showing the region? */
14535 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14536
14537 /* Clear the result glyph row and enable it. */
14538 prepare_desired_row (row);
14539
14540 row->y = it->current_y;
14541 row->start = it->start;
14542 row->continuation_lines_width = it->continuation_lines_width;
14543 row->displays_text_p = 1;
14544 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14545 it->starts_in_middle_of_char_p = 0;
14546
14547 /* Arrange the overlays nicely for our purposes. Usually, we call
14548 display_line on only one line at a time, in which case this
14549 can't really hurt too much, or we call it on lines which appear
14550 one after another in the buffer, in which case all calls to
14551 recenter_overlay_lists but the first will be pretty cheap. */
14552 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14553
14554 /* Move over display elements that are not visible because we are
14555 hscrolled. This may stop at an x-position < IT->first_visible_x
14556 if the first glyph is partially visible or if we hit a line end. */
14557 if (it->current_x < it->first_visible_x)
14558 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14559 MOVE_TO_POS | MOVE_TO_X);
14560
14561 /* Get the initial row height. This is either the height of the
14562 text hscrolled, if there is any, or zero. */
14563 row->ascent = it->max_ascent;
14564 row->height = it->max_ascent + it->max_descent;
14565 row->phys_ascent = it->max_phys_ascent;
14566 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14567
14568 /* Loop generating characters. The loop is left with IT on the next
14569 character to display. */
14570 while (1)
14571 {
14572 int n_glyphs_before, hpos_before, x_before;
14573 int x, i, nglyphs;
14574 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14575
14576 /* Retrieve the next thing to display. Value is zero if end of
14577 buffer reached. */
14578 if (!get_next_display_element (it))
14579 {
14580 /* Maybe add a space at the end of this line that is used to
14581 display the cursor there under X. Set the charpos of the
14582 first glyph of blank lines not corresponding to any text
14583 to -1. */
14584 #ifdef HAVE_WINDOW_SYSTEM
14585 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14586 row->exact_window_width_line_p = 1;
14587 else
14588 #endif /* HAVE_WINDOW_SYSTEM */
14589 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14590 || row->used[TEXT_AREA] == 0)
14591 {
14592 row->glyphs[TEXT_AREA]->charpos = -1;
14593 row->displays_text_p = 0;
14594
14595 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14596 && (!MINI_WINDOW_P (it->w)
14597 || (minibuf_level && EQ (it->window, minibuf_window))))
14598 row->indicate_empty_line_p = 1;
14599 }
14600
14601 it->continuation_lines_width = 0;
14602 row->ends_at_zv_p = 1;
14603 break;
14604 }
14605
14606 /* Now, get the metrics of what we want to display. This also
14607 generates glyphs in `row' (which is IT->glyph_row). */
14608 n_glyphs_before = row->used[TEXT_AREA];
14609 x = it->current_x;
14610
14611 /* Remember the line height so far in case the next element doesn't
14612 fit on the line. */
14613 if (!it->truncate_lines_p)
14614 {
14615 ascent = it->max_ascent;
14616 descent = it->max_descent;
14617 phys_ascent = it->max_phys_ascent;
14618 phys_descent = it->max_phys_descent;
14619 }
14620
14621 PRODUCE_GLYPHS (it);
14622
14623 /* If this display element was in marginal areas, continue with
14624 the next one. */
14625 if (it->area != TEXT_AREA)
14626 {
14627 row->ascent = max (row->ascent, it->max_ascent);
14628 row->height = max (row->height, it->max_ascent + it->max_descent);
14629 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14630 row->phys_height = max (row->phys_height,
14631 it->max_phys_ascent + it->max_phys_descent);
14632 set_iterator_to_next (it, 1);
14633 continue;
14634 }
14635
14636 /* Does the display element fit on the line? If we truncate
14637 lines, we should draw past the right edge of the window. If
14638 we don't truncate, we want to stop so that we can display the
14639 continuation glyph before the right margin. If lines are
14640 continued, there are two possible strategies for characters
14641 resulting in more than 1 glyph (e.g. tabs): Display as many
14642 glyphs as possible in this line and leave the rest for the
14643 continuation line, or display the whole element in the next
14644 line. Original redisplay did the former, so we do it also. */
14645 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14646 hpos_before = it->hpos;
14647 x_before = x;
14648
14649 if (/* Not a newline. */
14650 nglyphs > 0
14651 /* Glyphs produced fit entirely in the line. */
14652 && it->current_x < it->last_visible_x)
14653 {
14654 it->hpos += nglyphs;
14655 row->ascent = max (row->ascent, it->max_ascent);
14656 row->height = max (row->height, it->max_ascent + it->max_descent);
14657 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14658 row->phys_height = max (row->phys_height,
14659 it->max_phys_ascent + it->max_phys_descent);
14660 if (it->current_x - it->pixel_width < it->first_visible_x)
14661 row->x = x - it->first_visible_x;
14662 }
14663 else
14664 {
14665 int new_x;
14666 struct glyph *glyph;
14667
14668 for (i = 0; i < nglyphs; ++i, x = new_x)
14669 {
14670 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14671 new_x = x + glyph->pixel_width;
14672
14673 if (/* Lines are continued. */
14674 !it->truncate_lines_p
14675 && (/* Glyph doesn't fit on the line. */
14676 new_x > it->last_visible_x
14677 /* Or it fits exactly on a window system frame. */
14678 || (new_x == it->last_visible_x
14679 && FRAME_WINDOW_P (it->f))))
14680 {
14681 /* End of a continued line. */
14682
14683 if (it->hpos == 0
14684 || (new_x == it->last_visible_x
14685 && FRAME_WINDOW_P (it->f)))
14686 {
14687 /* Current glyph is the only one on the line or
14688 fits exactly on the line. We must continue
14689 the line because we can't draw the cursor
14690 after the glyph. */
14691 row->continued_p = 1;
14692 it->current_x = new_x;
14693 it->continuation_lines_width += new_x;
14694 ++it->hpos;
14695 if (i == nglyphs - 1)
14696 {
14697 set_iterator_to_next (it, 1);
14698 #ifdef HAVE_WINDOW_SYSTEM
14699 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14700 {
14701 if (!get_next_display_element (it))
14702 {
14703 row->exact_window_width_line_p = 1;
14704 it->continuation_lines_width = 0;
14705 row->continued_p = 0;
14706 row->ends_at_zv_p = 1;
14707 }
14708 else if (ITERATOR_AT_END_OF_LINE_P (it))
14709 {
14710 row->continued_p = 0;
14711 row->exact_window_width_line_p = 1;
14712 }
14713 }
14714 #endif /* HAVE_WINDOW_SYSTEM */
14715 }
14716 }
14717 else if (CHAR_GLYPH_PADDING_P (*glyph)
14718 && !FRAME_WINDOW_P (it->f))
14719 {
14720 /* A padding glyph that doesn't fit on this line.
14721 This means the whole character doesn't fit
14722 on the line. */
14723 row->used[TEXT_AREA] = n_glyphs_before;
14724
14725 /* Fill the rest of the row with continuation
14726 glyphs like in 20.x. */
14727 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14728 < row->glyphs[1 + TEXT_AREA])
14729 produce_special_glyphs (it, IT_CONTINUATION);
14730
14731 row->continued_p = 1;
14732 it->current_x = x_before;
14733 it->continuation_lines_width += x_before;
14734
14735 /* Restore the height to what it was before the
14736 element not fitting on the line. */
14737 it->max_ascent = ascent;
14738 it->max_descent = descent;
14739 it->max_phys_ascent = phys_ascent;
14740 it->max_phys_descent = phys_descent;
14741 }
14742 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14743 {
14744 /* A TAB that extends past the right edge of the
14745 window. This produces a single glyph on
14746 window system frames. We leave the glyph in
14747 this row and let it fill the row, but don't
14748 consume the TAB. */
14749 it->continuation_lines_width += it->last_visible_x;
14750 row->ends_in_middle_of_char_p = 1;
14751 row->continued_p = 1;
14752 glyph->pixel_width = it->last_visible_x - x;
14753 it->starts_in_middle_of_char_p = 1;
14754 }
14755 else
14756 {
14757 /* Something other than a TAB that draws past
14758 the right edge of the window. Restore
14759 positions to values before the element. */
14760 row->used[TEXT_AREA] = n_glyphs_before + i;
14761
14762 /* Display continuation glyphs. */
14763 if (!FRAME_WINDOW_P (it->f))
14764 produce_special_glyphs (it, IT_CONTINUATION);
14765 row->continued_p = 1;
14766
14767 it->continuation_lines_width += x;
14768
14769 if (nglyphs > 1 && i > 0)
14770 {
14771 row->ends_in_middle_of_char_p = 1;
14772 it->starts_in_middle_of_char_p = 1;
14773 }
14774
14775 /* Restore the height to what it was before the
14776 element not fitting on the line. */
14777 it->max_ascent = ascent;
14778 it->max_descent = descent;
14779 it->max_phys_ascent = phys_ascent;
14780 it->max_phys_descent = phys_descent;
14781 }
14782
14783 break;
14784 }
14785 else if (new_x > it->first_visible_x)
14786 {
14787 /* Increment number of glyphs actually displayed. */
14788 ++it->hpos;
14789
14790 if (x < it->first_visible_x)
14791 /* Glyph is partially visible, i.e. row starts at
14792 negative X position. */
14793 row->x = x - it->first_visible_x;
14794 }
14795 else
14796 {
14797 /* Glyph is completely off the left margin of the
14798 window. This should not happen because of the
14799 move_it_in_display_line at the start of this
14800 function, unless the text display area of the
14801 window is empty. */
14802 xassert (it->first_visible_x <= it->last_visible_x);
14803 }
14804 }
14805
14806 row->ascent = max (row->ascent, it->max_ascent);
14807 row->height = max (row->height, it->max_ascent + it->max_descent);
14808 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14809 row->phys_height = max (row->phys_height,
14810 it->max_phys_ascent + it->max_phys_descent);
14811
14812 /* End of this display line if row is continued. */
14813 if (row->continued_p || row->ends_at_zv_p)
14814 break;
14815 }
14816
14817 at_end_of_line:
14818 /* Is this a line end? If yes, we're also done, after making
14819 sure that a non-default face is extended up to the right
14820 margin of the window. */
14821 if (ITERATOR_AT_END_OF_LINE_P (it))
14822 {
14823 int used_before = row->used[TEXT_AREA];
14824
14825 row->ends_in_newline_from_string_p = STRINGP (it->object);
14826
14827 #ifdef HAVE_WINDOW_SYSTEM
14828 /* Add a space at the end of the line that is used to
14829 display the cursor there. */
14830 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14831 append_space_for_newline (it, 0);
14832 #endif /* HAVE_WINDOW_SYSTEM */
14833
14834 /* Extend the face to the end of the line. */
14835 extend_face_to_end_of_line (it);
14836
14837 /* Make sure we have the position. */
14838 if (used_before == 0)
14839 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14840
14841 /* Consume the line end. This skips over invisible lines. */
14842 set_iterator_to_next (it, 1);
14843 it->continuation_lines_width = 0;
14844 break;
14845 }
14846
14847 /* Proceed with next display element. Note that this skips
14848 over lines invisible because of selective display. */
14849 set_iterator_to_next (it, 1);
14850
14851 /* If we truncate lines, we are done when the last displayed
14852 glyphs reach past the right margin of the window. */
14853 if (it->truncate_lines_p
14854 && (FRAME_WINDOW_P (it->f)
14855 ? (it->current_x >= it->last_visible_x)
14856 : (it->current_x > it->last_visible_x)))
14857 {
14858 /* Maybe add truncation glyphs. */
14859 if (!FRAME_WINDOW_P (it->f))
14860 {
14861 int i, n;
14862
14863 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14864 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14865 break;
14866
14867 for (n = row->used[TEXT_AREA]; i < n; ++i)
14868 {
14869 row->used[TEXT_AREA] = i;
14870 produce_special_glyphs (it, IT_TRUNCATION);
14871 }
14872 }
14873 #ifdef HAVE_WINDOW_SYSTEM
14874 else
14875 {
14876 /* Don't truncate if we can overflow newline into fringe. */
14877 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14878 {
14879 if (!get_next_display_element (it))
14880 {
14881 #ifdef HAVE_WINDOW_SYSTEM
14882 it->continuation_lines_width = 0;
14883 row->ends_at_zv_p = 1;
14884 row->exact_window_width_line_p = 1;
14885 break;
14886 #endif /* HAVE_WINDOW_SYSTEM */
14887 }
14888 if (ITERATOR_AT_END_OF_LINE_P (it))
14889 {
14890 row->exact_window_width_line_p = 1;
14891 goto at_end_of_line;
14892 }
14893 }
14894 }
14895 #endif /* HAVE_WINDOW_SYSTEM */
14896
14897 row->truncated_on_right_p = 1;
14898 it->continuation_lines_width = 0;
14899 reseat_at_next_visible_line_start (it, 0);
14900 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14901 it->hpos = hpos_before;
14902 it->current_x = x_before;
14903 break;
14904 }
14905 }
14906
14907 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14908 at the left window margin. */
14909 if (it->first_visible_x
14910 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14911 {
14912 if (!FRAME_WINDOW_P (it->f))
14913 insert_left_trunc_glyphs (it);
14914 row->truncated_on_left_p = 1;
14915 }
14916
14917 /* If the start of this line is the overlay arrow-position, then
14918 mark this glyph row as the one containing the overlay arrow.
14919 This is clearly a mess with variable size fonts. It would be
14920 better to let it be displayed like cursors under X. */
14921 if (! overlay_arrow_seen
14922 && (overlay_arrow_string
14923 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14924 !NILP (overlay_arrow_string)))
14925 {
14926 /* Overlay arrow in window redisplay is a fringe bitmap. */
14927 if (!FRAME_WINDOW_P (it->f))
14928 {
14929 struct glyph_row *arrow_row
14930 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14931 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14932 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14933 struct glyph *p = row->glyphs[TEXT_AREA];
14934 struct glyph *p2, *end;
14935
14936 /* Copy the arrow glyphs. */
14937 while (glyph < arrow_end)
14938 *p++ = *glyph++;
14939
14940 /* Throw away padding glyphs. */
14941 p2 = p;
14942 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14943 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14944 ++p2;
14945 if (p2 > p)
14946 {
14947 while (p2 < end)
14948 *p++ = *p2++;
14949 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14950 }
14951 }
14952
14953 overlay_arrow_seen = 1;
14954 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14955 row->overlay_arrow_p = 1;
14956 }
14957
14958 /* Compute pixel dimensions of this line. */
14959 compute_line_metrics (it);
14960
14961 /* Remember the position at which this line ends. */
14962 row->end = it->current;
14963
14964 /* Save fringe bitmaps in this row. */
14965 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14966 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14967 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14968 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14969
14970 it->left_user_fringe_bitmap = 0;
14971 it->left_user_fringe_face_id = 0;
14972 it->right_user_fringe_bitmap = 0;
14973 it->right_user_fringe_face_id = 0;
14974
14975 /* Maybe set the cursor. */
14976 if (it->w->cursor.vpos < 0
14977 && PT >= MATRIX_ROW_START_CHARPOS (row)
14978 && PT <= MATRIX_ROW_END_CHARPOS (row)
14979 && cursor_row_p (it->w, row))
14980 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14981
14982 /* Highlight trailing whitespace. */
14983 if (!NILP (Vshow_trailing_whitespace))
14984 highlight_trailing_whitespace (it->f, it->glyph_row);
14985
14986 /* Prepare for the next line. This line starts horizontally at (X
14987 HPOS) = (0 0). Vertical positions are incremented. As a
14988 convenience for the caller, IT->glyph_row is set to the next
14989 row to be used. */
14990 it->current_x = it->hpos = 0;
14991 it->current_y += row->height;
14992 ++it->vpos;
14993 ++it->glyph_row;
14994 it->start = it->current;
14995 return row->displays_text_p;
14996 }
14997
14998
14999 \f
15000 /***********************************************************************
15001 Menu Bar
15002 ***********************************************************************/
15003
15004 /* Redisplay the menu bar in the frame for window W.
15005
15006 The menu bar of X frames that don't have X toolkit support is
15007 displayed in a special window W->frame->menu_bar_window.
15008
15009 The menu bar of terminal frames is treated specially as far as
15010 glyph matrices are concerned. Menu bar lines are not part of
15011 windows, so the update is done directly on the frame matrix rows
15012 for the menu bar. */
15013
15014 static void
15015 display_menu_bar (w)
15016 struct window *w;
15017 {
15018 struct frame *f = XFRAME (WINDOW_FRAME (w));
15019 struct it it;
15020 Lisp_Object items;
15021 int i;
15022
15023 /* Don't do all this for graphical frames. */
15024 #ifdef HAVE_NTGUI
15025 if (!NILP (Vwindow_system))
15026 return;
15027 #endif
15028 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15029 if (FRAME_X_P (f))
15030 return;
15031 #endif
15032 #ifdef MAC_OS
15033 if (FRAME_MAC_P (f))
15034 return;
15035 #endif
15036
15037 #ifdef USE_X_TOOLKIT
15038 xassert (!FRAME_WINDOW_P (f));
15039 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15040 it.first_visible_x = 0;
15041 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15042 #else /* not USE_X_TOOLKIT */
15043 if (FRAME_WINDOW_P (f))
15044 {
15045 /* Menu bar lines are displayed in the desired matrix of the
15046 dummy window menu_bar_window. */
15047 struct window *menu_w;
15048 xassert (WINDOWP (f->menu_bar_window));
15049 menu_w = XWINDOW (f->menu_bar_window);
15050 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15051 MENU_FACE_ID);
15052 it.first_visible_x = 0;
15053 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15054 }
15055 else
15056 {
15057 /* This is a TTY frame, i.e. character hpos/vpos are used as
15058 pixel x/y. */
15059 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15060 MENU_FACE_ID);
15061 it.first_visible_x = 0;
15062 it.last_visible_x = FRAME_COLS (f);
15063 }
15064 #endif /* not USE_X_TOOLKIT */
15065
15066 if (! mode_line_inverse_video)
15067 /* Force the menu-bar to be displayed in the default face. */
15068 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15069
15070 /* Clear all rows of the menu bar. */
15071 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15072 {
15073 struct glyph_row *row = it.glyph_row + i;
15074 clear_glyph_row (row);
15075 row->enabled_p = 1;
15076 row->full_width_p = 1;
15077 }
15078
15079 /* Display all items of the menu bar. */
15080 items = FRAME_MENU_BAR_ITEMS (it.f);
15081 for (i = 0; i < XVECTOR (items)->size; i += 4)
15082 {
15083 Lisp_Object string;
15084
15085 /* Stop at nil string. */
15086 string = AREF (items, i + 1);
15087 if (NILP (string))
15088 break;
15089
15090 /* Remember where item was displayed. */
15091 AREF (items, i + 3) = make_number (it.hpos);
15092
15093 /* Display the item, pad with one space. */
15094 if (it.current_x < it.last_visible_x)
15095 display_string (NULL, string, Qnil, 0, 0, &it,
15096 SCHARS (string) + 1, 0, 0, -1);
15097 }
15098
15099 /* Fill out the line with spaces. */
15100 if (it.current_x < it.last_visible_x)
15101 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15102
15103 /* Compute the total height of the lines. */
15104 compute_line_metrics (&it);
15105 }
15106
15107
15108 \f
15109 /***********************************************************************
15110 Mode Line
15111 ***********************************************************************/
15112
15113 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15114 FORCE is non-zero, redisplay mode lines unconditionally.
15115 Otherwise, redisplay only mode lines that are garbaged. Value is
15116 the number of windows whose mode lines were redisplayed. */
15117
15118 static int
15119 redisplay_mode_lines (window, force)
15120 Lisp_Object window;
15121 int force;
15122 {
15123 int nwindows = 0;
15124
15125 while (!NILP (window))
15126 {
15127 struct window *w = XWINDOW (window);
15128
15129 if (WINDOWP (w->hchild))
15130 nwindows += redisplay_mode_lines (w->hchild, force);
15131 else if (WINDOWP (w->vchild))
15132 nwindows += redisplay_mode_lines (w->vchild, force);
15133 else if (force
15134 || FRAME_GARBAGED_P (XFRAME (w->frame))
15135 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15136 {
15137 struct text_pos lpoint;
15138 struct buffer *old = current_buffer;
15139
15140 /* Set the window's buffer for the mode line display. */
15141 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15142 set_buffer_internal_1 (XBUFFER (w->buffer));
15143
15144 /* Point refers normally to the selected window. For any
15145 other window, set up appropriate value. */
15146 if (!EQ (window, selected_window))
15147 {
15148 struct text_pos pt;
15149
15150 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15151 if (CHARPOS (pt) < BEGV)
15152 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15153 else if (CHARPOS (pt) > (ZV - 1))
15154 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15155 else
15156 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15157 }
15158
15159 /* Display mode lines. */
15160 clear_glyph_matrix (w->desired_matrix);
15161 if (display_mode_lines (w))
15162 {
15163 ++nwindows;
15164 w->must_be_updated_p = 1;
15165 }
15166
15167 /* Restore old settings. */
15168 set_buffer_internal_1 (old);
15169 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15170 }
15171
15172 window = w->next;
15173 }
15174
15175 return nwindows;
15176 }
15177
15178
15179 /* Display the mode and/or top line of window W. Value is the number
15180 of mode lines displayed. */
15181
15182 static int
15183 display_mode_lines (w)
15184 struct window *w;
15185 {
15186 Lisp_Object old_selected_window, old_selected_frame;
15187 int n = 0;
15188
15189 old_selected_frame = selected_frame;
15190 selected_frame = w->frame;
15191 old_selected_window = selected_window;
15192 XSETWINDOW (selected_window, w);
15193
15194 /* These will be set while the mode line specs are processed. */
15195 line_number_displayed = 0;
15196 w->column_number_displayed = Qnil;
15197
15198 if (WINDOW_WANTS_MODELINE_P (w))
15199 {
15200 struct window *sel_w = XWINDOW (old_selected_window);
15201
15202 /* Select mode line face based on the real selected window. */
15203 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15204 current_buffer->mode_line_format);
15205 ++n;
15206 }
15207
15208 if (WINDOW_WANTS_HEADER_LINE_P (w))
15209 {
15210 display_mode_line (w, HEADER_LINE_FACE_ID,
15211 current_buffer->header_line_format);
15212 ++n;
15213 }
15214
15215 selected_frame = old_selected_frame;
15216 selected_window = old_selected_window;
15217 return n;
15218 }
15219
15220
15221 /* Display mode or top line of window W. FACE_ID specifies which line
15222 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15223 FORMAT is the mode line format to display. Value is the pixel
15224 height of the mode line displayed. */
15225
15226 static int
15227 display_mode_line (w, face_id, format)
15228 struct window *w;
15229 enum face_id face_id;
15230 Lisp_Object format;
15231 {
15232 struct it it;
15233 struct face *face;
15234
15235 init_iterator (&it, w, -1, -1, NULL, face_id);
15236 prepare_desired_row (it.glyph_row);
15237
15238 it.glyph_row->mode_line_p = 1;
15239
15240 if (! mode_line_inverse_video)
15241 /* Force the mode-line to be displayed in the default face. */
15242 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15243
15244 /* Temporarily make frame's keyboard the current kboard so that
15245 kboard-local variables in the mode_line_format will get the right
15246 values. */
15247 push_frame_kboard (it.f);
15248 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15249 pop_frame_kboard ();
15250
15251 /* Fill up with spaces. */
15252 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15253
15254 compute_line_metrics (&it);
15255 it.glyph_row->full_width_p = 1;
15256 it.glyph_row->continued_p = 0;
15257 it.glyph_row->truncated_on_left_p = 0;
15258 it.glyph_row->truncated_on_right_p = 0;
15259
15260 /* Make a 3D mode-line have a shadow at its right end. */
15261 face = FACE_FROM_ID (it.f, face_id);
15262 extend_face_to_end_of_line (&it);
15263 if (face->box != FACE_NO_BOX)
15264 {
15265 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15266 + it.glyph_row->used[TEXT_AREA] - 1);
15267 last->right_box_line_p = 1;
15268 }
15269
15270 return it.glyph_row->height;
15271 }
15272
15273 /* Alist that caches the results of :propertize.
15274 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15275 Lisp_Object mode_line_proptrans_alist;
15276
15277 /* List of strings making up the mode-line. */
15278 Lisp_Object mode_line_string_list;
15279
15280 /* Base face property when building propertized mode line string. */
15281 static Lisp_Object mode_line_string_face;
15282 static Lisp_Object mode_line_string_face_prop;
15283
15284
15285 /* Contribute ELT to the mode line for window IT->w. How it
15286 translates into text depends on its data type.
15287
15288 IT describes the display environment in which we display, as usual.
15289
15290 DEPTH is the depth in recursion. It is used to prevent
15291 infinite recursion here.
15292
15293 FIELD_WIDTH is the number of characters the display of ELT should
15294 occupy in the mode line, and PRECISION is the maximum number of
15295 characters to display from ELT's representation. See
15296 display_string for details.
15297
15298 Returns the hpos of the end of the text generated by ELT.
15299
15300 PROPS is a property list to add to any string we encounter.
15301
15302 If RISKY is nonzero, remove (disregard) any properties in any string
15303 we encounter, and ignore :eval and :propertize.
15304
15305 If the global variable `frame_title_ptr' is non-NULL, then the output
15306 is passed to `store_frame_title' instead of `display_string'. */
15307
15308 static int
15309 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15310 struct it *it;
15311 int depth;
15312 int field_width, precision;
15313 Lisp_Object elt, props;
15314 int risky;
15315 {
15316 int n = 0, field, prec;
15317 int literal = 0;
15318
15319 tail_recurse:
15320 if (depth > 100)
15321 elt = build_string ("*too-deep*");
15322
15323 depth++;
15324
15325 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15326 {
15327 case Lisp_String:
15328 {
15329 /* A string: output it and check for %-constructs within it. */
15330 unsigned char c;
15331 const unsigned char *this, *lisp_string;
15332
15333 if (!NILP (props) || risky)
15334 {
15335 Lisp_Object oprops, aelt;
15336 oprops = Ftext_properties_at (make_number (0), elt);
15337
15338 if (NILP (Fequal (props, oprops)) || risky)
15339 {
15340 /* If the starting string has properties,
15341 merge the specified ones onto the existing ones. */
15342 if (! NILP (oprops) && !risky)
15343 {
15344 Lisp_Object tem;
15345
15346 oprops = Fcopy_sequence (oprops);
15347 tem = props;
15348 while (CONSP (tem))
15349 {
15350 oprops = Fplist_put (oprops, XCAR (tem),
15351 XCAR (XCDR (tem)));
15352 tem = XCDR (XCDR (tem));
15353 }
15354 props = oprops;
15355 }
15356
15357 aelt = Fassoc (elt, mode_line_proptrans_alist);
15358 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15359 {
15360 mode_line_proptrans_alist
15361 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15362 elt = XCAR (aelt);
15363 }
15364 else
15365 {
15366 Lisp_Object tem;
15367
15368 elt = Fcopy_sequence (elt);
15369 Fset_text_properties (make_number (0), Flength (elt),
15370 props, elt);
15371 /* Add this item to mode_line_proptrans_alist. */
15372 mode_line_proptrans_alist
15373 = Fcons (Fcons (elt, props),
15374 mode_line_proptrans_alist);
15375 /* Truncate mode_line_proptrans_alist
15376 to at most 50 elements. */
15377 tem = Fnthcdr (make_number (50),
15378 mode_line_proptrans_alist);
15379 if (! NILP (tem))
15380 XSETCDR (tem, Qnil);
15381 }
15382 }
15383 }
15384
15385 this = SDATA (elt);
15386 lisp_string = this;
15387
15388 if (literal)
15389 {
15390 prec = precision - n;
15391 if (frame_title_ptr)
15392 n += store_frame_title (SDATA (elt), -1, prec);
15393 else if (!NILP (mode_line_string_list))
15394 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15395 else
15396 n += display_string (NULL, elt, Qnil, 0, 0, it,
15397 0, prec, 0, STRING_MULTIBYTE (elt));
15398
15399 break;
15400 }
15401
15402 while ((precision <= 0 || n < precision)
15403 && *this
15404 && (frame_title_ptr
15405 || !NILP (mode_line_string_list)
15406 || it->current_x < it->last_visible_x))
15407 {
15408 const unsigned char *last = this;
15409
15410 /* Advance to end of string or next format specifier. */
15411 while ((c = *this++) != '\0' && c != '%')
15412 ;
15413
15414 if (this - 1 != last)
15415 {
15416 /* Output to end of string or up to '%'. Field width
15417 is length of string. Don't output more than
15418 PRECISION allows us. */
15419 --this;
15420
15421 prec = chars_in_text (last, this - last);
15422 if (precision > 0 && prec > precision - n)
15423 prec = precision - n;
15424
15425 if (frame_title_ptr)
15426 n += store_frame_title (last, 0, prec);
15427 else if (!NILP (mode_line_string_list))
15428 {
15429 int bytepos = last - lisp_string;
15430 int charpos = string_byte_to_char (elt, bytepos);
15431 n += store_mode_line_string (NULL,
15432 Fsubstring (elt, make_number (charpos),
15433 make_number (charpos + prec)),
15434 0, 0, 0, Qnil);
15435 }
15436 else
15437 {
15438 int bytepos = last - lisp_string;
15439 int charpos = string_byte_to_char (elt, bytepos);
15440 n += display_string (NULL, elt, Qnil, 0, charpos,
15441 it, 0, prec, 0,
15442 STRING_MULTIBYTE (elt));
15443 }
15444 }
15445 else /* c == '%' */
15446 {
15447 const unsigned char *percent_position = this;
15448
15449 /* Get the specified minimum width. Zero means
15450 don't pad. */
15451 field = 0;
15452 while ((c = *this++) >= '0' && c <= '9')
15453 field = field * 10 + c - '0';
15454
15455 /* Don't pad beyond the total padding allowed. */
15456 if (field_width - n > 0 && field > field_width - n)
15457 field = field_width - n;
15458
15459 /* Note that either PRECISION <= 0 or N < PRECISION. */
15460 prec = precision - n;
15461
15462 if (c == 'M')
15463 n += display_mode_element (it, depth, field, prec,
15464 Vglobal_mode_string, props,
15465 risky);
15466 else if (c != 0)
15467 {
15468 int multibyte;
15469 int bytepos, charpos;
15470 unsigned char *spec;
15471
15472 bytepos = percent_position - lisp_string;
15473 charpos = (STRING_MULTIBYTE (elt)
15474 ? string_byte_to_char (elt, bytepos)
15475 : bytepos);
15476
15477 spec
15478 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15479
15480 if (frame_title_ptr)
15481 n += store_frame_title (spec, field, prec);
15482 else if (!NILP (mode_line_string_list))
15483 {
15484 int len = strlen (spec);
15485 Lisp_Object tem = make_string (spec, len);
15486 props = Ftext_properties_at (make_number (charpos), elt);
15487 /* Should only keep face property in props */
15488 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15489 }
15490 else
15491 {
15492 int nglyphs_before, nwritten;
15493
15494 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15495 nwritten = display_string (spec, Qnil, elt,
15496 charpos, 0, it,
15497 field, prec, 0,
15498 multibyte);
15499
15500 /* Assign to the glyphs written above the
15501 string where the `%x' came from, position
15502 of the `%'. */
15503 if (nwritten > 0)
15504 {
15505 struct glyph *glyph
15506 = (it->glyph_row->glyphs[TEXT_AREA]
15507 + nglyphs_before);
15508 int i;
15509
15510 for (i = 0; i < nwritten; ++i)
15511 {
15512 glyph[i].object = elt;
15513 glyph[i].charpos = charpos;
15514 }
15515
15516 n += nwritten;
15517 }
15518 }
15519 }
15520 else /* c == 0 */
15521 break;
15522 }
15523 }
15524 }
15525 break;
15526
15527 case Lisp_Symbol:
15528 /* A symbol: process the value of the symbol recursively
15529 as if it appeared here directly. Avoid error if symbol void.
15530 Special case: if value of symbol is a string, output the string
15531 literally. */
15532 {
15533 register Lisp_Object tem;
15534
15535 /* If the variable is not marked as risky to set
15536 then its contents are risky to use. */
15537 if (NILP (Fget (elt, Qrisky_local_variable)))
15538 risky = 1;
15539
15540 tem = Fboundp (elt);
15541 if (!NILP (tem))
15542 {
15543 tem = Fsymbol_value (elt);
15544 /* If value is a string, output that string literally:
15545 don't check for % within it. */
15546 if (STRINGP (tem))
15547 literal = 1;
15548
15549 if (!EQ (tem, elt))
15550 {
15551 /* Give up right away for nil or t. */
15552 elt = tem;
15553 goto tail_recurse;
15554 }
15555 }
15556 }
15557 break;
15558
15559 case Lisp_Cons:
15560 {
15561 register Lisp_Object car, tem;
15562
15563 /* A cons cell: five distinct cases.
15564 If first element is :eval or :propertize, do something special.
15565 If first element is a string or a cons, process all the elements
15566 and effectively concatenate them.
15567 If first element is a negative number, truncate displaying cdr to
15568 at most that many characters. If positive, pad (with spaces)
15569 to at least that many characters.
15570 If first element is a symbol, process the cadr or caddr recursively
15571 according to whether the symbol's value is non-nil or nil. */
15572 car = XCAR (elt);
15573 if (EQ (car, QCeval))
15574 {
15575 /* An element of the form (:eval FORM) means evaluate FORM
15576 and use the result as mode line elements. */
15577
15578 if (risky)
15579 break;
15580
15581 if (CONSP (XCDR (elt)))
15582 {
15583 Lisp_Object spec;
15584 spec = safe_eval (XCAR (XCDR (elt)));
15585 n += display_mode_element (it, depth, field_width - n,
15586 precision - n, spec, props,
15587 risky);
15588 }
15589 }
15590 else if (EQ (car, QCpropertize))
15591 {
15592 /* An element of the form (:propertize ELT PROPS...)
15593 means display ELT but applying properties PROPS. */
15594
15595 if (risky)
15596 break;
15597
15598 if (CONSP (XCDR (elt)))
15599 n += display_mode_element (it, depth, field_width - n,
15600 precision - n, XCAR (XCDR (elt)),
15601 XCDR (XCDR (elt)), risky);
15602 }
15603 else if (SYMBOLP (car))
15604 {
15605 tem = Fboundp (car);
15606 elt = XCDR (elt);
15607 if (!CONSP (elt))
15608 goto invalid;
15609 /* elt is now the cdr, and we know it is a cons cell.
15610 Use its car if CAR has a non-nil value. */
15611 if (!NILP (tem))
15612 {
15613 tem = Fsymbol_value (car);
15614 if (!NILP (tem))
15615 {
15616 elt = XCAR (elt);
15617 goto tail_recurse;
15618 }
15619 }
15620 /* Symbol's value is nil (or symbol is unbound)
15621 Get the cddr of the original list
15622 and if possible find the caddr and use that. */
15623 elt = XCDR (elt);
15624 if (NILP (elt))
15625 break;
15626 else if (!CONSP (elt))
15627 goto invalid;
15628 elt = XCAR (elt);
15629 goto tail_recurse;
15630 }
15631 else if (INTEGERP (car))
15632 {
15633 register int lim = XINT (car);
15634 elt = XCDR (elt);
15635 if (lim < 0)
15636 {
15637 /* Negative int means reduce maximum width. */
15638 if (precision <= 0)
15639 precision = -lim;
15640 else
15641 precision = min (precision, -lim);
15642 }
15643 else if (lim > 0)
15644 {
15645 /* Padding specified. Don't let it be more than
15646 current maximum. */
15647 if (precision > 0)
15648 lim = min (precision, lim);
15649
15650 /* If that's more padding than already wanted, queue it.
15651 But don't reduce padding already specified even if
15652 that is beyond the current truncation point. */
15653 field_width = max (lim, field_width);
15654 }
15655 goto tail_recurse;
15656 }
15657 else if (STRINGP (car) || CONSP (car))
15658 {
15659 register int limit = 50;
15660 /* Limit is to protect against circular lists. */
15661 while (CONSP (elt)
15662 && --limit > 0
15663 && (precision <= 0 || n < precision))
15664 {
15665 n += display_mode_element (it, depth, field_width - n,
15666 precision - n, XCAR (elt),
15667 props, risky);
15668 elt = XCDR (elt);
15669 }
15670 }
15671 }
15672 break;
15673
15674 default:
15675 invalid:
15676 elt = build_string ("*invalid*");
15677 goto tail_recurse;
15678 }
15679
15680 /* Pad to FIELD_WIDTH. */
15681 if (field_width > 0 && n < field_width)
15682 {
15683 if (frame_title_ptr)
15684 n += store_frame_title ("", field_width - n, 0);
15685 else if (!NILP (mode_line_string_list))
15686 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15687 else
15688 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15689 0, 0, 0);
15690 }
15691
15692 return n;
15693 }
15694
15695 /* Store a mode-line string element in mode_line_string_list.
15696
15697 If STRING is non-null, display that C string. Otherwise, the Lisp
15698 string LISP_STRING is displayed.
15699
15700 FIELD_WIDTH is the minimum number of output glyphs to produce.
15701 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15702 with spaces. FIELD_WIDTH <= 0 means don't pad.
15703
15704 PRECISION is the maximum number of characters to output from
15705 STRING. PRECISION <= 0 means don't truncate the string.
15706
15707 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15708 properties to the string.
15709
15710 PROPS are the properties to add to the string.
15711 The mode_line_string_face face property is always added to the string.
15712 */
15713
15714 static int
15715 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15716 char *string;
15717 Lisp_Object lisp_string;
15718 int copy_string;
15719 int field_width;
15720 int precision;
15721 Lisp_Object props;
15722 {
15723 int len;
15724 int n = 0;
15725
15726 if (string != NULL)
15727 {
15728 len = strlen (string);
15729 if (precision > 0 && len > precision)
15730 len = precision;
15731 lisp_string = make_string (string, len);
15732 if (NILP (props))
15733 props = mode_line_string_face_prop;
15734 else if (!NILP (mode_line_string_face))
15735 {
15736 Lisp_Object face = Fplist_get (props, Qface);
15737 props = Fcopy_sequence (props);
15738 if (NILP (face))
15739 face = mode_line_string_face;
15740 else
15741 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15742 props = Fplist_put (props, Qface, face);
15743 }
15744 Fadd_text_properties (make_number (0), make_number (len),
15745 props, lisp_string);
15746 }
15747 else
15748 {
15749 len = XFASTINT (Flength (lisp_string));
15750 if (precision > 0 && len > precision)
15751 {
15752 len = precision;
15753 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15754 precision = -1;
15755 }
15756 if (!NILP (mode_line_string_face))
15757 {
15758 Lisp_Object face;
15759 if (NILP (props))
15760 props = Ftext_properties_at (make_number (0), lisp_string);
15761 face = Fplist_get (props, Qface);
15762 if (NILP (face))
15763 face = mode_line_string_face;
15764 else
15765 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15766 props = Fcons (Qface, Fcons (face, Qnil));
15767 if (copy_string)
15768 lisp_string = Fcopy_sequence (lisp_string);
15769 }
15770 if (!NILP (props))
15771 Fadd_text_properties (make_number (0), make_number (len),
15772 props, lisp_string);
15773 }
15774
15775 if (len > 0)
15776 {
15777 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15778 n += len;
15779 }
15780
15781 if (field_width > len)
15782 {
15783 field_width -= len;
15784 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15785 if (!NILP (props))
15786 Fadd_text_properties (make_number (0), make_number (field_width),
15787 props, lisp_string);
15788 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15789 n += field_width;
15790 }
15791
15792 return n;
15793 }
15794
15795
15796 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15797 0, 4, 0,
15798 doc: /* Return the mode-line of selected window as a string.
15799 First optional arg FORMAT specifies a different format string (see
15800 `mode-line-format' for details) to use. If FORMAT is t, return
15801 the buffer's header-line. Second optional arg WINDOW specifies a
15802 different window to use as the context for the formatting.
15803 If third optional arg NO-PROPS is non-nil, string is not propertized.
15804 Fourth optional arg BUFFER specifies which buffer to use. */)
15805 (format, window, no_props, buffer)
15806 Lisp_Object format, window, no_props, buffer;
15807 {
15808 struct it it;
15809 int len;
15810 struct window *w;
15811 struct buffer *old_buffer = NULL;
15812 enum face_id face_id = DEFAULT_FACE_ID;
15813
15814 if (NILP (window))
15815 window = selected_window;
15816 CHECK_WINDOW (window);
15817 w = XWINDOW (window);
15818
15819 if (NILP (buffer))
15820 buffer = w->buffer;
15821
15822 CHECK_BUFFER (buffer);
15823
15824 if (XBUFFER (buffer) != current_buffer)
15825 {
15826 old_buffer = current_buffer;
15827 set_buffer_internal_1 (XBUFFER (buffer));
15828 }
15829
15830 if (NILP (format) || EQ (format, Qt))
15831 {
15832 face_id = (NILP (format)
15833 ? CURRENT_MODE_LINE_FACE_ID (w)
15834 : HEADER_LINE_FACE_ID);
15835 format = (NILP (format)
15836 ? current_buffer->mode_line_format
15837 : current_buffer->header_line_format);
15838 }
15839
15840 init_iterator (&it, w, -1, -1, NULL, face_id);
15841
15842 if (NILP (no_props))
15843 {
15844 mode_line_string_face
15845 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15846 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15847 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15848
15849 mode_line_string_face_prop
15850 = (NILP (mode_line_string_face) ? Qnil
15851 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15852
15853 /* We need a dummy last element in mode_line_string_list to
15854 indicate we are building the propertized mode-line string.
15855 Using mode_line_string_face_prop here GC protects it. */
15856 mode_line_string_list
15857 = Fcons (mode_line_string_face_prop, Qnil);
15858 frame_title_ptr = NULL;
15859 }
15860 else
15861 {
15862 mode_line_string_face_prop = Qnil;
15863 mode_line_string_list = Qnil;
15864 frame_title_ptr = frame_title_buf;
15865 }
15866
15867 push_frame_kboard (it.f);
15868 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15869 pop_frame_kboard ();
15870
15871 if (old_buffer)
15872 set_buffer_internal_1 (old_buffer);
15873
15874 if (NILP (no_props))
15875 {
15876 Lisp_Object str;
15877 mode_line_string_list = Fnreverse (mode_line_string_list);
15878 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15879 make_string ("", 0));
15880 mode_line_string_face_prop = Qnil;
15881 mode_line_string_list = Qnil;
15882 return str;
15883 }
15884
15885 len = frame_title_ptr - frame_title_buf;
15886 if (len > 0 && frame_title_ptr[-1] == '-')
15887 {
15888 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15889 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15890 ;
15891 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15892 if (len > frame_title_ptr - frame_title_buf)
15893 len = frame_title_ptr - frame_title_buf;
15894 }
15895
15896 frame_title_ptr = NULL;
15897 return make_string (frame_title_buf, len);
15898 }
15899
15900 /* Write a null-terminated, right justified decimal representation of
15901 the positive integer D to BUF using a minimal field width WIDTH. */
15902
15903 static void
15904 pint2str (buf, width, d)
15905 register char *buf;
15906 register int width;
15907 register int d;
15908 {
15909 register char *p = buf;
15910
15911 if (d <= 0)
15912 *p++ = '0';
15913 else
15914 {
15915 while (d > 0)
15916 {
15917 *p++ = d % 10 + '0';
15918 d /= 10;
15919 }
15920 }
15921
15922 for (width -= (int) (p - buf); width > 0; --width)
15923 *p++ = ' ';
15924 *p-- = '\0';
15925 while (p > buf)
15926 {
15927 d = *buf;
15928 *buf++ = *p;
15929 *p-- = d;
15930 }
15931 }
15932
15933 /* Write a null-terminated, right justified decimal and "human
15934 readable" representation of the nonnegative integer D to BUF using
15935 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15936
15937 static const char power_letter[] =
15938 {
15939 0, /* not used */
15940 'k', /* kilo */
15941 'M', /* mega */
15942 'G', /* giga */
15943 'T', /* tera */
15944 'P', /* peta */
15945 'E', /* exa */
15946 'Z', /* zetta */
15947 'Y' /* yotta */
15948 };
15949
15950 static void
15951 pint2hrstr (buf, width, d)
15952 char *buf;
15953 int width;
15954 int d;
15955 {
15956 /* We aim to represent the nonnegative integer D as
15957 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15958 int quotient = d;
15959 int remainder = 0;
15960 /* -1 means: do not use TENTHS. */
15961 int tenths = -1;
15962 int exponent = 0;
15963
15964 /* Length of QUOTIENT.TENTHS as a string. */
15965 int length;
15966
15967 char * psuffix;
15968 char * p;
15969
15970 if (1000 <= quotient)
15971 {
15972 /* Scale to the appropriate EXPONENT. */
15973 do
15974 {
15975 remainder = quotient % 1000;
15976 quotient /= 1000;
15977 exponent++;
15978 }
15979 while (1000 <= quotient);
15980
15981 /* Round to nearest and decide whether to use TENTHS or not. */
15982 if (quotient <= 9)
15983 {
15984 tenths = remainder / 100;
15985 if (50 <= remainder % 100)
15986 if (tenths < 9)
15987 tenths++;
15988 else
15989 {
15990 quotient++;
15991 if (quotient == 10)
15992 tenths = -1;
15993 else
15994 tenths = 0;
15995 }
15996 }
15997 else
15998 if (500 <= remainder)
15999 if (quotient < 999)
16000 quotient++;
16001 else
16002 {
16003 quotient = 1;
16004 exponent++;
16005 tenths = 0;
16006 }
16007 }
16008
16009 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16010 if (tenths == -1 && quotient <= 99)
16011 if (quotient <= 9)
16012 length = 1;
16013 else
16014 length = 2;
16015 else
16016 length = 3;
16017 p = psuffix = buf + max (width, length);
16018
16019 /* Print EXPONENT. */
16020 if (exponent)
16021 *psuffix++ = power_letter[exponent];
16022 *psuffix = '\0';
16023
16024 /* Print TENTHS. */
16025 if (tenths >= 0)
16026 {
16027 *--p = '0' + tenths;
16028 *--p = '.';
16029 }
16030
16031 /* Print QUOTIENT. */
16032 do
16033 {
16034 int digit = quotient % 10;
16035 *--p = '0' + digit;
16036 }
16037 while ((quotient /= 10) != 0);
16038
16039 /* Print leading spaces. */
16040 while (buf < p)
16041 *--p = ' ';
16042 }
16043
16044 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16045 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16046 type of CODING_SYSTEM. Return updated pointer into BUF. */
16047
16048 static unsigned char invalid_eol_type[] = "(*invalid*)";
16049
16050 static char *
16051 decode_mode_spec_coding (coding_system, buf, eol_flag)
16052 Lisp_Object coding_system;
16053 register char *buf;
16054 int eol_flag;
16055 {
16056 Lisp_Object val;
16057 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16058 const unsigned char *eol_str;
16059 int eol_str_len;
16060 /* The EOL conversion we are using. */
16061 Lisp_Object eoltype;
16062
16063 val = Fget (coding_system, Qcoding_system);
16064 eoltype = Qnil;
16065
16066 if (!VECTORP (val)) /* Not yet decided. */
16067 {
16068 if (multibyte)
16069 *buf++ = '-';
16070 if (eol_flag)
16071 eoltype = eol_mnemonic_undecided;
16072 /* Don't mention EOL conversion if it isn't decided. */
16073 }
16074 else
16075 {
16076 Lisp_Object eolvalue;
16077
16078 eolvalue = Fget (coding_system, Qeol_type);
16079
16080 if (multibyte)
16081 *buf++ = XFASTINT (AREF (val, 1));
16082
16083 if (eol_flag)
16084 {
16085 /* The EOL conversion that is normal on this system. */
16086
16087 if (NILP (eolvalue)) /* Not yet decided. */
16088 eoltype = eol_mnemonic_undecided;
16089 else if (VECTORP (eolvalue)) /* Not yet decided. */
16090 eoltype = eol_mnemonic_undecided;
16091 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16092 eoltype = (XFASTINT (eolvalue) == 0
16093 ? eol_mnemonic_unix
16094 : (XFASTINT (eolvalue) == 1
16095 ? eol_mnemonic_dos : eol_mnemonic_mac));
16096 }
16097 }
16098
16099 if (eol_flag)
16100 {
16101 /* Mention the EOL conversion if it is not the usual one. */
16102 if (STRINGP (eoltype))
16103 {
16104 eol_str = SDATA (eoltype);
16105 eol_str_len = SBYTES (eoltype);
16106 }
16107 else if (INTEGERP (eoltype)
16108 && CHAR_VALID_P (XINT (eoltype), 0))
16109 {
16110 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16111 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16112 eol_str = tmp;
16113 }
16114 else
16115 {
16116 eol_str = invalid_eol_type;
16117 eol_str_len = sizeof (invalid_eol_type) - 1;
16118 }
16119 bcopy (eol_str, buf, eol_str_len);
16120 buf += eol_str_len;
16121 }
16122
16123 return buf;
16124 }
16125
16126 /* Return a string for the output of a mode line %-spec for window W,
16127 generated by character C. PRECISION >= 0 means don't return a
16128 string longer than that value. FIELD_WIDTH > 0 means pad the
16129 string returned with spaces to that value. Return 1 in *MULTIBYTE
16130 if the result is multibyte text.
16131
16132 Note we operate on the current buffer for most purposes,
16133 the exception being w->base_line_pos. */
16134
16135 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16136
16137 static char *
16138 decode_mode_spec (w, c, field_width, precision, multibyte)
16139 struct window *w;
16140 register int c;
16141 int field_width, precision;
16142 int *multibyte;
16143 {
16144 Lisp_Object obj;
16145 struct frame *f = XFRAME (WINDOW_FRAME (w));
16146 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16147 struct buffer *b = current_buffer;
16148
16149 obj = Qnil;
16150 *multibyte = 0;
16151
16152 switch (c)
16153 {
16154 case '*':
16155 if (!NILP (b->read_only))
16156 return "%";
16157 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16158 return "*";
16159 return "-";
16160
16161 case '+':
16162 /* This differs from %* only for a modified read-only buffer. */
16163 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16164 return "*";
16165 if (!NILP (b->read_only))
16166 return "%";
16167 return "-";
16168
16169 case '&':
16170 /* This differs from %* in ignoring read-only-ness. */
16171 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16172 return "*";
16173 return "-";
16174
16175 case '%':
16176 return "%";
16177
16178 case '[':
16179 {
16180 int i;
16181 char *p;
16182
16183 if (command_loop_level > 5)
16184 return "[[[... ";
16185 p = decode_mode_spec_buf;
16186 for (i = 0; i < command_loop_level; i++)
16187 *p++ = '[';
16188 *p = 0;
16189 return decode_mode_spec_buf;
16190 }
16191
16192 case ']':
16193 {
16194 int i;
16195 char *p;
16196
16197 if (command_loop_level > 5)
16198 return " ...]]]";
16199 p = decode_mode_spec_buf;
16200 for (i = 0; i < command_loop_level; i++)
16201 *p++ = ']';
16202 *p = 0;
16203 return decode_mode_spec_buf;
16204 }
16205
16206 case '-':
16207 {
16208 register int i;
16209
16210 /* Let lots_of_dashes be a string of infinite length. */
16211 if (!NILP (mode_line_string_list))
16212 return "--";
16213 if (field_width <= 0
16214 || field_width > sizeof (lots_of_dashes))
16215 {
16216 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16217 decode_mode_spec_buf[i] = '-';
16218 decode_mode_spec_buf[i] = '\0';
16219 return decode_mode_spec_buf;
16220 }
16221 else
16222 return lots_of_dashes;
16223 }
16224
16225 case 'b':
16226 obj = b->name;
16227 break;
16228
16229 case 'c':
16230 {
16231 int col = (int) current_column (); /* iftc */
16232 w->column_number_displayed = make_number (col);
16233 pint2str (decode_mode_spec_buf, field_width, col);
16234 return decode_mode_spec_buf;
16235 }
16236
16237 case 'F':
16238 /* %F displays the frame name. */
16239 if (!NILP (f->title))
16240 return (char *) SDATA (f->title);
16241 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16242 return (char *) SDATA (f->name);
16243 return "Emacs";
16244
16245 case 'f':
16246 obj = b->filename;
16247 break;
16248
16249 case 'i':
16250 {
16251 int size = ZV - BEGV;
16252 pint2str (decode_mode_spec_buf, field_width, size);
16253 return decode_mode_spec_buf;
16254 }
16255
16256 case 'I':
16257 {
16258 int size = ZV - BEGV;
16259 pint2hrstr (decode_mode_spec_buf, field_width, size);
16260 return decode_mode_spec_buf;
16261 }
16262
16263 case 'l':
16264 {
16265 int startpos = XMARKER (w->start)->charpos;
16266 int startpos_byte = marker_byte_position (w->start);
16267 int line, linepos, linepos_byte, topline;
16268 int nlines, junk;
16269 int height = WINDOW_TOTAL_LINES (w);
16270
16271 /* If we decided that this buffer isn't suitable for line numbers,
16272 don't forget that too fast. */
16273 if (EQ (w->base_line_pos, w->buffer))
16274 goto no_value;
16275 /* But do forget it, if the window shows a different buffer now. */
16276 else if (BUFFERP (w->base_line_pos))
16277 w->base_line_pos = Qnil;
16278
16279 /* If the buffer is very big, don't waste time. */
16280 if (INTEGERP (Vline_number_display_limit)
16281 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16282 {
16283 w->base_line_pos = Qnil;
16284 w->base_line_number = Qnil;
16285 goto no_value;
16286 }
16287
16288 if (!NILP (w->base_line_number)
16289 && !NILP (w->base_line_pos)
16290 && XFASTINT (w->base_line_pos) <= startpos)
16291 {
16292 line = XFASTINT (w->base_line_number);
16293 linepos = XFASTINT (w->base_line_pos);
16294 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16295 }
16296 else
16297 {
16298 line = 1;
16299 linepos = BUF_BEGV (b);
16300 linepos_byte = BUF_BEGV_BYTE (b);
16301 }
16302
16303 /* Count lines from base line to window start position. */
16304 nlines = display_count_lines (linepos, linepos_byte,
16305 startpos_byte,
16306 startpos, &junk);
16307
16308 topline = nlines + line;
16309
16310 /* Determine a new base line, if the old one is too close
16311 or too far away, or if we did not have one.
16312 "Too close" means it's plausible a scroll-down would
16313 go back past it. */
16314 if (startpos == BUF_BEGV (b))
16315 {
16316 w->base_line_number = make_number (topline);
16317 w->base_line_pos = make_number (BUF_BEGV (b));
16318 }
16319 else if (nlines < height + 25 || nlines > height * 3 + 50
16320 || linepos == BUF_BEGV (b))
16321 {
16322 int limit = BUF_BEGV (b);
16323 int limit_byte = BUF_BEGV_BYTE (b);
16324 int position;
16325 int distance = (height * 2 + 30) * line_number_display_limit_width;
16326
16327 if (startpos - distance > limit)
16328 {
16329 limit = startpos - distance;
16330 limit_byte = CHAR_TO_BYTE (limit);
16331 }
16332
16333 nlines = display_count_lines (startpos, startpos_byte,
16334 limit_byte,
16335 - (height * 2 + 30),
16336 &position);
16337 /* If we couldn't find the lines we wanted within
16338 line_number_display_limit_width chars per line,
16339 give up on line numbers for this window. */
16340 if (position == limit_byte && limit == startpos - distance)
16341 {
16342 w->base_line_pos = w->buffer;
16343 w->base_line_number = Qnil;
16344 goto no_value;
16345 }
16346
16347 w->base_line_number = make_number (topline - nlines);
16348 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16349 }
16350
16351 /* Now count lines from the start pos to point. */
16352 nlines = display_count_lines (startpos, startpos_byte,
16353 PT_BYTE, PT, &junk);
16354
16355 /* Record that we did display the line number. */
16356 line_number_displayed = 1;
16357
16358 /* Make the string to show. */
16359 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16360 return decode_mode_spec_buf;
16361 no_value:
16362 {
16363 char* p = decode_mode_spec_buf;
16364 int pad = field_width - 2;
16365 while (pad-- > 0)
16366 *p++ = ' ';
16367 *p++ = '?';
16368 *p++ = '?';
16369 *p = '\0';
16370 return decode_mode_spec_buf;
16371 }
16372 }
16373 break;
16374
16375 case 'm':
16376 obj = b->mode_name;
16377 break;
16378
16379 case 'n':
16380 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16381 return " Narrow";
16382 break;
16383
16384 case 'p':
16385 {
16386 int pos = marker_position (w->start);
16387 int total = BUF_ZV (b) - BUF_BEGV (b);
16388
16389 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16390 {
16391 if (pos <= BUF_BEGV (b))
16392 return "All";
16393 else
16394 return "Bottom";
16395 }
16396 else if (pos <= BUF_BEGV (b))
16397 return "Top";
16398 else
16399 {
16400 if (total > 1000000)
16401 /* Do it differently for a large value, to avoid overflow. */
16402 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16403 else
16404 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16405 /* We can't normally display a 3-digit number,
16406 so get us a 2-digit number that is close. */
16407 if (total == 100)
16408 total = 99;
16409 sprintf (decode_mode_spec_buf, "%2d%%", total);
16410 return decode_mode_spec_buf;
16411 }
16412 }
16413
16414 /* Display percentage of size above the bottom of the screen. */
16415 case 'P':
16416 {
16417 int toppos = marker_position (w->start);
16418 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16419 int total = BUF_ZV (b) - BUF_BEGV (b);
16420
16421 if (botpos >= BUF_ZV (b))
16422 {
16423 if (toppos <= BUF_BEGV (b))
16424 return "All";
16425 else
16426 return "Bottom";
16427 }
16428 else
16429 {
16430 if (total > 1000000)
16431 /* Do it differently for a large value, to avoid overflow. */
16432 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16433 else
16434 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16435 /* We can't normally display a 3-digit number,
16436 so get us a 2-digit number that is close. */
16437 if (total == 100)
16438 total = 99;
16439 if (toppos <= BUF_BEGV (b))
16440 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16441 else
16442 sprintf (decode_mode_spec_buf, "%2d%%", total);
16443 return decode_mode_spec_buf;
16444 }
16445 }
16446
16447 case 's':
16448 /* status of process */
16449 obj = Fget_buffer_process (Fcurrent_buffer ());
16450 if (NILP (obj))
16451 return "no process";
16452 #ifdef subprocesses
16453 obj = Fsymbol_name (Fprocess_status (obj));
16454 #endif
16455 break;
16456
16457 case 't': /* indicate TEXT or BINARY */
16458 #ifdef MODE_LINE_BINARY_TEXT
16459 return MODE_LINE_BINARY_TEXT (b);
16460 #else
16461 return "T";
16462 #endif
16463
16464 case 'z':
16465 /* coding-system (not including end-of-line format) */
16466 case 'Z':
16467 /* coding-system (including end-of-line type) */
16468 {
16469 int eol_flag = (c == 'Z');
16470 char *p = decode_mode_spec_buf;
16471
16472 if (! FRAME_WINDOW_P (f))
16473 {
16474 /* No need to mention EOL here--the terminal never needs
16475 to do EOL conversion. */
16476 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16477 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16478 }
16479 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16480 p, eol_flag);
16481
16482 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16483 #ifdef subprocesses
16484 obj = Fget_buffer_process (Fcurrent_buffer ());
16485 if (PROCESSP (obj))
16486 {
16487 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16488 p, eol_flag);
16489 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16490 p, eol_flag);
16491 }
16492 #endif /* subprocesses */
16493 #endif /* 0 */
16494 *p = 0;
16495 return decode_mode_spec_buf;
16496 }
16497 }
16498
16499 if (STRINGP (obj))
16500 {
16501 *multibyte = STRING_MULTIBYTE (obj);
16502 return (char *) SDATA (obj);
16503 }
16504 else
16505 return "";
16506 }
16507
16508
16509 /* Count up to COUNT lines starting from START / START_BYTE.
16510 But don't go beyond LIMIT_BYTE.
16511 Return the number of lines thus found (always nonnegative).
16512
16513 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16514
16515 static int
16516 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16517 int start, start_byte, limit_byte, count;
16518 int *byte_pos_ptr;
16519 {
16520 register unsigned char *cursor;
16521 unsigned char *base;
16522
16523 register int ceiling;
16524 register unsigned char *ceiling_addr;
16525 int orig_count = count;
16526
16527 /* If we are not in selective display mode,
16528 check only for newlines. */
16529 int selective_display = (!NILP (current_buffer->selective_display)
16530 && !INTEGERP (current_buffer->selective_display));
16531
16532 if (count > 0)
16533 {
16534 while (start_byte < limit_byte)
16535 {
16536 ceiling = BUFFER_CEILING_OF (start_byte);
16537 ceiling = min (limit_byte - 1, ceiling);
16538 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16539 base = (cursor = BYTE_POS_ADDR (start_byte));
16540 while (1)
16541 {
16542 if (selective_display)
16543 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16544 ;
16545 else
16546 while (*cursor != '\n' && ++cursor != ceiling_addr)
16547 ;
16548
16549 if (cursor != ceiling_addr)
16550 {
16551 if (--count == 0)
16552 {
16553 start_byte += cursor - base + 1;
16554 *byte_pos_ptr = start_byte;
16555 return orig_count;
16556 }
16557 else
16558 if (++cursor == ceiling_addr)
16559 break;
16560 }
16561 else
16562 break;
16563 }
16564 start_byte += cursor - base;
16565 }
16566 }
16567 else
16568 {
16569 while (start_byte > limit_byte)
16570 {
16571 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16572 ceiling = max (limit_byte, ceiling);
16573 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16574 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16575 while (1)
16576 {
16577 if (selective_display)
16578 while (--cursor != ceiling_addr
16579 && *cursor != '\n' && *cursor != 015)
16580 ;
16581 else
16582 while (--cursor != ceiling_addr && *cursor != '\n')
16583 ;
16584
16585 if (cursor != ceiling_addr)
16586 {
16587 if (++count == 0)
16588 {
16589 start_byte += cursor - base + 1;
16590 *byte_pos_ptr = start_byte;
16591 /* When scanning backwards, we should
16592 not count the newline posterior to which we stop. */
16593 return - orig_count - 1;
16594 }
16595 }
16596 else
16597 break;
16598 }
16599 /* Here we add 1 to compensate for the last decrement
16600 of CURSOR, which took it past the valid range. */
16601 start_byte += cursor - base + 1;
16602 }
16603 }
16604
16605 *byte_pos_ptr = limit_byte;
16606
16607 if (count < 0)
16608 return - orig_count + count;
16609 return orig_count - count;
16610
16611 }
16612
16613
16614 \f
16615 /***********************************************************************
16616 Displaying strings
16617 ***********************************************************************/
16618
16619 /* Display a NUL-terminated string, starting with index START.
16620
16621 If STRING is non-null, display that C string. Otherwise, the Lisp
16622 string LISP_STRING is displayed.
16623
16624 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16625 FACE_STRING. Display STRING or LISP_STRING with the face at
16626 FACE_STRING_POS in FACE_STRING:
16627
16628 Display the string in the environment given by IT, but use the
16629 standard display table, temporarily.
16630
16631 FIELD_WIDTH is the minimum number of output glyphs to produce.
16632 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16633 with spaces. If STRING has more characters, more than FIELD_WIDTH
16634 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16635
16636 PRECISION is the maximum number of characters to output from
16637 STRING. PRECISION < 0 means don't truncate the string.
16638
16639 This is roughly equivalent to printf format specifiers:
16640
16641 FIELD_WIDTH PRECISION PRINTF
16642 ----------------------------------------
16643 -1 -1 %s
16644 -1 10 %.10s
16645 10 -1 %10s
16646 20 10 %20.10s
16647
16648 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16649 display them, and < 0 means obey the current buffer's value of
16650 enable_multibyte_characters.
16651
16652 Value is the number of glyphs produced. */
16653
16654 static int
16655 display_string (string, lisp_string, face_string, face_string_pos,
16656 start, it, field_width, precision, max_x, multibyte)
16657 unsigned char *string;
16658 Lisp_Object lisp_string;
16659 Lisp_Object face_string;
16660 int face_string_pos;
16661 int start;
16662 struct it *it;
16663 int field_width, precision, max_x;
16664 int multibyte;
16665 {
16666 int hpos_at_start = it->hpos;
16667 int saved_face_id = it->face_id;
16668 struct glyph_row *row = it->glyph_row;
16669
16670 /* Initialize the iterator IT for iteration over STRING beginning
16671 with index START. */
16672 reseat_to_string (it, string, lisp_string, start,
16673 precision, field_width, multibyte);
16674
16675 /* If displaying STRING, set up the face of the iterator
16676 from LISP_STRING, if that's given. */
16677 if (STRINGP (face_string))
16678 {
16679 int endptr;
16680 struct face *face;
16681
16682 it->face_id
16683 = face_at_string_position (it->w, face_string, face_string_pos,
16684 0, it->region_beg_charpos,
16685 it->region_end_charpos,
16686 &endptr, it->base_face_id, 0);
16687 face = FACE_FROM_ID (it->f, it->face_id);
16688 it->face_box_p = face->box != FACE_NO_BOX;
16689 }
16690
16691 /* Set max_x to the maximum allowed X position. Don't let it go
16692 beyond the right edge of the window. */
16693 if (max_x <= 0)
16694 max_x = it->last_visible_x;
16695 else
16696 max_x = min (max_x, it->last_visible_x);
16697
16698 /* Skip over display elements that are not visible. because IT->w is
16699 hscrolled. */
16700 if (it->current_x < it->first_visible_x)
16701 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16702 MOVE_TO_POS | MOVE_TO_X);
16703
16704 row->ascent = it->max_ascent;
16705 row->height = it->max_ascent + it->max_descent;
16706 row->phys_ascent = it->max_phys_ascent;
16707 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16708
16709 /* This condition is for the case that we are called with current_x
16710 past last_visible_x. */
16711 while (it->current_x < max_x)
16712 {
16713 int x_before, x, n_glyphs_before, i, nglyphs;
16714
16715 /* Get the next display element. */
16716 if (!get_next_display_element (it))
16717 break;
16718
16719 /* Produce glyphs. */
16720 x_before = it->current_x;
16721 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16722 PRODUCE_GLYPHS (it);
16723
16724 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16725 i = 0;
16726 x = x_before;
16727 while (i < nglyphs)
16728 {
16729 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16730
16731 if (!it->truncate_lines_p
16732 && x + glyph->pixel_width > max_x)
16733 {
16734 /* End of continued line or max_x reached. */
16735 if (CHAR_GLYPH_PADDING_P (*glyph))
16736 {
16737 /* A wide character is unbreakable. */
16738 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16739 it->current_x = x_before;
16740 }
16741 else
16742 {
16743 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16744 it->current_x = x;
16745 }
16746 break;
16747 }
16748 else if (x + glyph->pixel_width > it->first_visible_x)
16749 {
16750 /* Glyph is at least partially visible. */
16751 ++it->hpos;
16752 if (x < it->first_visible_x)
16753 it->glyph_row->x = x - it->first_visible_x;
16754 }
16755 else
16756 {
16757 /* Glyph is off the left margin of the display area.
16758 Should not happen. */
16759 abort ();
16760 }
16761
16762 row->ascent = max (row->ascent, it->max_ascent);
16763 row->height = max (row->height, it->max_ascent + it->max_descent);
16764 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16765 row->phys_height = max (row->phys_height,
16766 it->max_phys_ascent + it->max_phys_descent);
16767 x += glyph->pixel_width;
16768 ++i;
16769 }
16770
16771 /* Stop if max_x reached. */
16772 if (i < nglyphs)
16773 break;
16774
16775 /* Stop at line ends. */
16776 if (ITERATOR_AT_END_OF_LINE_P (it))
16777 {
16778 it->continuation_lines_width = 0;
16779 break;
16780 }
16781
16782 set_iterator_to_next (it, 1);
16783
16784 /* Stop if truncating at the right edge. */
16785 if (it->truncate_lines_p
16786 && it->current_x >= it->last_visible_x)
16787 {
16788 /* Add truncation mark, but don't do it if the line is
16789 truncated at a padding space. */
16790 if (IT_CHARPOS (*it) < it->string_nchars)
16791 {
16792 if (!FRAME_WINDOW_P (it->f))
16793 {
16794 int i, n;
16795
16796 if (it->current_x > it->last_visible_x)
16797 {
16798 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16799 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16800 break;
16801 for (n = row->used[TEXT_AREA]; i < n; ++i)
16802 {
16803 row->used[TEXT_AREA] = i;
16804 produce_special_glyphs (it, IT_TRUNCATION);
16805 }
16806 }
16807 produce_special_glyphs (it, IT_TRUNCATION);
16808 }
16809 it->glyph_row->truncated_on_right_p = 1;
16810 }
16811 break;
16812 }
16813 }
16814
16815 /* Maybe insert a truncation at the left. */
16816 if (it->first_visible_x
16817 && IT_CHARPOS (*it) > 0)
16818 {
16819 if (!FRAME_WINDOW_P (it->f))
16820 insert_left_trunc_glyphs (it);
16821 it->glyph_row->truncated_on_left_p = 1;
16822 }
16823
16824 it->face_id = saved_face_id;
16825
16826 /* Value is number of columns displayed. */
16827 return it->hpos - hpos_at_start;
16828 }
16829
16830
16831 \f
16832 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16833 appears as an element of LIST or as the car of an element of LIST.
16834 If PROPVAL is a list, compare each element against LIST in that
16835 way, and return 1/2 if any element of PROPVAL is found in LIST.
16836 Otherwise return 0. This function cannot quit.
16837 The return value is 2 if the text is invisible but with an ellipsis
16838 and 1 if it's invisible and without an ellipsis. */
16839
16840 int
16841 invisible_p (propval, list)
16842 register Lisp_Object propval;
16843 Lisp_Object list;
16844 {
16845 register Lisp_Object tail, proptail;
16846
16847 for (tail = list; CONSP (tail); tail = XCDR (tail))
16848 {
16849 register Lisp_Object tem;
16850 tem = XCAR (tail);
16851 if (EQ (propval, tem))
16852 return 1;
16853 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16854 return NILP (XCDR (tem)) ? 1 : 2;
16855 }
16856
16857 if (CONSP (propval))
16858 {
16859 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16860 {
16861 Lisp_Object propelt;
16862 propelt = XCAR (proptail);
16863 for (tail = list; CONSP (tail); tail = XCDR (tail))
16864 {
16865 register Lisp_Object tem;
16866 tem = XCAR (tail);
16867 if (EQ (propelt, tem))
16868 return 1;
16869 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16870 return NILP (XCDR (tem)) ? 1 : 2;
16871 }
16872 }
16873 }
16874
16875 return 0;
16876 }
16877
16878 /* Calculate a width or height in pixels from a specification using
16879 the following elements:
16880
16881 SPEC ::=
16882 NUM - a (fractional) multiple of the default font width/height
16883 (NUM) - specifies exactly NUM pixels
16884 UNIT - a fixed number of pixels, see below.
16885 ELEMENT - size of a display element in pixels, see below.
16886 (NUM . SPEC) - equals NUM * SPEC
16887 (+ SPEC SPEC ...) - add pixel values
16888 (- SPEC SPEC ...) - subtract pixel values
16889 (- SPEC) - negate pixel value
16890
16891 NUM ::=
16892 INT or FLOAT - a number constant
16893 SYMBOL - use symbol's (buffer local) variable binding.
16894
16895 UNIT ::=
16896 in - pixels per inch *)
16897 mm - pixels per 1/1000 meter *)
16898 cm - pixels per 1/100 meter *)
16899 width - width of current font in pixels.
16900 height - height of current font in pixels.
16901
16902 *) using the ratio(s) defined in display-pixels-per-inch.
16903
16904 ELEMENT ::=
16905
16906 left-fringe - left fringe width in pixels
16907 right-fringe - right fringe width in pixels
16908
16909 left-margin - left margin width in pixels
16910 right-margin - right margin width in pixels
16911
16912 scroll-bar - scroll-bar area width in pixels
16913
16914 Examples:
16915
16916 Pixels corresponding to 5 inches:
16917 (5 . in)
16918
16919 Total width of non-text areas on left side of window (if scroll-bar is on left):
16920 '(space :width (+ left-fringe left-margin scroll-bar))
16921
16922 Align to first text column (in header line):
16923 '(space :align-to 0)
16924
16925 Align to middle of text area minus half the width of variable `my-image'
16926 containing a loaded image:
16927 '(space :align-to (0.5 . (- text my-image)))
16928
16929 Width of left margin minus width of 1 character in the default font:
16930 '(space :width (- left-margin 1))
16931
16932 Width of left margin minus width of 2 characters in the current font:
16933 '(space :width (- left-margin (2 . width)))
16934
16935 Center 1 character over left-margin (in header line):
16936 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16937
16938 Different ways to express width of left fringe plus left margin minus one pixel:
16939 '(space :width (- (+ left-fringe left-margin) (1)))
16940 '(space :width (+ left-fringe left-margin (- (1))))
16941 '(space :width (+ left-fringe left-margin (-1)))
16942
16943 */
16944
16945 #define NUMVAL(X) \
16946 ((INTEGERP (X) || FLOATP (X)) \
16947 ? XFLOATINT (X) \
16948 : - 1)
16949
16950 int
16951 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
16952 double *res;
16953 struct it *it;
16954 Lisp_Object prop;
16955 void *font;
16956 int width_p, *align_to;
16957 {
16958 double pixels;
16959
16960 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16961 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16962
16963 if (NILP (prop))
16964 return OK_PIXELS (0);
16965
16966 if (SYMBOLP (prop))
16967 {
16968 if (SCHARS (SYMBOL_NAME (prop)) == 2)
16969 {
16970 char *unit = SDATA (SYMBOL_NAME (prop));
16971
16972 if (unit[0] == 'i' && unit[1] == 'n')
16973 pixels = 1.0;
16974 else if (unit[0] == 'm' && unit[1] == 'm')
16975 pixels = 25.4;
16976 else if (unit[0] == 'c' && unit[1] == 'm')
16977 pixels = 2.54;
16978 else
16979 pixels = 0;
16980 if (pixels > 0)
16981 {
16982 double ppi;
16983 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
16984 || (CONSP (Vdisplay_pixels_per_inch)
16985 && (ppi = (width_p
16986 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
16987 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
16988 ppi > 0)))
16989 return OK_PIXELS (ppi / pixels);
16990
16991 return 0;
16992 }
16993 }
16994
16995 #ifdef HAVE_WINDOW_SYSTEM
16996 if (EQ (prop, Qheight))
16997 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
16998 if (EQ (prop, Qwidth))
16999 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17000 #else
17001 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17002 return OK_PIXELS (1);
17003 #endif
17004
17005 if (EQ (prop, Qtext))
17006 return OK_PIXELS (width_p
17007 ? window_box_width (it->w, TEXT_AREA)
17008 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17009
17010 if (align_to && *align_to < 0)
17011 {
17012 *res = 0;
17013 if (EQ (prop, Qleft))
17014 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17015 if (EQ (prop, Qright))
17016 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17017 if (EQ (prop, Qcenter))
17018 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17019 + window_box_width (it->w, TEXT_AREA) / 2);
17020 if (EQ (prop, Qleft_fringe))
17021 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17022 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17023 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17024 if (EQ (prop, Qright_fringe))
17025 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17026 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17027 : window_box_right_offset (it->w, TEXT_AREA));
17028 if (EQ (prop, Qleft_margin))
17029 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17030 if (EQ (prop, Qright_margin))
17031 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17032 if (EQ (prop, Qscroll_bar))
17033 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17034 ? 0
17035 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17036 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17037 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17038 : 0)));
17039 }
17040 else
17041 {
17042 if (EQ (prop, Qleft_fringe))
17043 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17044 if (EQ (prop, Qright_fringe))
17045 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17046 if (EQ (prop, Qleft_margin))
17047 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17048 if (EQ (prop, Qright_margin))
17049 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17050 if (EQ (prop, Qscroll_bar))
17051 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17052 }
17053
17054 prop = Fbuffer_local_value (prop, it->w->buffer);
17055 }
17056
17057 if (INTEGERP (prop) || FLOATP (prop))
17058 {
17059 int base_unit = (width_p
17060 ? FRAME_COLUMN_WIDTH (it->f)
17061 : FRAME_LINE_HEIGHT (it->f));
17062 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17063 }
17064
17065 if (CONSP (prop))
17066 {
17067 Lisp_Object car = XCAR (prop);
17068 Lisp_Object cdr = XCDR (prop);
17069
17070 if (SYMBOLP (car))
17071 {
17072 #ifdef HAVE_WINDOW_SYSTEM
17073 if (valid_image_p (prop))
17074 {
17075 int id = lookup_image (it->f, prop);
17076 struct image *img = IMAGE_FROM_ID (it->f, id);
17077
17078 return OK_PIXELS (width_p ? img->width : img->height);
17079 }
17080 #endif
17081 if (EQ (car, Qplus) || EQ (car, Qminus))
17082 {
17083 int first = 1;
17084 double px;
17085
17086 pixels = 0;
17087 while (CONSP (cdr))
17088 {
17089 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17090 font, width_p, align_to))
17091 return 0;
17092 if (first)
17093 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17094 else
17095 pixels += px;
17096 cdr = XCDR (cdr);
17097 }
17098 if (EQ (car, Qminus))
17099 pixels = -pixels;
17100 return OK_PIXELS (pixels);
17101 }
17102
17103 car = Fbuffer_local_value (car, it->w->buffer);
17104 }
17105
17106 if (INTEGERP (car) || FLOATP (car))
17107 {
17108 double fact;
17109 pixels = XFLOATINT (car);
17110 if (NILP (cdr))
17111 return OK_PIXELS (pixels);
17112 if (calc_pixel_width_or_height (&fact, it, cdr,
17113 font, width_p, align_to))
17114 return OK_PIXELS (pixels * fact);
17115 return 0;
17116 }
17117
17118 return 0;
17119 }
17120
17121 return 0;
17122 }
17123
17124 \f
17125 /***********************************************************************
17126 Glyph Display
17127 ***********************************************************************/
17128
17129 #ifdef HAVE_WINDOW_SYSTEM
17130
17131 #if GLYPH_DEBUG
17132
17133 void
17134 dump_glyph_string (s)
17135 struct glyph_string *s;
17136 {
17137 fprintf (stderr, "glyph string\n");
17138 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17139 s->x, s->y, s->width, s->height);
17140 fprintf (stderr, " ybase = %d\n", s->ybase);
17141 fprintf (stderr, " hl = %d\n", s->hl);
17142 fprintf (stderr, " left overhang = %d, right = %d\n",
17143 s->left_overhang, s->right_overhang);
17144 fprintf (stderr, " nchars = %d\n", s->nchars);
17145 fprintf (stderr, " extends to end of line = %d\n",
17146 s->extends_to_end_of_line_p);
17147 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17148 fprintf (stderr, " bg width = %d\n", s->background_width);
17149 }
17150
17151 #endif /* GLYPH_DEBUG */
17152
17153 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17154 of XChar2b structures for S; it can't be allocated in
17155 init_glyph_string because it must be allocated via `alloca'. W
17156 is the window on which S is drawn. ROW and AREA are the glyph row
17157 and area within the row from which S is constructed. START is the
17158 index of the first glyph structure covered by S. HL is a
17159 face-override for drawing S. */
17160
17161 #ifdef HAVE_NTGUI
17162 #define OPTIONAL_HDC(hdc) hdc,
17163 #define DECLARE_HDC(hdc) HDC hdc;
17164 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17165 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17166 #endif
17167
17168 #ifndef OPTIONAL_HDC
17169 #define OPTIONAL_HDC(hdc)
17170 #define DECLARE_HDC(hdc)
17171 #define ALLOCATE_HDC(hdc, f)
17172 #define RELEASE_HDC(hdc, f)
17173 #endif
17174
17175 static void
17176 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17177 struct glyph_string *s;
17178 DECLARE_HDC (hdc)
17179 XChar2b *char2b;
17180 struct window *w;
17181 struct glyph_row *row;
17182 enum glyph_row_area area;
17183 int start;
17184 enum draw_glyphs_face hl;
17185 {
17186 bzero (s, sizeof *s);
17187 s->w = w;
17188 s->f = XFRAME (w->frame);
17189 #ifdef HAVE_NTGUI
17190 s->hdc = hdc;
17191 #endif
17192 s->display = FRAME_X_DISPLAY (s->f);
17193 s->window = FRAME_X_WINDOW (s->f);
17194 s->char2b = char2b;
17195 s->hl = hl;
17196 s->row = row;
17197 s->area = area;
17198 s->first_glyph = row->glyphs[area] + start;
17199 s->height = row->height;
17200 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17201
17202 /* Display the internal border below the tool-bar window. */
17203 if (s->w == XWINDOW (s->f->tool_bar_window))
17204 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17205
17206 s->ybase = s->y + row->ascent;
17207 }
17208
17209
17210 /* Append the list of glyph strings with head H and tail T to the list
17211 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17212
17213 static INLINE void
17214 append_glyph_string_lists (head, tail, h, t)
17215 struct glyph_string **head, **tail;
17216 struct glyph_string *h, *t;
17217 {
17218 if (h)
17219 {
17220 if (*head)
17221 (*tail)->next = h;
17222 else
17223 *head = h;
17224 h->prev = *tail;
17225 *tail = t;
17226 }
17227 }
17228
17229
17230 /* Prepend the list of glyph strings with head H and tail T to the
17231 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17232 result. */
17233
17234 static INLINE void
17235 prepend_glyph_string_lists (head, tail, h, t)
17236 struct glyph_string **head, **tail;
17237 struct glyph_string *h, *t;
17238 {
17239 if (h)
17240 {
17241 if (*head)
17242 (*head)->prev = t;
17243 else
17244 *tail = t;
17245 t->next = *head;
17246 *head = h;
17247 }
17248 }
17249
17250
17251 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17252 Set *HEAD and *TAIL to the resulting list. */
17253
17254 static INLINE void
17255 append_glyph_string (head, tail, s)
17256 struct glyph_string **head, **tail;
17257 struct glyph_string *s;
17258 {
17259 s->next = s->prev = NULL;
17260 append_glyph_string_lists (head, tail, s, s);
17261 }
17262
17263
17264 /* Get face and two-byte form of character glyph GLYPH on frame F.
17265 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17266 a pointer to a realized face that is ready for display. */
17267
17268 static INLINE struct face *
17269 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17270 struct frame *f;
17271 struct glyph *glyph;
17272 XChar2b *char2b;
17273 int *two_byte_p;
17274 {
17275 struct face *face;
17276
17277 xassert (glyph->type == CHAR_GLYPH);
17278 face = FACE_FROM_ID (f, glyph->face_id);
17279
17280 if (two_byte_p)
17281 *two_byte_p = 0;
17282
17283 if (!glyph->multibyte_p)
17284 {
17285 /* Unibyte case. We don't have to encode, but we have to make
17286 sure to use a face suitable for unibyte. */
17287 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17288 }
17289 else if (glyph->u.ch < 128
17290 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17291 {
17292 /* Case of ASCII in a face known to fit ASCII. */
17293 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17294 }
17295 else
17296 {
17297 int c1, c2, charset;
17298
17299 /* Split characters into bytes. If c2 is -1 afterwards, C is
17300 really a one-byte character so that byte1 is zero. */
17301 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17302 if (c2 > 0)
17303 STORE_XCHAR2B (char2b, c1, c2);
17304 else
17305 STORE_XCHAR2B (char2b, 0, c1);
17306
17307 /* Maybe encode the character in *CHAR2B. */
17308 if (charset != CHARSET_ASCII)
17309 {
17310 struct font_info *font_info
17311 = FONT_INFO_FROM_ID (f, face->font_info_id);
17312 if (font_info)
17313 glyph->font_type
17314 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17315 }
17316 }
17317
17318 /* Make sure X resources of the face are allocated. */
17319 xassert (face != NULL);
17320 PREPARE_FACE_FOR_DISPLAY (f, face);
17321 return face;
17322 }
17323
17324
17325 /* Fill glyph string S with composition components specified by S->cmp.
17326
17327 FACES is an array of faces for all components of this composition.
17328 S->gidx is the index of the first component for S.
17329 OVERLAPS_P non-zero means S should draw the foreground only, and
17330 use its physical height for clipping.
17331
17332 Value is the index of a component not in S. */
17333
17334 static int
17335 fill_composite_glyph_string (s, faces, overlaps_p)
17336 struct glyph_string *s;
17337 struct face **faces;
17338 int overlaps_p;
17339 {
17340 int i;
17341
17342 xassert (s);
17343
17344 s->for_overlaps_p = overlaps_p;
17345
17346 s->face = faces[s->gidx];
17347 s->font = s->face->font;
17348 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17349
17350 /* For all glyphs of this composition, starting at the offset
17351 S->gidx, until we reach the end of the definition or encounter a
17352 glyph that requires the different face, add it to S. */
17353 ++s->nchars;
17354 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17355 ++s->nchars;
17356
17357 /* All glyph strings for the same composition has the same width,
17358 i.e. the width set for the first component of the composition. */
17359
17360 s->width = s->first_glyph->pixel_width;
17361
17362 /* If the specified font could not be loaded, use the frame's
17363 default font, but record the fact that we couldn't load it in
17364 the glyph string so that we can draw rectangles for the
17365 characters of the glyph string. */
17366 if (s->font == NULL)
17367 {
17368 s->font_not_found_p = 1;
17369 s->font = FRAME_FONT (s->f);
17370 }
17371
17372 /* Adjust base line for subscript/superscript text. */
17373 s->ybase += s->first_glyph->voffset;
17374
17375 xassert (s->face && s->face->gc);
17376
17377 /* This glyph string must always be drawn with 16-bit functions. */
17378 s->two_byte_p = 1;
17379
17380 return s->gidx + s->nchars;
17381 }
17382
17383
17384 /* Fill glyph string S from a sequence of character glyphs.
17385
17386 FACE_ID is the face id of the string. START is the index of the
17387 first glyph to consider, END is the index of the last + 1.
17388 OVERLAPS_P non-zero means S should draw the foreground only, and
17389 use its physical height for clipping.
17390
17391 Value is the index of the first glyph not in S. */
17392
17393 static int
17394 fill_glyph_string (s, face_id, start, end, overlaps_p)
17395 struct glyph_string *s;
17396 int face_id;
17397 int start, end, overlaps_p;
17398 {
17399 struct glyph *glyph, *last;
17400 int voffset;
17401 int glyph_not_available_p;
17402
17403 xassert (s->f == XFRAME (s->w->frame));
17404 xassert (s->nchars == 0);
17405 xassert (start >= 0 && end > start);
17406
17407 s->for_overlaps_p = overlaps_p,
17408 glyph = s->row->glyphs[s->area] + start;
17409 last = s->row->glyphs[s->area] + end;
17410 voffset = glyph->voffset;
17411
17412 glyph_not_available_p = glyph->glyph_not_available_p;
17413
17414 while (glyph < last
17415 && glyph->type == CHAR_GLYPH
17416 && glyph->voffset == voffset
17417 /* Same face id implies same font, nowadays. */
17418 && glyph->face_id == face_id
17419 && glyph->glyph_not_available_p == glyph_not_available_p)
17420 {
17421 int two_byte_p;
17422
17423 s->face = get_glyph_face_and_encoding (s->f, glyph,
17424 s->char2b + s->nchars,
17425 &two_byte_p);
17426 s->two_byte_p = two_byte_p;
17427 ++s->nchars;
17428 xassert (s->nchars <= end - start);
17429 s->width += glyph->pixel_width;
17430 ++glyph;
17431 }
17432
17433 s->font = s->face->font;
17434 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17435
17436 /* If the specified font could not be loaded, use the frame's font,
17437 but record the fact that we couldn't load it in
17438 S->font_not_found_p so that we can draw rectangles for the
17439 characters of the glyph string. */
17440 if (s->font == NULL || glyph_not_available_p)
17441 {
17442 s->font_not_found_p = 1;
17443 s->font = FRAME_FONT (s->f);
17444 }
17445
17446 /* Adjust base line for subscript/superscript text. */
17447 s->ybase += voffset;
17448
17449 xassert (s->face && s->face->gc);
17450 return glyph - s->row->glyphs[s->area];
17451 }
17452
17453
17454 /* Fill glyph string S from image glyph S->first_glyph. */
17455
17456 static void
17457 fill_image_glyph_string (s)
17458 struct glyph_string *s;
17459 {
17460 xassert (s->first_glyph->type == IMAGE_GLYPH);
17461 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17462 xassert (s->img);
17463 s->slice = s->first_glyph->slice;
17464 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17465 s->font = s->face->font;
17466 s->width = s->first_glyph->pixel_width;
17467
17468 /* Adjust base line for subscript/superscript text. */
17469 s->ybase += s->first_glyph->voffset;
17470 }
17471
17472
17473 /* Fill glyph string S from a sequence of stretch glyphs.
17474
17475 ROW is the glyph row in which the glyphs are found, AREA is the
17476 area within the row. START is the index of the first glyph to
17477 consider, END is the index of the last + 1.
17478
17479 Value is the index of the first glyph not in S. */
17480
17481 static int
17482 fill_stretch_glyph_string (s, row, area, start, end)
17483 struct glyph_string *s;
17484 struct glyph_row *row;
17485 enum glyph_row_area area;
17486 int start, end;
17487 {
17488 struct glyph *glyph, *last;
17489 int voffset, face_id;
17490
17491 xassert (s->first_glyph->type == STRETCH_GLYPH);
17492
17493 glyph = s->row->glyphs[s->area] + start;
17494 last = s->row->glyphs[s->area] + end;
17495 face_id = glyph->face_id;
17496 s->face = FACE_FROM_ID (s->f, face_id);
17497 s->font = s->face->font;
17498 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17499 s->width = glyph->pixel_width;
17500 voffset = glyph->voffset;
17501
17502 for (++glyph;
17503 (glyph < last
17504 && glyph->type == STRETCH_GLYPH
17505 && glyph->voffset == voffset
17506 && glyph->face_id == face_id);
17507 ++glyph)
17508 s->width += glyph->pixel_width;
17509
17510 /* Adjust base line for subscript/superscript text. */
17511 s->ybase += voffset;
17512
17513 /* The case that face->gc == 0 is handled when drawing the glyph
17514 string by calling PREPARE_FACE_FOR_DISPLAY. */
17515 xassert (s->face);
17516 return glyph - s->row->glyphs[s->area];
17517 }
17518
17519
17520 /* EXPORT for RIF:
17521 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17522 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17523 assumed to be zero. */
17524
17525 void
17526 x_get_glyph_overhangs (glyph, f, left, right)
17527 struct glyph *glyph;
17528 struct frame *f;
17529 int *left, *right;
17530 {
17531 *left = *right = 0;
17532
17533 if (glyph->type == CHAR_GLYPH)
17534 {
17535 XFontStruct *font;
17536 struct face *face;
17537 struct font_info *font_info;
17538 XChar2b char2b;
17539 XCharStruct *pcm;
17540
17541 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17542 font = face->font;
17543 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17544 if (font /* ++KFS: Should this be font_info ? */
17545 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17546 {
17547 if (pcm->rbearing > pcm->width)
17548 *right = pcm->rbearing - pcm->width;
17549 if (pcm->lbearing < 0)
17550 *left = -pcm->lbearing;
17551 }
17552 }
17553 }
17554
17555
17556 /* Return the index of the first glyph preceding glyph string S that
17557 is overwritten by S because of S's left overhang. Value is -1
17558 if no glyphs are overwritten. */
17559
17560 static int
17561 left_overwritten (s)
17562 struct glyph_string *s;
17563 {
17564 int k;
17565
17566 if (s->left_overhang)
17567 {
17568 int x = 0, i;
17569 struct glyph *glyphs = s->row->glyphs[s->area];
17570 int first = s->first_glyph - glyphs;
17571
17572 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17573 x -= glyphs[i].pixel_width;
17574
17575 k = i + 1;
17576 }
17577 else
17578 k = -1;
17579
17580 return k;
17581 }
17582
17583
17584 /* Return the index of the first glyph preceding glyph string S that
17585 is overwriting S because of its right overhang. Value is -1 if no
17586 glyph in front of S overwrites S. */
17587
17588 static int
17589 left_overwriting (s)
17590 struct glyph_string *s;
17591 {
17592 int i, k, x;
17593 struct glyph *glyphs = s->row->glyphs[s->area];
17594 int first = s->first_glyph - glyphs;
17595
17596 k = -1;
17597 x = 0;
17598 for (i = first - 1; i >= 0; --i)
17599 {
17600 int left, right;
17601 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17602 if (x + right > 0)
17603 k = i;
17604 x -= glyphs[i].pixel_width;
17605 }
17606
17607 return k;
17608 }
17609
17610
17611 /* Return the index of the last glyph following glyph string S that is
17612 not overwritten by S because of S's right overhang. Value is -1 if
17613 no such glyph is found. */
17614
17615 static int
17616 right_overwritten (s)
17617 struct glyph_string *s;
17618 {
17619 int k = -1;
17620
17621 if (s->right_overhang)
17622 {
17623 int x = 0, i;
17624 struct glyph *glyphs = s->row->glyphs[s->area];
17625 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17626 int end = s->row->used[s->area];
17627
17628 for (i = first; i < end && s->right_overhang > x; ++i)
17629 x += glyphs[i].pixel_width;
17630
17631 k = i;
17632 }
17633
17634 return k;
17635 }
17636
17637
17638 /* Return the index of the last glyph following glyph string S that
17639 overwrites S because of its left overhang. Value is negative
17640 if no such glyph is found. */
17641
17642 static int
17643 right_overwriting (s)
17644 struct glyph_string *s;
17645 {
17646 int i, k, x;
17647 int end = s->row->used[s->area];
17648 struct glyph *glyphs = s->row->glyphs[s->area];
17649 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17650
17651 k = -1;
17652 x = 0;
17653 for (i = first; i < end; ++i)
17654 {
17655 int left, right;
17656 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17657 if (x - left < 0)
17658 k = i;
17659 x += glyphs[i].pixel_width;
17660 }
17661
17662 return k;
17663 }
17664
17665
17666 /* Get face and two-byte form of character C in face FACE_ID on frame
17667 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17668 means we want to display multibyte text. DISPLAY_P non-zero means
17669 make sure that X resources for the face returned are allocated.
17670 Value is a pointer to a realized face that is ready for display if
17671 DISPLAY_P is non-zero. */
17672
17673 static INLINE struct face *
17674 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17675 struct frame *f;
17676 int c, face_id;
17677 XChar2b *char2b;
17678 int multibyte_p, display_p;
17679 {
17680 struct face *face = FACE_FROM_ID (f, face_id);
17681
17682 if (!multibyte_p)
17683 {
17684 /* Unibyte case. We don't have to encode, but we have to make
17685 sure to use a face suitable for unibyte. */
17686 STORE_XCHAR2B (char2b, 0, c);
17687 face_id = FACE_FOR_CHAR (f, face, c);
17688 face = FACE_FROM_ID (f, face_id);
17689 }
17690 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17691 {
17692 /* Case of ASCII in a face known to fit ASCII. */
17693 STORE_XCHAR2B (char2b, 0, c);
17694 }
17695 else
17696 {
17697 int c1, c2, charset;
17698
17699 /* Split characters into bytes. If c2 is -1 afterwards, C is
17700 really a one-byte character so that byte1 is zero. */
17701 SPLIT_CHAR (c, charset, c1, c2);
17702 if (c2 > 0)
17703 STORE_XCHAR2B (char2b, c1, c2);
17704 else
17705 STORE_XCHAR2B (char2b, 0, c1);
17706
17707 /* Maybe encode the character in *CHAR2B. */
17708 if (face->font != NULL)
17709 {
17710 struct font_info *font_info
17711 = FONT_INFO_FROM_ID (f, face->font_info_id);
17712 if (font_info)
17713 rif->encode_char (c, char2b, font_info, 0);
17714 }
17715 }
17716
17717 /* Make sure X resources of the face are allocated. */
17718 #ifdef HAVE_X_WINDOWS
17719 if (display_p)
17720 #endif
17721 {
17722 xassert (face != NULL);
17723 PREPARE_FACE_FOR_DISPLAY (f, face);
17724 }
17725
17726 return face;
17727 }
17728
17729
17730 /* Set background width of glyph string S. START is the index of the
17731 first glyph following S. LAST_X is the right-most x-position + 1
17732 in the drawing area. */
17733
17734 static INLINE void
17735 set_glyph_string_background_width (s, start, last_x)
17736 struct glyph_string *s;
17737 int start;
17738 int last_x;
17739 {
17740 /* If the face of this glyph string has to be drawn to the end of
17741 the drawing area, set S->extends_to_end_of_line_p. */
17742 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17743
17744 if (start == s->row->used[s->area]
17745 && s->area == TEXT_AREA
17746 && ((s->hl == DRAW_NORMAL_TEXT
17747 && (s->row->fill_line_p
17748 || s->face->background != default_face->background
17749 || s->face->stipple != default_face->stipple
17750 || s->row->mouse_face_p))
17751 || s->hl == DRAW_MOUSE_FACE
17752 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17753 && s->row->fill_line_p)))
17754 s->extends_to_end_of_line_p = 1;
17755
17756 /* If S extends its face to the end of the line, set its
17757 background_width to the distance to the right edge of the drawing
17758 area. */
17759 if (s->extends_to_end_of_line_p)
17760 s->background_width = last_x - s->x + 1;
17761 else
17762 s->background_width = s->width;
17763 }
17764
17765
17766 /* Compute overhangs and x-positions for glyph string S and its
17767 predecessors, or successors. X is the starting x-position for S.
17768 BACKWARD_P non-zero means process predecessors. */
17769
17770 static void
17771 compute_overhangs_and_x (s, x, backward_p)
17772 struct glyph_string *s;
17773 int x;
17774 int backward_p;
17775 {
17776 if (backward_p)
17777 {
17778 while (s)
17779 {
17780 if (rif->compute_glyph_string_overhangs)
17781 rif->compute_glyph_string_overhangs (s);
17782 x -= s->width;
17783 s->x = x;
17784 s = s->prev;
17785 }
17786 }
17787 else
17788 {
17789 while (s)
17790 {
17791 if (rif->compute_glyph_string_overhangs)
17792 rif->compute_glyph_string_overhangs (s);
17793 s->x = x;
17794 x += s->width;
17795 s = s->next;
17796 }
17797 }
17798 }
17799
17800
17801
17802 /* The following macros are only called from draw_glyphs below.
17803 They reference the following parameters of that function directly:
17804 `w', `row', `area', and `overlap_p'
17805 as well as the following local variables:
17806 `s', `f', and `hdc' (in W32) */
17807
17808 #ifdef HAVE_NTGUI
17809 /* On W32, silently add local `hdc' variable to argument list of
17810 init_glyph_string. */
17811 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17812 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17813 #else
17814 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17815 init_glyph_string (s, char2b, w, row, area, start, hl)
17816 #endif
17817
17818 /* Add a glyph string for a stretch glyph to the list of strings
17819 between HEAD and TAIL. START is the index of the stretch glyph in
17820 row area AREA of glyph row ROW. END is the index of the last glyph
17821 in that glyph row area. X is the current output position assigned
17822 to the new glyph string constructed. HL overrides that face of the
17823 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17824 is the right-most x-position of the drawing area. */
17825
17826 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17827 and below -- keep them on one line. */
17828 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17829 do \
17830 { \
17831 s = (struct glyph_string *) alloca (sizeof *s); \
17832 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17833 START = fill_stretch_glyph_string (s, row, area, START, END); \
17834 append_glyph_string (&HEAD, &TAIL, s); \
17835 s->x = (X); \
17836 } \
17837 while (0)
17838
17839
17840 /* Add a glyph string for an image glyph to the list of strings
17841 between HEAD and TAIL. START is the index of the image glyph in
17842 row area AREA of glyph row ROW. END is the index of the last glyph
17843 in that glyph row area. X is the current output position assigned
17844 to the new glyph string constructed. HL overrides that face of the
17845 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17846 is the right-most x-position of the drawing area. */
17847
17848 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17849 do \
17850 { \
17851 s = (struct glyph_string *) alloca (sizeof *s); \
17852 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17853 fill_image_glyph_string (s); \
17854 append_glyph_string (&HEAD, &TAIL, s); \
17855 ++START; \
17856 s->x = (X); \
17857 } \
17858 while (0)
17859
17860
17861 /* Add a glyph string for a sequence of character glyphs to the list
17862 of strings between HEAD and TAIL. START is the index of the first
17863 glyph in row area AREA of glyph row ROW that is part of the new
17864 glyph string. END is the index of the last glyph in that glyph row
17865 area. X is the current output position assigned to the new glyph
17866 string constructed. HL overrides that face of the glyph; e.g. it
17867 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17868 right-most x-position of the drawing area. */
17869
17870 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17871 do \
17872 { \
17873 int c, face_id; \
17874 XChar2b *char2b; \
17875 \
17876 c = (row)->glyphs[area][START].u.ch; \
17877 face_id = (row)->glyphs[area][START].face_id; \
17878 \
17879 s = (struct glyph_string *) alloca (sizeof *s); \
17880 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17881 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17882 append_glyph_string (&HEAD, &TAIL, s); \
17883 s->x = (X); \
17884 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17885 } \
17886 while (0)
17887
17888
17889 /* Add a glyph string for a composite sequence to the list of strings
17890 between HEAD and TAIL. START is the index of the first glyph in
17891 row area AREA of glyph row ROW that is part of the new glyph
17892 string. END is the index of the last glyph in that glyph row area.
17893 X is the current output position assigned to the new glyph string
17894 constructed. HL overrides that face of the glyph; e.g. it is
17895 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17896 x-position of the drawing area. */
17897
17898 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17899 do { \
17900 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17901 int face_id = (row)->glyphs[area][START].face_id; \
17902 struct face *base_face = FACE_FROM_ID (f, face_id); \
17903 struct composition *cmp = composition_table[cmp_id]; \
17904 int glyph_len = cmp->glyph_len; \
17905 XChar2b *char2b; \
17906 struct face **faces; \
17907 struct glyph_string *first_s = NULL; \
17908 int n; \
17909 \
17910 base_face = base_face->ascii_face; \
17911 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17912 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17913 /* At first, fill in `char2b' and `faces'. */ \
17914 for (n = 0; n < glyph_len; n++) \
17915 { \
17916 int c = COMPOSITION_GLYPH (cmp, n); \
17917 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17918 faces[n] = FACE_FROM_ID (f, this_face_id); \
17919 get_char_face_and_encoding (f, c, this_face_id, \
17920 char2b + n, 1, 1); \
17921 } \
17922 \
17923 /* Make glyph_strings for each glyph sequence that is drawable by \
17924 the same face, and append them to HEAD/TAIL. */ \
17925 for (n = 0; n < cmp->glyph_len;) \
17926 { \
17927 s = (struct glyph_string *) alloca (sizeof *s); \
17928 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17929 append_glyph_string (&(HEAD), &(TAIL), s); \
17930 s->cmp = cmp; \
17931 s->gidx = n; \
17932 s->x = (X); \
17933 \
17934 if (n == 0) \
17935 first_s = s; \
17936 \
17937 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17938 } \
17939 \
17940 ++START; \
17941 s = first_s; \
17942 } while (0)
17943
17944
17945 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17946 of AREA of glyph row ROW on window W between indices START and END.
17947 HL overrides the face for drawing glyph strings, e.g. it is
17948 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17949 x-positions of the drawing area.
17950
17951 This is an ugly monster macro construct because we must use alloca
17952 to allocate glyph strings (because draw_glyphs can be called
17953 asynchronously). */
17954
17955 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17956 do \
17957 { \
17958 HEAD = TAIL = NULL; \
17959 while (START < END) \
17960 { \
17961 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17962 switch (first_glyph->type) \
17963 { \
17964 case CHAR_GLYPH: \
17965 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17966 HL, X, LAST_X); \
17967 break; \
17968 \
17969 case COMPOSITE_GLYPH: \
17970 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17971 HL, X, LAST_X); \
17972 break; \
17973 \
17974 case STRETCH_GLYPH: \
17975 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17976 HL, X, LAST_X); \
17977 break; \
17978 \
17979 case IMAGE_GLYPH: \
17980 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17981 HL, X, LAST_X); \
17982 break; \
17983 \
17984 default: \
17985 abort (); \
17986 } \
17987 \
17988 set_glyph_string_background_width (s, START, LAST_X); \
17989 (X) += s->width; \
17990 } \
17991 } \
17992 while (0)
17993
17994
17995 /* Draw glyphs between START and END in AREA of ROW on window W,
17996 starting at x-position X. X is relative to AREA in W. HL is a
17997 face-override with the following meaning:
17998
17999 DRAW_NORMAL_TEXT draw normally
18000 DRAW_CURSOR draw in cursor face
18001 DRAW_MOUSE_FACE draw in mouse face.
18002 DRAW_INVERSE_VIDEO draw in mode line face
18003 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18004 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18005
18006 If OVERLAPS_P is non-zero, draw only the foreground of characters
18007 and clip to the physical height of ROW.
18008
18009 Value is the x-position reached, relative to AREA of W. */
18010
18011 static int
18012 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18013 struct window *w;
18014 int x;
18015 struct glyph_row *row;
18016 enum glyph_row_area area;
18017 int start, end;
18018 enum draw_glyphs_face hl;
18019 int overlaps_p;
18020 {
18021 struct glyph_string *head, *tail;
18022 struct glyph_string *s;
18023 int last_x, area_width;
18024 int x_reached;
18025 int i, j;
18026 struct frame *f = XFRAME (WINDOW_FRAME (w));
18027 DECLARE_HDC (hdc);
18028
18029 ALLOCATE_HDC (hdc, f);
18030
18031 /* Let's rather be paranoid than getting a SEGV. */
18032 end = min (end, row->used[area]);
18033 start = max (0, start);
18034 start = min (end, start);
18035
18036 /* Translate X to frame coordinates. Set last_x to the right
18037 end of the drawing area. */
18038 if (row->full_width_p)
18039 {
18040 /* X is relative to the left edge of W, without scroll bars
18041 or fringes. */
18042 x += WINDOW_LEFT_EDGE_X (w);
18043 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18044 }
18045 else
18046 {
18047 int area_left = window_box_left (w, area);
18048 x += area_left;
18049 area_width = window_box_width (w, area);
18050 last_x = area_left + area_width;
18051 }
18052
18053 /* Build a doubly-linked list of glyph_string structures between
18054 head and tail from what we have to draw. Note that the macro
18055 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18056 the reason we use a separate variable `i'. */
18057 i = start;
18058 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18059 if (tail)
18060 x_reached = tail->x + tail->background_width;
18061 else
18062 x_reached = x;
18063
18064 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18065 the row, redraw some glyphs in front or following the glyph
18066 strings built above. */
18067 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18068 {
18069 int dummy_x = 0;
18070 struct glyph_string *h, *t;
18071
18072 /* Compute overhangs for all glyph strings. */
18073 if (rif->compute_glyph_string_overhangs)
18074 for (s = head; s; s = s->next)
18075 rif->compute_glyph_string_overhangs (s);
18076
18077 /* Prepend glyph strings for glyphs in front of the first glyph
18078 string that are overwritten because of the first glyph
18079 string's left overhang. The background of all strings
18080 prepended must be drawn because the first glyph string
18081 draws over it. */
18082 i = left_overwritten (head);
18083 if (i >= 0)
18084 {
18085 j = i;
18086 BUILD_GLYPH_STRINGS (j, start, h, t,
18087 DRAW_NORMAL_TEXT, dummy_x, last_x);
18088 start = i;
18089 compute_overhangs_and_x (t, head->x, 1);
18090 prepend_glyph_string_lists (&head, &tail, h, t);
18091 }
18092
18093 /* Prepend glyph strings for glyphs in front of the first glyph
18094 string that overwrite that glyph string because of their
18095 right overhang. For these strings, only the foreground must
18096 be drawn, because it draws over the glyph string at `head'.
18097 The background must not be drawn because this would overwrite
18098 right overhangs of preceding glyphs for which no glyph
18099 strings exist. */
18100 i = left_overwriting (head);
18101 if (i >= 0)
18102 {
18103 BUILD_GLYPH_STRINGS (i, start, h, t,
18104 DRAW_NORMAL_TEXT, dummy_x, last_x);
18105 for (s = h; s; s = s->next)
18106 s->background_filled_p = 1;
18107 compute_overhangs_and_x (t, head->x, 1);
18108 prepend_glyph_string_lists (&head, &tail, h, t);
18109 }
18110
18111 /* Append glyphs strings for glyphs following the last glyph
18112 string tail that are overwritten by tail. The background of
18113 these strings has to be drawn because tail's foreground draws
18114 over it. */
18115 i = right_overwritten (tail);
18116 if (i >= 0)
18117 {
18118 BUILD_GLYPH_STRINGS (end, i, h, t,
18119 DRAW_NORMAL_TEXT, x, last_x);
18120 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18121 append_glyph_string_lists (&head, &tail, h, t);
18122 }
18123
18124 /* Append glyph strings for glyphs following the last glyph
18125 string tail that overwrite tail. The foreground of such
18126 glyphs has to be drawn because it writes into the background
18127 of tail. The background must not be drawn because it could
18128 paint over the foreground of following glyphs. */
18129 i = right_overwriting (tail);
18130 if (i >= 0)
18131 {
18132 BUILD_GLYPH_STRINGS (end, i, h, t,
18133 DRAW_NORMAL_TEXT, x, last_x);
18134 for (s = h; s; s = s->next)
18135 s->background_filled_p = 1;
18136 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18137 append_glyph_string_lists (&head, &tail, h, t);
18138 }
18139 }
18140
18141 /* Draw all strings. */
18142 for (s = head; s; s = s->next)
18143 rif->draw_glyph_string (s);
18144
18145 if (area == TEXT_AREA
18146 && !row->full_width_p
18147 /* When drawing overlapping rows, only the glyph strings'
18148 foreground is drawn, which doesn't erase a cursor
18149 completely. */
18150 && !overlaps_p)
18151 {
18152 int x0 = head ? head->x : x;
18153 int x1 = tail ? tail->x + tail->background_width : x;
18154
18155 int text_left = window_box_left (w, TEXT_AREA);
18156 x0 -= text_left;
18157 x1 -= text_left;
18158
18159 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18160 row->y, MATRIX_ROW_BOTTOM_Y (row));
18161 }
18162
18163 /* Value is the x-position up to which drawn, relative to AREA of W.
18164 This doesn't include parts drawn because of overhangs. */
18165 if (row->full_width_p)
18166 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18167 else
18168 x_reached -= window_box_left (w, area);
18169
18170 RELEASE_HDC (hdc, f);
18171
18172 return x_reached;
18173 }
18174
18175
18176 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18177 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18178
18179 static INLINE void
18180 append_glyph (it)
18181 struct it *it;
18182 {
18183 struct glyph *glyph;
18184 enum glyph_row_area area = it->area;
18185
18186 xassert (it->glyph_row);
18187 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18188
18189 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18190 if (glyph < it->glyph_row->glyphs[area + 1])
18191 {
18192 glyph->charpos = CHARPOS (it->position);
18193 glyph->object = it->object;
18194 glyph->pixel_width = it->pixel_width;
18195 glyph->ascent = it->ascent;
18196 glyph->descent = it->descent;
18197 glyph->voffset = it->voffset;
18198 glyph->type = CHAR_GLYPH;
18199 glyph->multibyte_p = it->multibyte_p;
18200 glyph->left_box_line_p = it->start_of_box_run_p;
18201 glyph->right_box_line_p = it->end_of_box_run_p;
18202 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18203 || it->phys_descent > it->descent);
18204 glyph->padding_p = 0;
18205 glyph->glyph_not_available_p = it->glyph_not_available_p;
18206 glyph->face_id = it->face_id;
18207 glyph->u.ch = it->char_to_display;
18208 glyph->slice = null_glyph_slice;
18209 glyph->font_type = FONT_TYPE_UNKNOWN;
18210 ++it->glyph_row->used[area];
18211 }
18212 else if (!fonts_changed_p)
18213 {
18214 it->w->ncols_scale_factor++;
18215 fonts_changed_p = 1;
18216 }
18217 }
18218
18219 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18220 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18221
18222 static INLINE void
18223 append_composite_glyph (it)
18224 struct it *it;
18225 {
18226 struct glyph *glyph;
18227 enum glyph_row_area area = it->area;
18228
18229 xassert (it->glyph_row);
18230
18231 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18232 if (glyph < it->glyph_row->glyphs[area + 1])
18233 {
18234 glyph->charpos = CHARPOS (it->position);
18235 glyph->object = it->object;
18236 glyph->pixel_width = it->pixel_width;
18237 glyph->ascent = it->ascent;
18238 glyph->descent = it->descent;
18239 glyph->voffset = it->voffset;
18240 glyph->type = COMPOSITE_GLYPH;
18241 glyph->multibyte_p = it->multibyte_p;
18242 glyph->left_box_line_p = it->start_of_box_run_p;
18243 glyph->right_box_line_p = it->end_of_box_run_p;
18244 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18245 || it->phys_descent > it->descent);
18246 glyph->padding_p = 0;
18247 glyph->glyph_not_available_p = 0;
18248 glyph->face_id = it->face_id;
18249 glyph->u.cmp_id = it->cmp_id;
18250 glyph->slice = null_glyph_slice;
18251 glyph->font_type = FONT_TYPE_UNKNOWN;
18252 ++it->glyph_row->used[area];
18253 }
18254 else if (!fonts_changed_p)
18255 {
18256 it->w->ncols_scale_factor++;
18257 fonts_changed_p = 1;
18258 }
18259 }
18260
18261
18262 /* Change IT->ascent and IT->height according to the setting of
18263 IT->voffset. */
18264
18265 static INLINE void
18266 take_vertical_position_into_account (it)
18267 struct it *it;
18268 {
18269 if (it->voffset)
18270 {
18271 if (it->voffset < 0)
18272 /* Increase the ascent so that we can display the text higher
18273 in the line. */
18274 it->ascent -= it->voffset;
18275 else
18276 /* Increase the descent so that we can display the text lower
18277 in the line. */
18278 it->descent += it->voffset;
18279 }
18280 }
18281
18282
18283 /* Produce glyphs/get display metrics for the image IT is loaded with.
18284 See the description of struct display_iterator in dispextern.h for
18285 an overview of struct display_iterator. */
18286
18287 static void
18288 produce_image_glyph (it)
18289 struct it *it;
18290 {
18291 struct image *img;
18292 struct face *face;
18293 int face_ascent, glyph_ascent;
18294 struct glyph_slice slice;
18295
18296 xassert (it->what == IT_IMAGE);
18297
18298 face = FACE_FROM_ID (it->f, it->face_id);
18299 xassert (face);
18300 /* Make sure X resources of the face is loaded. */
18301 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18302
18303 if (it->image_id < 0)
18304 {
18305 /* Fringe bitmap. */
18306 it->ascent = it->phys_ascent = 0;
18307 it->descent = it->phys_descent = 0;
18308 it->pixel_width = 0;
18309 it->nglyphs = 0;
18310 return;
18311 }
18312
18313 img = IMAGE_FROM_ID (it->f, it->image_id);
18314 xassert (img);
18315 /* Make sure X resources of the image is loaded. */
18316 prepare_image_for_display (it->f, img);
18317
18318 slice.x = slice.y = 0;
18319 slice.width = img->width;
18320 slice.height = img->height;
18321
18322 if (INTEGERP (it->slice.x))
18323 slice.x = XINT (it->slice.x);
18324 else if (FLOATP (it->slice.x))
18325 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18326
18327 if (INTEGERP (it->slice.y))
18328 slice.y = XINT (it->slice.y);
18329 else if (FLOATP (it->slice.y))
18330 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18331
18332 if (INTEGERP (it->slice.width))
18333 slice.width = XINT (it->slice.width);
18334 else if (FLOATP (it->slice.width))
18335 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18336
18337 if (INTEGERP (it->slice.height))
18338 slice.height = XINT (it->slice.height);
18339 else if (FLOATP (it->slice.height))
18340 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18341
18342 if (slice.x >= img->width)
18343 slice.x = img->width;
18344 if (slice.y >= img->height)
18345 slice.y = img->height;
18346 if (slice.x + slice.width >= img->width)
18347 slice.width = img->width - slice.x;
18348 if (slice.y + slice.height > img->height)
18349 slice.height = img->height - slice.y;
18350
18351 if (slice.width == 0 || slice.height == 0)
18352 return;
18353
18354 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18355
18356 it->descent = slice.height - glyph_ascent;
18357 if (slice.y == 0)
18358 it->descent += img->vmargin;
18359 if (slice.y + slice.height == img->height)
18360 it->descent += img->vmargin;
18361 it->phys_descent = it->descent;
18362
18363 it->pixel_width = slice.width;
18364 if (slice.x == 0)
18365 it->pixel_width += img->hmargin;
18366 if (slice.x + slice.width == img->width)
18367 it->pixel_width += img->hmargin;
18368
18369 /* It's quite possible for images to have an ascent greater than
18370 their height, so don't get confused in that case. */
18371 if (it->descent < 0)
18372 it->descent = 0;
18373
18374 #if 0 /* this breaks image tiling */
18375 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18376 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18377 if (face_ascent > it->ascent)
18378 it->ascent = it->phys_ascent = face_ascent;
18379 #endif
18380
18381 it->nglyphs = 1;
18382
18383 if (face->box != FACE_NO_BOX)
18384 {
18385 if (face->box_line_width > 0)
18386 {
18387 if (slice.y == 0)
18388 it->ascent += face->box_line_width;
18389 if (slice.y + slice.height == img->height)
18390 it->descent += face->box_line_width;
18391 }
18392
18393 if (it->start_of_box_run_p && slice.x == 0)
18394 it->pixel_width += abs (face->box_line_width);
18395 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18396 it->pixel_width += abs (face->box_line_width);
18397 }
18398
18399 take_vertical_position_into_account (it);
18400
18401 if (it->glyph_row)
18402 {
18403 struct glyph *glyph;
18404 enum glyph_row_area area = it->area;
18405
18406 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18407 if (glyph < it->glyph_row->glyphs[area + 1])
18408 {
18409 glyph->charpos = CHARPOS (it->position);
18410 glyph->object = it->object;
18411 glyph->pixel_width = it->pixel_width;
18412 glyph->ascent = glyph_ascent;
18413 glyph->descent = it->descent;
18414 glyph->voffset = it->voffset;
18415 glyph->type = IMAGE_GLYPH;
18416 glyph->multibyte_p = it->multibyte_p;
18417 glyph->left_box_line_p = it->start_of_box_run_p;
18418 glyph->right_box_line_p = it->end_of_box_run_p;
18419 glyph->overlaps_vertically_p = 0;
18420 glyph->padding_p = 0;
18421 glyph->glyph_not_available_p = 0;
18422 glyph->face_id = it->face_id;
18423 glyph->u.img_id = img->id;
18424 glyph->slice = slice;
18425 glyph->font_type = FONT_TYPE_UNKNOWN;
18426 ++it->glyph_row->used[area];
18427 }
18428 else if (!fonts_changed_p)
18429 {
18430 it->w->ncols_scale_factor++;
18431 fonts_changed_p = 1;
18432 }
18433 }
18434 }
18435
18436
18437 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18438 of the glyph, WIDTH and HEIGHT are the width and height of the
18439 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18440
18441 static void
18442 append_stretch_glyph (it, object, width, height, ascent)
18443 struct it *it;
18444 Lisp_Object object;
18445 int width, height;
18446 int ascent;
18447 {
18448 struct glyph *glyph;
18449 enum glyph_row_area area = it->area;
18450
18451 xassert (ascent >= 0 && ascent <= height);
18452
18453 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18454 if (glyph < it->glyph_row->glyphs[area + 1])
18455 {
18456 glyph->charpos = CHARPOS (it->position);
18457 glyph->object = object;
18458 glyph->pixel_width = width;
18459 glyph->ascent = ascent;
18460 glyph->descent = height - ascent;
18461 glyph->voffset = it->voffset;
18462 glyph->type = STRETCH_GLYPH;
18463 glyph->multibyte_p = it->multibyte_p;
18464 glyph->left_box_line_p = it->start_of_box_run_p;
18465 glyph->right_box_line_p = it->end_of_box_run_p;
18466 glyph->overlaps_vertically_p = 0;
18467 glyph->padding_p = 0;
18468 glyph->glyph_not_available_p = 0;
18469 glyph->face_id = it->face_id;
18470 glyph->u.stretch.ascent = ascent;
18471 glyph->u.stretch.height = height;
18472 glyph->slice = null_glyph_slice;
18473 glyph->font_type = FONT_TYPE_UNKNOWN;
18474 ++it->glyph_row->used[area];
18475 }
18476 else if (!fonts_changed_p)
18477 {
18478 it->w->ncols_scale_factor++;
18479 fonts_changed_p = 1;
18480 }
18481 }
18482
18483
18484 /* Produce a stretch glyph for iterator IT. IT->object is the value
18485 of the glyph property displayed. The value must be a list
18486 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18487 being recognized:
18488
18489 1. `:width WIDTH' specifies that the space should be WIDTH *
18490 canonical char width wide. WIDTH may be an integer or floating
18491 point number.
18492
18493 2. `:relative-width FACTOR' specifies that the width of the stretch
18494 should be computed from the width of the first character having the
18495 `glyph' property, and should be FACTOR times that width.
18496
18497 3. `:align-to HPOS' specifies that the space should be wide enough
18498 to reach HPOS, a value in canonical character units.
18499
18500 Exactly one of the above pairs must be present.
18501
18502 4. `:height HEIGHT' specifies that the height of the stretch produced
18503 should be HEIGHT, measured in canonical character units.
18504
18505 5. `:relative-height FACTOR' specifies that the height of the
18506 stretch should be FACTOR times the height of the characters having
18507 the glyph property.
18508
18509 Either none or exactly one of 4 or 5 must be present.
18510
18511 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18512 of the stretch should be used for the ascent of the stretch.
18513 ASCENT must be in the range 0 <= ASCENT <= 100. */
18514
18515 static void
18516 produce_stretch_glyph (it)
18517 struct it *it;
18518 {
18519 /* (space :width WIDTH :height HEIGHT ...) */
18520 Lisp_Object prop, plist;
18521 int width = 0, height = 0, align_to = -1;
18522 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18523 int ascent = 0;
18524 double tem;
18525 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18526 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18527
18528 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18529
18530 /* List should start with `space'. */
18531 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18532 plist = XCDR (it->object);
18533
18534 /* Compute the width of the stretch. */
18535 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18536 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18537 {
18538 /* Absolute width `:width WIDTH' specified and valid. */
18539 zero_width_ok_p = 1;
18540 width = (int)tem;
18541 }
18542 else if (prop = Fplist_get (plist, QCrelative_width),
18543 NUMVAL (prop) > 0)
18544 {
18545 /* Relative width `:relative-width FACTOR' specified and valid.
18546 Compute the width of the characters having the `glyph'
18547 property. */
18548 struct it it2;
18549 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18550
18551 it2 = *it;
18552 if (it->multibyte_p)
18553 {
18554 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18555 - IT_BYTEPOS (*it));
18556 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18557 }
18558 else
18559 it2.c = *p, it2.len = 1;
18560
18561 it2.glyph_row = NULL;
18562 it2.what = IT_CHARACTER;
18563 x_produce_glyphs (&it2);
18564 width = NUMVAL (prop) * it2.pixel_width;
18565 }
18566 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18567 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18568 {
18569 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18570 align_to = (align_to < 0
18571 ? 0
18572 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18573 else if (align_to < 0)
18574 align_to = window_box_left_offset (it->w, TEXT_AREA);
18575 width = max (0, (int)tem + align_to - it->current_x);
18576 zero_width_ok_p = 1;
18577 }
18578 else
18579 /* Nothing specified -> width defaults to canonical char width. */
18580 width = FRAME_COLUMN_WIDTH (it->f);
18581
18582 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18583 width = 1;
18584
18585 /* Compute height. */
18586 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18587 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18588 {
18589 height = (int)tem;
18590 zero_height_ok_p = 1;
18591 }
18592 else if (prop = Fplist_get (plist, QCrelative_height),
18593 NUMVAL (prop) > 0)
18594 height = FONT_HEIGHT (font) * NUMVAL (prop);
18595 else
18596 height = FONT_HEIGHT (font);
18597
18598 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18599 height = 1;
18600
18601 /* Compute percentage of height used for ascent. If
18602 `:ascent ASCENT' is present and valid, use that. Otherwise,
18603 derive the ascent from the font in use. */
18604 if (prop = Fplist_get (plist, QCascent),
18605 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18606 ascent = height * NUMVAL (prop) / 100.0;
18607 else if (!NILP (prop)
18608 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18609 ascent = min (max (0, (int)tem), height);
18610 else
18611 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18612
18613 if (width > 0 && height > 0 && it->glyph_row)
18614 {
18615 Lisp_Object object = it->stack[it->sp - 1].string;
18616 if (!STRINGP (object))
18617 object = it->w->buffer;
18618 append_stretch_glyph (it, object, width, height, ascent);
18619 }
18620
18621 it->pixel_width = width;
18622 it->ascent = it->phys_ascent = ascent;
18623 it->descent = it->phys_descent = height - it->ascent;
18624 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18625
18626 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18627 {
18628 if (face->box_line_width > 0)
18629 {
18630 it->ascent += face->box_line_width;
18631 it->descent += face->box_line_width;
18632 }
18633
18634 if (it->start_of_box_run_p)
18635 it->pixel_width += abs (face->box_line_width);
18636 if (it->end_of_box_run_p)
18637 it->pixel_width += abs (face->box_line_width);
18638 }
18639
18640 take_vertical_position_into_account (it);
18641 }
18642
18643 /* Calculate line-height and line-spacing properties.
18644 An integer value specifies explicit pixel value.
18645 A float value specifies relative value to current face height.
18646 A cons (float . face-name) specifies relative value to
18647 height of specified face font.
18648
18649 Returns height in pixels, or nil. */
18650
18651 static Lisp_Object
18652 calc_line_height_property (it, prop, font, boff, total)
18653 struct it *it;
18654 Lisp_Object prop;
18655 XFontStruct *font;
18656 int boff, *total;
18657 {
18658 Lisp_Object position, val;
18659 Lisp_Object face_name = Qnil;
18660 int ascent, descent, height, override;
18661
18662 if (STRINGP (it->object))
18663 position = make_number (IT_STRING_CHARPOS (*it));
18664 else
18665 position = make_number (IT_CHARPOS (*it));
18666
18667 val = Fget_char_property (position, prop, it->object);
18668
18669 if (NILP (val))
18670 return val;
18671
18672 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18673 {
18674 *total = 1;
18675 val = XCDR (val);
18676 }
18677
18678 if (INTEGERP (val))
18679 return val;
18680
18681 if (CONSP (val))
18682 {
18683 face_name = XCDR (val);
18684 val = XCAR (val);
18685 }
18686 else if (SYMBOLP (val))
18687 {
18688 face_name = val;
18689 val = Qnil;
18690 }
18691
18692 override = EQ (prop, Qline_height);
18693
18694 if (NILP (face_name))
18695 {
18696 font = FRAME_FONT (it->f);
18697 boff = FRAME_BASELINE_OFFSET (it->f);
18698 }
18699 else if (EQ (face_name, Qt))
18700 {
18701 override = 0;
18702 }
18703 else
18704 {
18705 int face_id;
18706 struct face *face;
18707 struct font_info *font_info;
18708
18709 face_id = lookup_named_face (it->f, face_name, ' ');
18710 if (face_id < 0)
18711 return make_number (-1);
18712
18713 face = FACE_FROM_ID (it->f, face_id);
18714 font = face->font;
18715 if (font == NULL)
18716 return make_number (-1);
18717
18718 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18719 boff = font_info->baseline_offset;
18720 if (font_info->vertical_centering)
18721 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18722 }
18723
18724 ascent = FONT_BASE (font) + boff;
18725 descent = FONT_DESCENT (font) - boff;
18726
18727 if (override)
18728 {
18729 it->override_ascent = ascent;
18730 it->override_descent = descent;
18731 it->override_boff = boff;
18732 }
18733
18734 height = ascent + descent;
18735 if (FLOATP (val))
18736 height = (int)(XFLOAT_DATA (val) * height);
18737 else if (INTEGERP (val))
18738 height *= XINT (val);
18739
18740 return make_number (height);
18741 }
18742
18743
18744 /* RIF:
18745 Produce glyphs/get display metrics for the display element IT is
18746 loaded with. See the description of struct display_iterator in
18747 dispextern.h for an overview of struct display_iterator. */
18748
18749 void
18750 x_produce_glyphs (it)
18751 struct it *it;
18752 {
18753 int extra_line_spacing = it->extra_line_spacing;
18754
18755 it->glyph_not_available_p = 0;
18756
18757 if (it->what == IT_CHARACTER)
18758 {
18759 XChar2b char2b;
18760 XFontStruct *font;
18761 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18762 XCharStruct *pcm;
18763 int font_not_found_p;
18764 struct font_info *font_info;
18765 int boff; /* baseline offset */
18766 /* We may change it->multibyte_p upon unibyte<->multibyte
18767 conversion. So, save the current value now and restore it
18768 later.
18769
18770 Note: It seems that we don't have to record multibyte_p in
18771 struct glyph because the character code itself tells if or
18772 not the character is multibyte. Thus, in the future, we must
18773 consider eliminating the field `multibyte_p' in the struct
18774 glyph. */
18775 int saved_multibyte_p = it->multibyte_p;
18776
18777 /* Maybe translate single-byte characters to multibyte, or the
18778 other way. */
18779 it->char_to_display = it->c;
18780 if (!ASCII_BYTE_P (it->c))
18781 {
18782 if (unibyte_display_via_language_environment
18783 && SINGLE_BYTE_CHAR_P (it->c)
18784 && (it->c >= 0240
18785 || !NILP (Vnonascii_translation_table)))
18786 {
18787 it->char_to_display = unibyte_char_to_multibyte (it->c);
18788 it->multibyte_p = 1;
18789 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18790 face = FACE_FROM_ID (it->f, it->face_id);
18791 }
18792 else if (!SINGLE_BYTE_CHAR_P (it->c)
18793 && !it->multibyte_p)
18794 {
18795 it->multibyte_p = 1;
18796 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18797 face = FACE_FROM_ID (it->f, it->face_id);
18798 }
18799 }
18800
18801 /* Get font to use. Encode IT->char_to_display. */
18802 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18803 &char2b, it->multibyte_p, 0);
18804 font = face->font;
18805
18806 /* When no suitable font found, use the default font. */
18807 font_not_found_p = font == NULL;
18808 if (font_not_found_p)
18809 {
18810 font = FRAME_FONT (it->f);
18811 boff = FRAME_BASELINE_OFFSET (it->f);
18812 font_info = NULL;
18813 }
18814 else
18815 {
18816 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18817 boff = font_info->baseline_offset;
18818 if (font_info->vertical_centering)
18819 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18820 }
18821
18822 if (it->char_to_display >= ' '
18823 && (!it->multibyte_p || it->char_to_display < 128))
18824 {
18825 /* Either unibyte or ASCII. */
18826 int stretched_p;
18827
18828 it->nglyphs = 1;
18829
18830 pcm = rif->per_char_metric (font, &char2b,
18831 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18832
18833 if (it->override_ascent >= 0)
18834 {
18835 it->ascent = it->override_ascent;
18836 it->descent = it->override_descent;
18837 boff = it->override_boff;
18838 }
18839 else
18840 {
18841 it->ascent = FONT_BASE (font) + boff;
18842 it->descent = FONT_DESCENT (font) - boff;
18843 }
18844
18845 if (pcm)
18846 {
18847 it->phys_ascent = pcm->ascent + boff;
18848 it->phys_descent = pcm->descent - boff;
18849 it->pixel_width = pcm->width;
18850 }
18851 else
18852 {
18853 it->glyph_not_available_p = 1;
18854 it->phys_ascent = it->ascent;
18855 it->phys_descent = it->descent;
18856 it->pixel_width = FONT_WIDTH (font);
18857 }
18858
18859 if (it->constrain_row_ascent_descent_p)
18860 {
18861 if (it->descent > it->max_descent)
18862 {
18863 it->ascent += it->descent - it->max_descent;
18864 it->descent = it->max_descent;
18865 }
18866 if (it->ascent > it->max_ascent)
18867 {
18868 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18869 it->ascent = it->max_ascent;
18870 }
18871 it->phys_ascent = min (it->phys_ascent, it->ascent);
18872 it->phys_descent = min (it->phys_descent, it->descent);
18873 extra_line_spacing = 0;
18874 }
18875
18876 /* If this is a space inside a region of text with
18877 `space-width' property, change its width. */
18878 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18879 if (stretched_p)
18880 it->pixel_width *= XFLOATINT (it->space_width);
18881
18882 /* If face has a box, add the box thickness to the character
18883 height. If character has a box line to the left and/or
18884 right, add the box line width to the character's width. */
18885 if (face->box != FACE_NO_BOX)
18886 {
18887 int thick = face->box_line_width;
18888
18889 if (thick > 0)
18890 {
18891 it->ascent += thick;
18892 it->descent += thick;
18893 }
18894 else
18895 thick = -thick;
18896
18897 if (it->start_of_box_run_p)
18898 it->pixel_width += thick;
18899 if (it->end_of_box_run_p)
18900 it->pixel_width += thick;
18901 }
18902
18903 /* If face has an overline, add the height of the overline
18904 (1 pixel) and a 1 pixel margin to the character height. */
18905 if (face->overline_p)
18906 it->ascent += 2;
18907
18908 if (it->constrain_row_ascent_descent_p)
18909 {
18910 if (it->ascent > it->max_ascent)
18911 it->ascent = it->max_ascent;
18912 if (it->descent > it->max_descent)
18913 it->descent = it->max_descent;
18914 }
18915
18916 take_vertical_position_into_account (it);
18917
18918 /* If we have to actually produce glyphs, do it. */
18919 if (it->glyph_row)
18920 {
18921 if (stretched_p)
18922 {
18923 /* Translate a space with a `space-width' property
18924 into a stretch glyph. */
18925 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18926 / FONT_HEIGHT (font));
18927 append_stretch_glyph (it, it->object, it->pixel_width,
18928 it->ascent + it->descent, ascent);
18929 }
18930 else
18931 append_glyph (it);
18932
18933 /* If characters with lbearing or rbearing are displayed
18934 in this line, record that fact in a flag of the
18935 glyph row. This is used to optimize X output code. */
18936 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18937 it->glyph_row->contains_overlapping_glyphs_p = 1;
18938 }
18939 }
18940 else if (it->char_to_display == '\n')
18941 {
18942 /* A newline has no width but we need the height of the line.
18943 But if previous part of the line set a height, don't
18944 increase that height */
18945
18946 Lisp_Object height;
18947
18948 it->override_ascent = -1;
18949 it->pixel_width = 0;
18950 it->nglyphs = 0;
18951
18952 height = calc_line_height_property(it, Qline_height, font, boff, 0);
18953
18954 if (it->override_ascent >= 0)
18955 {
18956 it->ascent = it->override_ascent;
18957 it->descent = it->override_descent;
18958 boff = it->override_boff;
18959 }
18960 else
18961 {
18962 it->ascent = FONT_BASE (font) + boff;
18963 it->descent = FONT_DESCENT (font) - boff;
18964 }
18965
18966 if (EQ (height, make_number(0)))
18967 {
18968 if (it->descent > it->max_descent)
18969 {
18970 it->ascent += it->descent - it->max_descent;
18971 it->descent = it->max_descent;
18972 }
18973 if (it->ascent > it->max_ascent)
18974 {
18975 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18976 it->ascent = it->max_ascent;
18977 }
18978 it->phys_ascent = min (it->phys_ascent, it->ascent);
18979 it->phys_descent = min (it->phys_descent, it->descent);
18980 it->constrain_row_ascent_descent_p = 1;
18981 extra_line_spacing = 0;
18982 }
18983 else
18984 {
18985 Lisp_Object spacing;
18986 int total = 0;
18987
18988 it->phys_ascent = it->ascent;
18989 it->phys_descent = it->descent;
18990
18991 if ((it->max_ascent > 0 || it->max_descent > 0)
18992 && face->box != FACE_NO_BOX
18993 && face->box_line_width > 0)
18994 {
18995 it->ascent += face->box_line_width;
18996 it->descent += face->box_line_width;
18997 }
18998 if (!NILP (height)
18999 && XINT (height) > it->ascent + it->descent)
19000 it->ascent = XINT (height) - it->descent;
19001
19002 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
19003 if (INTEGERP (spacing))
19004 {
19005 extra_line_spacing = XINT (spacing);
19006 if (total)
19007 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19008 }
19009 }
19010 }
19011 else if (it->char_to_display == '\t')
19012 {
19013 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19014 int x = it->current_x + it->continuation_lines_width;
19015 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19016
19017 /* If the distance from the current position to the next tab
19018 stop is less than a canonical character width, use the
19019 tab stop after that. */
19020 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19021 next_tab_x += tab_width;
19022
19023 it->pixel_width = next_tab_x - x;
19024 it->nglyphs = 1;
19025 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19026 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19027
19028 if (it->glyph_row)
19029 {
19030 append_stretch_glyph (it, it->object, it->pixel_width,
19031 it->ascent + it->descent, it->ascent);
19032 }
19033 }
19034 else
19035 {
19036 /* A multi-byte character. Assume that the display width of the
19037 character is the width of the character multiplied by the
19038 width of the font. */
19039
19040 /* If we found a font, this font should give us the right
19041 metrics. If we didn't find a font, use the frame's
19042 default font and calculate the width of the character
19043 from the charset width; this is what old redisplay code
19044 did. */
19045
19046 pcm = rif->per_char_metric (font, &char2b,
19047 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19048
19049 if (font_not_found_p || !pcm)
19050 {
19051 int charset = CHAR_CHARSET (it->char_to_display);
19052
19053 it->glyph_not_available_p = 1;
19054 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19055 * CHARSET_WIDTH (charset));
19056 it->phys_ascent = FONT_BASE (font) + boff;
19057 it->phys_descent = FONT_DESCENT (font) - boff;
19058 }
19059 else
19060 {
19061 it->pixel_width = pcm->width;
19062 it->phys_ascent = pcm->ascent + boff;
19063 it->phys_descent = pcm->descent - boff;
19064 if (it->glyph_row
19065 && (pcm->lbearing < 0
19066 || pcm->rbearing > pcm->width))
19067 it->glyph_row->contains_overlapping_glyphs_p = 1;
19068 }
19069 it->nglyphs = 1;
19070 it->ascent = FONT_BASE (font) + boff;
19071 it->descent = FONT_DESCENT (font) - boff;
19072 if (face->box != FACE_NO_BOX)
19073 {
19074 int thick = face->box_line_width;
19075
19076 if (thick > 0)
19077 {
19078 it->ascent += thick;
19079 it->descent += thick;
19080 }
19081 else
19082 thick = - thick;
19083
19084 if (it->start_of_box_run_p)
19085 it->pixel_width += thick;
19086 if (it->end_of_box_run_p)
19087 it->pixel_width += thick;
19088 }
19089
19090 /* If face has an overline, add the height of the overline
19091 (1 pixel) and a 1 pixel margin to the character height. */
19092 if (face->overline_p)
19093 it->ascent += 2;
19094
19095 take_vertical_position_into_account (it);
19096
19097 if (it->glyph_row)
19098 append_glyph (it);
19099 }
19100 it->multibyte_p = saved_multibyte_p;
19101 }
19102 else if (it->what == IT_COMPOSITION)
19103 {
19104 /* Note: A composition is represented as one glyph in the
19105 glyph matrix. There are no padding glyphs. */
19106 XChar2b char2b;
19107 XFontStruct *font;
19108 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19109 XCharStruct *pcm;
19110 int font_not_found_p;
19111 struct font_info *font_info;
19112 int boff; /* baseline offset */
19113 struct composition *cmp = composition_table[it->cmp_id];
19114
19115 /* Maybe translate single-byte characters to multibyte. */
19116 it->char_to_display = it->c;
19117 if (unibyte_display_via_language_environment
19118 && SINGLE_BYTE_CHAR_P (it->c)
19119 && (it->c >= 0240
19120 || (it->c >= 0200
19121 && !NILP (Vnonascii_translation_table))))
19122 {
19123 it->char_to_display = unibyte_char_to_multibyte (it->c);
19124 }
19125
19126 /* Get face and font to use. Encode IT->char_to_display. */
19127 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19128 face = FACE_FROM_ID (it->f, it->face_id);
19129 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19130 &char2b, it->multibyte_p, 0);
19131 font = face->font;
19132
19133 /* When no suitable font found, use the default font. */
19134 font_not_found_p = font == NULL;
19135 if (font_not_found_p)
19136 {
19137 font = FRAME_FONT (it->f);
19138 boff = FRAME_BASELINE_OFFSET (it->f);
19139 font_info = NULL;
19140 }
19141 else
19142 {
19143 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19144 boff = font_info->baseline_offset;
19145 if (font_info->vertical_centering)
19146 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19147 }
19148
19149 /* There are no padding glyphs, so there is only one glyph to
19150 produce for the composition. Important is that pixel_width,
19151 ascent and descent are the values of what is drawn by
19152 draw_glyphs (i.e. the values of the overall glyphs composed). */
19153 it->nglyphs = 1;
19154
19155 /* If we have not yet calculated pixel size data of glyphs of
19156 the composition for the current face font, calculate them
19157 now. Theoretically, we have to check all fonts for the
19158 glyphs, but that requires much time and memory space. So,
19159 here we check only the font of the first glyph. This leads
19160 to incorrect display very rarely, and C-l (recenter) can
19161 correct the display anyway. */
19162 if (cmp->font != (void *) font)
19163 {
19164 /* Ascent and descent of the font of the first character of
19165 this composition (adjusted by baseline offset). Ascent
19166 and descent of overall glyphs should not be less than
19167 them respectively. */
19168 int font_ascent = FONT_BASE (font) + boff;
19169 int font_descent = FONT_DESCENT (font) - boff;
19170 /* Bounding box of the overall glyphs. */
19171 int leftmost, rightmost, lowest, highest;
19172 int i, width, ascent, descent;
19173
19174 cmp->font = (void *) font;
19175
19176 /* Initialize the bounding box. */
19177 if (font_info
19178 && (pcm = rif->per_char_metric (font, &char2b,
19179 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19180 {
19181 width = pcm->width;
19182 ascent = pcm->ascent;
19183 descent = pcm->descent;
19184 }
19185 else
19186 {
19187 width = FONT_WIDTH (font);
19188 ascent = FONT_BASE (font);
19189 descent = FONT_DESCENT (font);
19190 }
19191
19192 rightmost = width;
19193 lowest = - descent + boff;
19194 highest = ascent + boff;
19195 leftmost = 0;
19196
19197 if (font_info
19198 && font_info->default_ascent
19199 && CHAR_TABLE_P (Vuse_default_ascent)
19200 && !NILP (Faref (Vuse_default_ascent,
19201 make_number (it->char_to_display))))
19202 highest = font_info->default_ascent + boff;
19203
19204 /* Draw the first glyph at the normal position. It may be
19205 shifted to right later if some other glyphs are drawn at
19206 the left. */
19207 cmp->offsets[0] = 0;
19208 cmp->offsets[1] = boff;
19209
19210 /* Set cmp->offsets for the remaining glyphs. */
19211 for (i = 1; i < cmp->glyph_len; i++)
19212 {
19213 int left, right, btm, top;
19214 int ch = COMPOSITION_GLYPH (cmp, i);
19215 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19216
19217 face = FACE_FROM_ID (it->f, face_id);
19218 get_char_face_and_encoding (it->f, ch, face->id,
19219 &char2b, it->multibyte_p, 0);
19220 font = face->font;
19221 if (font == NULL)
19222 {
19223 font = FRAME_FONT (it->f);
19224 boff = FRAME_BASELINE_OFFSET (it->f);
19225 font_info = NULL;
19226 }
19227 else
19228 {
19229 font_info
19230 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19231 boff = font_info->baseline_offset;
19232 if (font_info->vertical_centering)
19233 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19234 }
19235
19236 if (font_info
19237 && (pcm = rif->per_char_metric (font, &char2b,
19238 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19239 {
19240 width = pcm->width;
19241 ascent = pcm->ascent;
19242 descent = pcm->descent;
19243 }
19244 else
19245 {
19246 width = FONT_WIDTH (font);
19247 ascent = 1;
19248 descent = 0;
19249 }
19250
19251 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19252 {
19253 /* Relative composition with or without
19254 alternate chars. */
19255 left = (leftmost + rightmost - width) / 2;
19256 btm = - descent + boff;
19257 if (font_info && font_info->relative_compose
19258 && (! CHAR_TABLE_P (Vignore_relative_composition)
19259 || NILP (Faref (Vignore_relative_composition,
19260 make_number (ch)))))
19261 {
19262
19263 if (- descent >= font_info->relative_compose)
19264 /* One extra pixel between two glyphs. */
19265 btm = highest + 1;
19266 else if (ascent <= 0)
19267 /* One extra pixel between two glyphs. */
19268 btm = lowest - 1 - ascent - descent;
19269 }
19270 }
19271 else
19272 {
19273 /* A composition rule is specified by an integer
19274 value that encodes global and new reference
19275 points (GREF and NREF). GREF and NREF are
19276 specified by numbers as below:
19277
19278 0---1---2 -- ascent
19279 | |
19280 | |
19281 | |
19282 9--10--11 -- center
19283 | |
19284 ---3---4---5--- baseline
19285 | |
19286 6---7---8 -- descent
19287 */
19288 int rule = COMPOSITION_RULE (cmp, i);
19289 int gref, nref, grefx, grefy, nrefx, nrefy;
19290
19291 COMPOSITION_DECODE_RULE (rule, gref, nref);
19292 grefx = gref % 3, nrefx = nref % 3;
19293 grefy = gref / 3, nrefy = nref / 3;
19294
19295 left = (leftmost
19296 + grefx * (rightmost - leftmost) / 2
19297 - nrefx * width / 2);
19298 btm = ((grefy == 0 ? highest
19299 : grefy == 1 ? 0
19300 : grefy == 2 ? lowest
19301 : (highest + lowest) / 2)
19302 - (nrefy == 0 ? ascent + descent
19303 : nrefy == 1 ? descent - boff
19304 : nrefy == 2 ? 0
19305 : (ascent + descent) / 2));
19306 }
19307
19308 cmp->offsets[i * 2] = left;
19309 cmp->offsets[i * 2 + 1] = btm + descent;
19310
19311 /* Update the bounding box of the overall glyphs. */
19312 right = left + width;
19313 top = btm + descent + ascent;
19314 if (left < leftmost)
19315 leftmost = left;
19316 if (right > rightmost)
19317 rightmost = right;
19318 if (top > highest)
19319 highest = top;
19320 if (btm < lowest)
19321 lowest = btm;
19322 }
19323
19324 /* If there are glyphs whose x-offsets are negative,
19325 shift all glyphs to the right and make all x-offsets
19326 non-negative. */
19327 if (leftmost < 0)
19328 {
19329 for (i = 0; i < cmp->glyph_len; i++)
19330 cmp->offsets[i * 2] -= leftmost;
19331 rightmost -= leftmost;
19332 }
19333
19334 cmp->pixel_width = rightmost;
19335 cmp->ascent = highest;
19336 cmp->descent = - lowest;
19337 if (cmp->ascent < font_ascent)
19338 cmp->ascent = font_ascent;
19339 if (cmp->descent < font_descent)
19340 cmp->descent = font_descent;
19341 }
19342
19343 it->pixel_width = cmp->pixel_width;
19344 it->ascent = it->phys_ascent = cmp->ascent;
19345 it->descent = it->phys_descent = cmp->descent;
19346
19347 if (face->box != FACE_NO_BOX)
19348 {
19349 int thick = face->box_line_width;
19350
19351 if (thick > 0)
19352 {
19353 it->ascent += thick;
19354 it->descent += thick;
19355 }
19356 else
19357 thick = - thick;
19358
19359 if (it->start_of_box_run_p)
19360 it->pixel_width += thick;
19361 if (it->end_of_box_run_p)
19362 it->pixel_width += thick;
19363 }
19364
19365 /* If face has an overline, add the height of the overline
19366 (1 pixel) and a 1 pixel margin to the character height. */
19367 if (face->overline_p)
19368 it->ascent += 2;
19369
19370 take_vertical_position_into_account (it);
19371
19372 if (it->glyph_row)
19373 append_composite_glyph (it);
19374 }
19375 else if (it->what == IT_IMAGE)
19376 produce_image_glyph (it);
19377 else if (it->what == IT_STRETCH)
19378 produce_stretch_glyph (it);
19379
19380 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19381 because this isn't true for images with `:ascent 100'. */
19382 xassert (it->ascent >= 0 && it->descent >= 0);
19383 if (it->area == TEXT_AREA)
19384 it->current_x += it->pixel_width;
19385
19386 if (extra_line_spacing > 0)
19387 it->descent += extra_line_spacing;
19388
19389 it->max_ascent = max (it->max_ascent, it->ascent);
19390 it->max_descent = max (it->max_descent, it->descent);
19391 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19392 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19393 }
19394
19395 /* EXPORT for RIF:
19396 Output LEN glyphs starting at START at the nominal cursor position.
19397 Advance the nominal cursor over the text. The global variable
19398 updated_window contains the window being updated, updated_row is
19399 the glyph row being updated, and updated_area is the area of that
19400 row being updated. */
19401
19402 void
19403 x_write_glyphs (start, len)
19404 struct glyph *start;
19405 int len;
19406 {
19407 int x, hpos;
19408
19409 xassert (updated_window && updated_row);
19410 BLOCK_INPUT;
19411
19412 /* Write glyphs. */
19413
19414 hpos = start - updated_row->glyphs[updated_area];
19415 x = draw_glyphs (updated_window, output_cursor.x,
19416 updated_row, updated_area,
19417 hpos, hpos + len,
19418 DRAW_NORMAL_TEXT, 0);
19419
19420 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19421 if (updated_area == TEXT_AREA
19422 && updated_window->phys_cursor_on_p
19423 && updated_window->phys_cursor.vpos == output_cursor.vpos
19424 && updated_window->phys_cursor.hpos >= hpos
19425 && updated_window->phys_cursor.hpos < hpos + len)
19426 updated_window->phys_cursor_on_p = 0;
19427
19428 UNBLOCK_INPUT;
19429
19430 /* Advance the output cursor. */
19431 output_cursor.hpos += len;
19432 output_cursor.x = x;
19433 }
19434
19435
19436 /* EXPORT for RIF:
19437 Insert LEN glyphs from START at the nominal cursor position. */
19438
19439 void
19440 x_insert_glyphs (start, len)
19441 struct glyph *start;
19442 int len;
19443 {
19444 struct frame *f;
19445 struct window *w;
19446 int line_height, shift_by_width, shifted_region_width;
19447 struct glyph_row *row;
19448 struct glyph *glyph;
19449 int frame_x, frame_y, hpos;
19450
19451 xassert (updated_window && updated_row);
19452 BLOCK_INPUT;
19453 w = updated_window;
19454 f = XFRAME (WINDOW_FRAME (w));
19455
19456 /* Get the height of the line we are in. */
19457 row = updated_row;
19458 line_height = row->height;
19459
19460 /* Get the width of the glyphs to insert. */
19461 shift_by_width = 0;
19462 for (glyph = start; glyph < start + len; ++glyph)
19463 shift_by_width += glyph->pixel_width;
19464
19465 /* Get the width of the region to shift right. */
19466 shifted_region_width = (window_box_width (w, updated_area)
19467 - output_cursor.x
19468 - shift_by_width);
19469
19470 /* Shift right. */
19471 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19472 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19473
19474 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19475 line_height, shift_by_width);
19476
19477 /* Write the glyphs. */
19478 hpos = start - row->glyphs[updated_area];
19479 draw_glyphs (w, output_cursor.x, row, updated_area,
19480 hpos, hpos + len,
19481 DRAW_NORMAL_TEXT, 0);
19482
19483 /* Advance the output cursor. */
19484 output_cursor.hpos += len;
19485 output_cursor.x += shift_by_width;
19486 UNBLOCK_INPUT;
19487 }
19488
19489
19490 /* EXPORT for RIF:
19491 Erase the current text line from the nominal cursor position
19492 (inclusive) to pixel column TO_X (exclusive). The idea is that
19493 everything from TO_X onward is already erased.
19494
19495 TO_X is a pixel position relative to updated_area of
19496 updated_window. TO_X == -1 means clear to the end of this area. */
19497
19498 void
19499 x_clear_end_of_line (to_x)
19500 int to_x;
19501 {
19502 struct frame *f;
19503 struct window *w = updated_window;
19504 int max_x, min_y, max_y;
19505 int from_x, from_y, to_y;
19506
19507 xassert (updated_window && updated_row);
19508 f = XFRAME (w->frame);
19509
19510 if (updated_row->full_width_p)
19511 max_x = WINDOW_TOTAL_WIDTH (w);
19512 else
19513 max_x = window_box_width (w, updated_area);
19514 max_y = window_text_bottom_y (w);
19515
19516 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19517 of window. For TO_X > 0, truncate to end of drawing area. */
19518 if (to_x == 0)
19519 return;
19520 else if (to_x < 0)
19521 to_x = max_x;
19522 else
19523 to_x = min (to_x, max_x);
19524
19525 to_y = min (max_y, output_cursor.y + updated_row->height);
19526
19527 /* Notice if the cursor will be cleared by this operation. */
19528 if (!updated_row->full_width_p)
19529 notice_overwritten_cursor (w, updated_area,
19530 output_cursor.x, -1,
19531 updated_row->y,
19532 MATRIX_ROW_BOTTOM_Y (updated_row));
19533
19534 from_x = output_cursor.x;
19535
19536 /* Translate to frame coordinates. */
19537 if (updated_row->full_width_p)
19538 {
19539 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19540 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19541 }
19542 else
19543 {
19544 int area_left = window_box_left (w, updated_area);
19545 from_x += area_left;
19546 to_x += area_left;
19547 }
19548
19549 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19550 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19551 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19552
19553 /* Prevent inadvertently clearing to end of the X window. */
19554 if (to_x > from_x && to_y > from_y)
19555 {
19556 BLOCK_INPUT;
19557 rif->clear_frame_area (f, from_x, from_y,
19558 to_x - from_x, to_y - from_y);
19559 UNBLOCK_INPUT;
19560 }
19561 }
19562
19563 #endif /* HAVE_WINDOW_SYSTEM */
19564
19565
19566 \f
19567 /***********************************************************************
19568 Cursor types
19569 ***********************************************************************/
19570
19571 /* Value is the internal representation of the specified cursor type
19572 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19573 of the bar cursor. */
19574
19575 static enum text_cursor_kinds
19576 get_specified_cursor_type (arg, width)
19577 Lisp_Object arg;
19578 int *width;
19579 {
19580 enum text_cursor_kinds type;
19581
19582 if (NILP (arg))
19583 return NO_CURSOR;
19584
19585 if (EQ (arg, Qbox))
19586 return FILLED_BOX_CURSOR;
19587
19588 if (EQ (arg, Qhollow))
19589 return HOLLOW_BOX_CURSOR;
19590
19591 if (EQ (arg, Qbar))
19592 {
19593 *width = 2;
19594 return BAR_CURSOR;
19595 }
19596
19597 if (CONSP (arg)
19598 && EQ (XCAR (arg), Qbar)
19599 && INTEGERP (XCDR (arg))
19600 && XINT (XCDR (arg)) >= 0)
19601 {
19602 *width = XINT (XCDR (arg));
19603 return BAR_CURSOR;
19604 }
19605
19606 if (EQ (arg, Qhbar))
19607 {
19608 *width = 2;
19609 return HBAR_CURSOR;
19610 }
19611
19612 if (CONSP (arg)
19613 && EQ (XCAR (arg), Qhbar)
19614 && INTEGERP (XCDR (arg))
19615 && XINT (XCDR (arg)) >= 0)
19616 {
19617 *width = XINT (XCDR (arg));
19618 return HBAR_CURSOR;
19619 }
19620
19621 /* Treat anything unknown as "hollow box cursor".
19622 It was bad to signal an error; people have trouble fixing
19623 .Xdefaults with Emacs, when it has something bad in it. */
19624 type = HOLLOW_BOX_CURSOR;
19625
19626 return type;
19627 }
19628
19629 /* Set the default cursor types for specified frame. */
19630 void
19631 set_frame_cursor_types (f, arg)
19632 struct frame *f;
19633 Lisp_Object arg;
19634 {
19635 int width;
19636 Lisp_Object tem;
19637
19638 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19639 FRAME_CURSOR_WIDTH (f) = width;
19640
19641 /* By default, set up the blink-off state depending on the on-state. */
19642
19643 tem = Fassoc (arg, Vblink_cursor_alist);
19644 if (!NILP (tem))
19645 {
19646 FRAME_BLINK_OFF_CURSOR (f)
19647 = get_specified_cursor_type (XCDR (tem), &width);
19648 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19649 }
19650 else
19651 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19652 }
19653
19654
19655 /* Return the cursor we want to be displayed in window W. Return
19656 width of bar/hbar cursor through WIDTH arg. Return with
19657 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19658 (i.e. if the `system caret' should track this cursor).
19659
19660 In a mini-buffer window, we want the cursor only to appear if we
19661 are reading input from this window. For the selected window, we
19662 want the cursor type given by the frame parameter or buffer local
19663 setting of cursor-type. If explicitly marked off, draw no cursor.
19664 In all other cases, we want a hollow box cursor. */
19665
19666 static enum text_cursor_kinds
19667 get_window_cursor_type (w, glyph, width, active_cursor)
19668 struct window *w;
19669 struct glyph *glyph;
19670 int *width;
19671 int *active_cursor;
19672 {
19673 struct frame *f = XFRAME (w->frame);
19674 struct buffer *b = XBUFFER (w->buffer);
19675 int cursor_type = DEFAULT_CURSOR;
19676 Lisp_Object alt_cursor;
19677 int non_selected = 0;
19678
19679 *active_cursor = 1;
19680
19681 /* Echo area */
19682 if (cursor_in_echo_area
19683 && FRAME_HAS_MINIBUF_P (f)
19684 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19685 {
19686 if (w == XWINDOW (echo_area_window))
19687 {
19688 *width = FRAME_CURSOR_WIDTH (f);
19689 return FRAME_DESIRED_CURSOR (f);
19690 }
19691
19692 *active_cursor = 0;
19693 non_selected = 1;
19694 }
19695
19696 /* Nonselected window or nonselected frame. */
19697 else if (w != XWINDOW (f->selected_window)
19698 #ifdef HAVE_WINDOW_SYSTEM
19699 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19700 #endif
19701 )
19702 {
19703 *active_cursor = 0;
19704
19705 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19706 return NO_CURSOR;
19707
19708 non_selected = 1;
19709 }
19710
19711 /* Never display a cursor in a window in which cursor-type is nil. */
19712 if (NILP (b->cursor_type))
19713 return NO_CURSOR;
19714
19715 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19716 if (non_selected)
19717 {
19718 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19719 return get_specified_cursor_type (alt_cursor, width);
19720 }
19721
19722 /* Get the normal cursor type for this window. */
19723 if (EQ (b->cursor_type, Qt))
19724 {
19725 cursor_type = FRAME_DESIRED_CURSOR (f);
19726 *width = FRAME_CURSOR_WIDTH (f);
19727 }
19728 else
19729 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19730
19731 /* Use normal cursor if not blinked off. */
19732 if (!w->cursor_off_p)
19733 {
19734 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19735 if (cursor_type == FILLED_BOX_CURSOR)
19736 cursor_type = HOLLOW_BOX_CURSOR;
19737 }
19738 return cursor_type;
19739 }
19740
19741 /* Cursor is blinked off, so determine how to "toggle" it. */
19742
19743 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19744 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19745 return get_specified_cursor_type (XCDR (alt_cursor), width);
19746
19747 /* Then see if frame has specified a specific blink off cursor type. */
19748 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19749 {
19750 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19751 return FRAME_BLINK_OFF_CURSOR (f);
19752 }
19753
19754 #if 0
19755 /* Some people liked having a permanently visible blinking cursor,
19756 while others had very strong opinions against it. So it was
19757 decided to remove it. KFS 2003-09-03 */
19758
19759 /* Finally perform built-in cursor blinking:
19760 filled box <-> hollow box
19761 wide [h]bar <-> narrow [h]bar
19762 narrow [h]bar <-> no cursor
19763 other type <-> no cursor */
19764
19765 if (cursor_type == FILLED_BOX_CURSOR)
19766 return HOLLOW_BOX_CURSOR;
19767
19768 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19769 {
19770 *width = 1;
19771 return cursor_type;
19772 }
19773 #endif
19774
19775 return NO_CURSOR;
19776 }
19777
19778
19779 #ifdef HAVE_WINDOW_SYSTEM
19780
19781 /* Notice when the text cursor of window W has been completely
19782 overwritten by a drawing operation that outputs glyphs in AREA
19783 starting at X0 and ending at X1 in the line starting at Y0 and
19784 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19785 the rest of the line after X0 has been written. Y coordinates
19786 are window-relative. */
19787
19788 static void
19789 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19790 struct window *w;
19791 enum glyph_row_area area;
19792 int x0, y0, x1, y1;
19793 {
19794 int cx0, cx1, cy0, cy1;
19795 struct glyph_row *row;
19796
19797 if (!w->phys_cursor_on_p)
19798 return;
19799 if (area != TEXT_AREA)
19800 return;
19801
19802 row = w->current_matrix->rows + w->phys_cursor.vpos;
19803 if (!row->displays_text_p)
19804 return;
19805
19806 if (row->cursor_in_fringe_p)
19807 {
19808 row->cursor_in_fringe_p = 0;
19809 draw_fringe_bitmap (w, row, 0);
19810 w->phys_cursor_on_p = 0;
19811 return;
19812 }
19813
19814 cx0 = w->phys_cursor.x;
19815 cx1 = cx0 + w->phys_cursor_width;
19816 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19817 return;
19818
19819 /* The cursor image will be completely removed from the
19820 screen if the output area intersects the cursor area in
19821 y-direction. When we draw in [y0 y1[, and some part of
19822 the cursor is at y < y0, that part must have been drawn
19823 before. When scrolling, the cursor is erased before
19824 actually scrolling, so we don't come here. When not
19825 scrolling, the rows above the old cursor row must have
19826 changed, and in this case these rows must have written
19827 over the cursor image.
19828
19829 Likewise if part of the cursor is below y1, with the
19830 exception of the cursor being in the first blank row at
19831 the buffer and window end because update_text_area
19832 doesn't draw that row. (Except when it does, but
19833 that's handled in update_text_area.) */
19834
19835 cy0 = w->phys_cursor.y;
19836 cy1 = cy0 + w->phys_cursor_height;
19837 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19838 return;
19839
19840 w->phys_cursor_on_p = 0;
19841 }
19842
19843 #endif /* HAVE_WINDOW_SYSTEM */
19844
19845 \f
19846 /************************************************************************
19847 Mouse Face
19848 ************************************************************************/
19849
19850 #ifdef HAVE_WINDOW_SYSTEM
19851
19852 /* EXPORT for RIF:
19853 Fix the display of area AREA of overlapping row ROW in window W. */
19854
19855 void
19856 x_fix_overlapping_area (w, row, area)
19857 struct window *w;
19858 struct glyph_row *row;
19859 enum glyph_row_area area;
19860 {
19861 int i, x;
19862
19863 BLOCK_INPUT;
19864
19865 x = 0;
19866 for (i = 0; i < row->used[area];)
19867 {
19868 if (row->glyphs[area][i].overlaps_vertically_p)
19869 {
19870 int start = i, start_x = x;
19871
19872 do
19873 {
19874 x += row->glyphs[area][i].pixel_width;
19875 ++i;
19876 }
19877 while (i < row->used[area]
19878 && row->glyphs[area][i].overlaps_vertically_p);
19879
19880 draw_glyphs (w, start_x, row, area,
19881 start, i,
19882 DRAW_NORMAL_TEXT, 1);
19883 }
19884 else
19885 {
19886 x += row->glyphs[area][i].pixel_width;
19887 ++i;
19888 }
19889 }
19890
19891 UNBLOCK_INPUT;
19892 }
19893
19894
19895 /* EXPORT:
19896 Draw the cursor glyph of window W in glyph row ROW. See the
19897 comment of draw_glyphs for the meaning of HL. */
19898
19899 void
19900 draw_phys_cursor_glyph (w, row, hl)
19901 struct window *w;
19902 struct glyph_row *row;
19903 enum draw_glyphs_face hl;
19904 {
19905 /* If cursor hpos is out of bounds, don't draw garbage. This can
19906 happen in mini-buffer windows when switching between echo area
19907 glyphs and mini-buffer. */
19908 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19909 {
19910 int on_p = w->phys_cursor_on_p;
19911 int x1;
19912 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19913 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19914 hl, 0);
19915 w->phys_cursor_on_p = on_p;
19916
19917 if (hl == DRAW_CURSOR)
19918 w->phys_cursor_width = x1 - w->phys_cursor.x;
19919 /* When we erase the cursor, and ROW is overlapped by other
19920 rows, make sure that these overlapping parts of other rows
19921 are redrawn. */
19922 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19923 {
19924 if (row > w->current_matrix->rows
19925 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19926 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19927
19928 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19929 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19930 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19931 }
19932 }
19933 }
19934
19935
19936 /* EXPORT:
19937 Erase the image of a cursor of window W from the screen. */
19938
19939 void
19940 erase_phys_cursor (w)
19941 struct window *w;
19942 {
19943 struct frame *f = XFRAME (w->frame);
19944 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19945 int hpos = w->phys_cursor.hpos;
19946 int vpos = w->phys_cursor.vpos;
19947 int mouse_face_here_p = 0;
19948 struct glyph_matrix *active_glyphs = w->current_matrix;
19949 struct glyph_row *cursor_row;
19950 struct glyph *cursor_glyph;
19951 enum draw_glyphs_face hl;
19952
19953 /* No cursor displayed or row invalidated => nothing to do on the
19954 screen. */
19955 if (w->phys_cursor_type == NO_CURSOR)
19956 goto mark_cursor_off;
19957
19958 /* VPOS >= active_glyphs->nrows means that window has been resized.
19959 Don't bother to erase the cursor. */
19960 if (vpos >= active_glyphs->nrows)
19961 goto mark_cursor_off;
19962
19963 /* If row containing cursor is marked invalid, there is nothing we
19964 can do. */
19965 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19966 if (!cursor_row->enabled_p)
19967 goto mark_cursor_off;
19968
19969 /* If row is completely invisible, don't attempt to delete a cursor which
19970 isn't there. This can happen if cursor is at top of a window, and
19971 we switch to a buffer with a header line in that window. */
19972 if (cursor_row->visible_height <= 0)
19973 goto mark_cursor_off;
19974
19975 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19976 if (cursor_row->cursor_in_fringe_p)
19977 {
19978 cursor_row->cursor_in_fringe_p = 0;
19979 draw_fringe_bitmap (w, cursor_row, 0);
19980 goto mark_cursor_off;
19981 }
19982
19983 /* This can happen when the new row is shorter than the old one.
19984 In this case, either draw_glyphs or clear_end_of_line
19985 should have cleared the cursor. Note that we wouldn't be
19986 able to erase the cursor in this case because we don't have a
19987 cursor glyph at hand. */
19988 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19989 goto mark_cursor_off;
19990
19991 /* If the cursor is in the mouse face area, redisplay that when
19992 we clear the cursor. */
19993 if (! NILP (dpyinfo->mouse_face_window)
19994 && w == XWINDOW (dpyinfo->mouse_face_window)
19995 && (vpos > dpyinfo->mouse_face_beg_row
19996 || (vpos == dpyinfo->mouse_face_beg_row
19997 && hpos >= dpyinfo->mouse_face_beg_col))
19998 && (vpos < dpyinfo->mouse_face_end_row
19999 || (vpos == dpyinfo->mouse_face_end_row
20000 && hpos < dpyinfo->mouse_face_end_col))
20001 /* Don't redraw the cursor's spot in mouse face if it is at the
20002 end of a line (on a newline). The cursor appears there, but
20003 mouse highlighting does not. */
20004 && cursor_row->used[TEXT_AREA] > hpos)
20005 mouse_face_here_p = 1;
20006
20007 /* Maybe clear the display under the cursor. */
20008 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20009 {
20010 int x, y;
20011 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20012
20013 cursor_glyph = get_phys_cursor_glyph (w);
20014 if (cursor_glyph == NULL)
20015 goto mark_cursor_off;
20016
20017 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20018 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20019
20020 rif->clear_frame_area (f, x, y,
20021 cursor_glyph->pixel_width, cursor_row->visible_height);
20022 }
20023
20024 /* Erase the cursor by redrawing the character underneath it. */
20025 if (mouse_face_here_p)
20026 hl = DRAW_MOUSE_FACE;
20027 else
20028 hl = DRAW_NORMAL_TEXT;
20029 draw_phys_cursor_glyph (w, cursor_row, hl);
20030
20031 mark_cursor_off:
20032 w->phys_cursor_on_p = 0;
20033 w->phys_cursor_type = NO_CURSOR;
20034 }
20035
20036
20037 /* EXPORT:
20038 Display or clear cursor of window W. If ON is zero, clear the
20039 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20040 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20041
20042 void
20043 display_and_set_cursor (w, on, hpos, vpos, x, y)
20044 struct window *w;
20045 int on, hpos, vpos, x, y;
20046 {
20047 struct frame *f = XFRAME (w->frame);
20048 int new_cursor_type;
20049 int new_cursor_width;
20050 int active_cursor;
20051 struct glyph_row *glyph_row;
20052 struct glyph *glyph;
20053
20054 /* This is pointless on invisible frames, and dangerous on garbaged
20055 windows and frames; in the latter case, the frame or window may
20056 be in the midst of changing its size, and x and y may be off the
20057 window. */
20058 if (! FRAME_VISIBLE_P (f)
20059 || FRAME_GARBAGED_P (f)
20060 || vpos >= w->current_matrix->nrows
20061 || hpos >= w->current_matrix->matrix_w)
20062 return;
20063
20064 /* If cursor is off and we want it off, return quickly. */
20065 if (!on && !w->phys_cursor_on_p)
20066 return;
20067
20068 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20069 /* If cursor row is not enabled, we don't really know where to
20070 display the cursor. */
20071 if (!glyph_row->enabled_p)
20072 {
20073 w->phys_cursor_on_p = 0;
20074 return;
20075 }
20076
20077 glyph = NULL;
20078 if (!glyph_row->exact_window_width_line_p
20079 || hpos < glyph_row->used[TEXT_AREA])
20080 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20081
20082 xassert (interrupt_input_blocked);
20083
20084 /* Set new_cursor_type to the cursor we want to be displayed. */
20085 new_cursor_type = get_window_cursor_type (w, glyph,
20086 &new_cursor_width, &active_cursor);
20087
20088 /* If cursor is currently being shown and we don't want it to be or
20089 it is in the wrong place, or the cursor type is not what we want,
20090 erase it. */
20091 if (w->phys_cursor_on_p
20092 && (!on
20093 || w->phys_cursor.x != x
20094 || w->phys_cursor.y != y
20095 || new_cursor_type != w->phys_cursor_type
20096 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20097 && new_cursor_width != w->phys_cursor_width)))
20098 erase_phys_cursor (w);
20099
20100 /* Don't check phys_cursor_on_p here because that flag is only set
20101 to zero in some cases where we know that the cursor has been
20102 completely erased, to avoid the extra work of erasing the cursor
20103 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20104 still not be visible, or it has only been partly erased. */
20105 if (on)
20106 {
20107 w->phys_cursor_ascent = glyph_row->ascent;
20108 w->phys_cursor_height = glyph_row->height;
20109
20110 /* Set phys_cursor_.* before x_draw_.* is called because some
20111 of them may need the information. */
20112 w->phys_cursor.x = x;
20113 w->phys_cursor.y = glyph_row->y;
20114 w->phys_cursor.hpos = hpos;
20115 w->phys_cursor.vpos = vpos;
20116 }
20117
20118 rif->draw_window_cursor (w, glyph_row, x, y,
20119 new_cursor_type, new_cursor_width,
20120 on, active_cursor);
20121 }
20122
20123
20124 /* Switch the display of W's cursor on or off, according to the value
20125 of ON. */
20126
20127 static void
20128 update_window_cursor (w, on)
20129 struct window *w;
20130 int on;
20131 {
20132 /* Don't update cursor in windows whose frame is in the process
20133 of being deleted. */
20134 if (w->current_matrix)
20135 {
20136 BLOCK_INPUT;
20137 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20138 w->phys_cursor.x, w->phys_cursor.y);
20139 UNBLOCK_INPUT;
20140 }
20141 }
20142
20143
20144 /* Call update_window_cursor with parameter ON_P on all leaf windows
20145 in the window tree rooted at W. */
20146
20147 static void
20148 update_cursor_in_window_tree (w, on_p)
20149 struct window *w;
20150 int on_p;
20151 {
20152 while (w)
20153 {
20154 if (!NILP (w->hchild))
20155 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20156 else if (!NILP (w->vchild))
20157 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20158 else
20159 update_window_cursor (w, on_p);
20160
20161 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20162 }
20163 }
20164
20165
20166 /* EXPORT:
20167 Display the cursor on window W, or clear it, according to ON_P.
20168 Don't change the cursor's position. */
20169
20170 void
20171 x_update_cursor (f, on_p)
20172 struct frame *f;
20173 int on_p;
20174 {
20175 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20176 }
20177
20178
20179 /* EXPORT:
20180 Clear the cursor of window W to background color, and mark the
20181 cursor as not shown. This is used when the text where the cursor
20182 is is about to be rewritten. */
20183
20184 void
20185 x_clear_cursor (w)
20186 struct window *w;
20187 {
20188 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20189 update_window_cursor (w, 0);
20190 }
20191
20192
20193 /* EXPORT:
20194 Display the active region described by mouse_face_* according to DRAW. */
20195
20196 void
20197 show_mouse_face (dpyinfo, draw)
20198 Display_Info *dpyinfo;
20199 enum draw_glyphs_face draw;
20200 {
20201 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20202 struct frame *f = XFRAME (WINDOW_FRAME (w));
20203
20204 if (/* If window is in the process of being destroyed, don't bother
20205 to do anything. */
20206 w->current_matrix != NULL
20207 /* Don't update mouse highlight if hidden */
20208 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20209 /* Recognize when we are called to operate on rows that don't exist
20210 anymore. This can happen when a window is split. */
20211 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20212 {
20213 int phys_cursor_on_p = w->phys_cursor_on_p;
20214 struct glyph_row *row, *first, *last;
20215
20216 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20217 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20218
20219 for (row = first; row <= last && row->enabled_p; ++row)
20220 {
20221 int start_hpos, end_hpos, start_x;
20222
20223 /* For all but the first row, the highlight starts at column 0. */
20224 if (row == first)
20225 {
20226 start_hpos = dpyinfo->mouse_face_beg_col;
20227 start_x = dpyinfo->mouse_face_beg_x;
20228 }
20229 else
20230 {
20231 start_hpos = 0;
20232 start_x = 0;
20233 }
20234
20235 if (row == last)
20236 end_hpos = dpyinfo->mouse_face_end_col;
20237 else
20238 end_hpos = row->used[TEXT_AREA];
20239
20240 if (end_hpos > start_hpos)
20241 {
20242 draw_glyphs (w, start_x, row, TEXT_AREA,
20243 start_hpos, end_hpos,
20244 draw, 0);
20245
20246 row->mouse_face_p
20247 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20248 }
20249 }
20250
20251 /* When we've written over the cursor, arrange for it to
20252 be displayed again. */
20253 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20254 {
20255 BLOCK_INPUT;
20256 display_and_set_cursor (w, 1,
20257 w->phys_cursor.hpos, w->phys_cursor.vpos,
20258 w->phys_cursor.x, w->phys_cursor.y);
20259 UNBLOCK_INPUT;
20260 }
20261 }
20262
20263 /* Change the mouse cursor. */
20264 if (draw == DRAW_NORMAL_TEXT)
20265 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20266 else if (draw == DRAW_MOUSE_FACE)
20267 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20268 else
20269 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20270 }
20271
20272 /* EXPORT:
20273 Clear out the mouse-highlighted active region.
20274 Redraw it un-highlighted first. Value is non-zero if mouse
20275 face was actually drawn unhighlighted. */
20276
20277 int
20278 clear_mouse_face (dpyinfo)
20279 Display_Info *dpyinfo;
20280 {
20281 int cleared = 0;
20282
20283 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20284 {
20285 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20286 cleared = 1;
20287 }
20288
20289 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20290 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20291 dpyinfo->mouse_face_window = Qnil;
20292 dpyinfo->mouse_face_overlay = Qnil;
20293 return cleared;
20294 }
20295
20296
20297 /* EXPORT:
20298 Non-zero if physical cursor of window W is within mouse face. */
20299
20300 int
20301 cursor_in_mouse_face_p (w)
20302 struct window *w;
20303 {
20304 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20305 int in_mouse_face = 0;
20306
20307 if (WINDOWP (dpyinfo->mouse_face_window)
20308 && XWINDOW (dpyinfo->mouse_face_window) == w)
20309 {
20310 int hpos = w->phys_cursor.hpos;
20311 int vpos = w->phys_cursor.vpos;
20312
20313 if (vpos >= dpyinfo->mouse_face_beg_row
20314 && vpos <= dpyinfo->mouse_face_end_row
20315 && (vpos > dpyinfo->mouse_face_beg_row
20316 || hpos >= dpyinfo->mouse_face_beg_col)
20317 && (vpos < dpyinfo->mouse_face_end_row
20318 || hpos < dpyinfo->mouse_face_end_col
20319 || dpyinfo->mouse_face_past_end))
20320 in_mouse_face = 1;
20321 }
20322
20323 return in_mouse_face;
20324 }
20325
20326
20327
20328 \f
20329 /* Find the glyph matrix position of buffer position CHARPOS in window
20330 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20331 current glyphs must be up to date. If CHARPOS is above window
20332 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20333 of last line in W. In the row containing CHARPOS, stop before glyphs
20334 having STOP as object. */
20335
20336 #if 1 /* This is a version of fast_find_position that's more correct
20337 in the presence of hscrolling, for example. I didn't install
20338 it right away because the problem fixed is minor, it failed
20339 in 20.x as well, and I think it's too risky to install
20340 so near the release of 21.1. 2001-09-25 gerd. */
20341
20342 static int
20343 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20344 struct window *w;
20345 int charpos;
20346 int *hpos, *vpos, *x, *y;
20347 Lisp_Object stop;
20348 {
20349 struct glyph_row *row, *first;
20350 struct glyph *glyph, *end;
20351 int past_end = 0;
20352
20353 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20354 row = row_containing_pos (w, charpos, first, NULL, 0);
20355 if (row == NULL)
20356 {
20357 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20358 {
20359 *x = *y = *hpos = *vpos = 0;
20360 return 1;
20361 }
20362 else
20363 {
20364 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20365 past_end = 1;
20366 }
20367 }
20368
20369 *x = row->x;
20370 *y = row->y;
20371 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20372
20373 glyph = row->glyphs[TEXT_AREA];
20374 end = glyph + row->used[TEXT_AREA];
20375
20376 /* Skip over glyphs not having an object at the start of the row.
20377 These are special glyphs like truncation marks on terminal
20378 frames. */
20379 if (row->displays_text_p)
20380 while (glyph < end
20381 && INTEGERP (glyph->object)
20382 && !EQ (stop, glyph->object)
20383 && glyph->charpos < 0)
20384 {
20385 *x += glyph->pixel_width;
20386 ++glyph;
20387 }
20388
20389 while (glyph < end
20390 && !INTEGERP (glyph->object)
20391 && !EQ (stop, glyph->object)
20392 && (!BUFFERP (glyph->object)
20393 || glyph->charpos < charpos))
20394 {
20395 *x += glyph->pixel_width;
20396 ++glyph;
20397 }
20398
20399 *hpos = glyph - row->glyphs[TEXT_AREA];
20400 return !past_end;
20401 }
20402
20403 #else /* not 1 */
20404
20405 static int
20406 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20407 struct window *w;
20408 int pos;
20409 int *hpos, *vpos, *x, *y;
20410 Lisp_Object stop;
20411 {
20412 int i;
20413 int lastcol;
20414 int maybe_next_line_p = 0;
20415 int line_start_position;
20416 int yb = window_text_bottom_y (w);
20417 struct glyph_row *row, *best_row;
20418 int row_vpos, best_row_vpos;
20419 int current_x;
20420
20421 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20422 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20423
20424 while (row->y < yb)
20425 {
20426 if (row->used[TEXT_AREA])
20427 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20428 else
20429 line_start_position = 0;
20430
20431 if (line_start_position > pos)
20432 break;
20433 /* If the position sought is the end of the buffer,
20434 don't include the blank lines at the bottom of the window. */
20435 else if (line_start_position == pos
20436 && pos == BUF_ZV (XBUFFER (w->buffer)))
20437 {
20438 maybe_next_line_p = 1;
20439 break;
20440 }
20441 else if (line_start_position > 0)
20442 {
20443 best_row = row;
20444 best_row_vpos = row_vpos;
20445 }
20446
20447 if (row->y + row->height >= yb)
20448 break;
20449
20450 ++row;
20451 ++row_vpos;
20452 }
20453
20454 /* Find the right column within BEST_ROW. */
20455 lastcol = 0;
20456 current_x = best_row->x;
20457 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20458 {
20459 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20460 int charpos = glyph->charpos;
20461
20462 if (BUFFERP (glyph->object))
20463 {
20464 if (charpos == pos)
20465 {
20466 *hpos = i;
20467 *vpos = best_row_vpos;
20468 *x = current_x;
20469 *y = best_row->y;
20470 return 1;
20471 }
20472 else if (charpos > pos)
20473 break;
20474 }
20475 else if (EQ (glyph->object, stop))
20476 break;
20477
20478 if (charpos > 0)
20479 lastcol = i;
20480 current_x += glyph->pixel_width;
20481 }
20482
20483 /* If we're looking for the end of the buffer,
20484 and we didn't find it in the line we scanned,
20485 use the start of the following line. */
20486 if (maybe_next_line_p)
20487 {
20488 ++best_row;
20489 ++best_row_vpos;
20490 lastcol = 0;
20491 current_x = best_row->x;
20492 }
20493
20494 *vpos = best_row_vpos;
20495 *hpos = lastcol + 1;
20496 *x = current_x;
20497 *y = best_row->y;
20498 return 0;
20499 }
20500
20501 #endif /* not 1 */
20502
20503
20504 /* Find the position of the glyph for position POS in OBJECT in
20505 window W's current matrix, and return in *X, *Y the pixel
20506 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20507
20508 RIGHT_P non-zero means return the position of the right edge of the
20509 glyph, RIGHT_P zero means return the left edge position.
20510
20511 If no glyph for POS exists in the matrix, return the position of
20512 the glyph with the next smaller position that is in the matrix, if
20513 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20514 exists in the matrix, return the position of the glyph with the
20515 next larger position in OBJECT.
20516
20517 Value is non-zero if a glyph was found. */
20518
20519 static int
20520 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20521 struct window *w;
20522 int pos;
20523 Lisp_Object object;
20524 int *hpos, *vpos, *x, *y;
20525 int right_p;
20526 {
20527 int yb = window_text_bottom_y (w);
20528 struct glyph_row *r;
20529 struct glyph *best_glyph = NULL;
20530 struct glyph_row *best_row = NULL;
20531 int best_x = 0;
20532
20533 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20534 r->enabled_p && r->y < yb;
20535 ++r)
20536 {
20537 struct glyph *g = r->glyphs[TEXT_AREA];
20538 struct glyph *e = g + r->used[TEXT_AREA];
20539 int gx;
20540
20541 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20542 if (EQ (g->object, object))
20543 {
20544 if (g->charpos == pos)
20545 {
20546 best_glyph = g;
20547 best_x = gx;
20548 best_row = r;
20549 goto found;
20550 }
20551 else if (best_glyph == NULL
20552 || ((abs (g->charpos - pos)
20553 < abs (best_glyph->charpos - pos))
20554 && (right_p
20555 ? g->charpos < pos
20556 : g->charpos > pos)))
20557 {
20558 best_glyph = g;
20559 best_x = gx;
20560 best_row = r;
20561 }
20562 }
20563 }
20564
20565 found:
20566
20567 if (best_glyph)
20568 {
20569 *x = best_x;
20570 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20571
20572 if (right_p)
20573 {
20574 *x += best_glyph->pixel_width;
20575 ++*hpos;
20576 }
20577
20578 *y = best_row->y;
20579 *vpos = best_row - w->current_matrix->rows;
20580 }
20581
20582 return best_glyph != NULL;
20583 }
20584
20585
20586 /* See if position X, Y is within a hot-spot of an image. */
20587
20588 static int
20589 on_hot_spot_p (hot_spot, x, y)
20590 Lisp_Object hot_spot;
20591 int x, y;
20592 {
20593 if (!CONSP (hot_spot))
20594 return 0;
20595
20596 if (EQ (XCAR (hot_spot), Qrect))
20597 {
20598 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20599 Lisp_Object rect = XCDR (hot_spot);
20600 Lisp_Object tem;
20601 if (!CONSP (rect))
20602 return 0;
20603 if (!CONSP (XCAR (rect)))
20604 return 0;
20605 if (!CONSP (XCDR (rect)))
20606 return 0;
20607 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20608 return 0;
20609 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20610 return 0;
20611 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20612 return 0;
20613 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20614 return 0;
20615 return 1;
20616 }
20617 else if (EQ (XCAR (hot_spot), Qcircle))
20618 {
20619 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20620 Lisp_Object circ = XCDR (hot_spot);
20621 Lisp_Object lr, lx0, ly0;
20622 if (CONSP (circ)
20623 && CONSP (XCAR (circ))
20624 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20625 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20626 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20627 {
20628 double r = XFLOATINT (lr);
20629 double dx = XINT (lx0) - x;
20630 double dy = XINT (ly0) - y;
20631 return (dx * dx + dy * dy <= r * r);
20632 }
20633 }
20634 else if (EQ (XCAR (hot_spot), Qpoly))
20635 {
20636 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20637 if (VECTORP (XCDR (hot_spot)))
20638 {
20639 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20640 Lisp_Object *poly = v->contents;
20641 int n = v->size;
20642 int i;
20643 int inside = 0;
20644 Lisp_Object lx, ly;
20645 int x0, y0;
20646
20647 /* Need an even number of coordinates, and at least 3 edges. */
20648 if (n < 6 || n & 1)
20649 return 0;
20650
20651 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20652 If count is odd, we are inside polygon. Pixels on edges
20653 may or may not be included depending on actual geometry of the
20654 polygon. */
20655 if ((lx = poly[n-2], !INTEGERP (lx))
20656 || (ly = poly[n-1], !INTEGERP (lx)))
20657 return 0;
20658 x0 = XINT (lx), y0 = XINT (ly);
20659 for (i = 0; i < n; i += 2)
20660 {
20661 int x1 = x0, y1 = y0;
20662 if ((lx = poly[i], !INTEGERP (lx))
20663 || (ly = poly[i+1], !INTEGERP (ly)))
20664 return 0;
20665 x0 = XINT (lx), y0 = XINT (ly);
20666
20667 /* Does this segment cross the X line? */
20668 if (x0 >= x)
20669 {
20670 if (x1 >= x)
20671 continue;
20672 }
20673 else if (x1 < x)
20674 continue;
20675 if (y > y0 && y > y1)
20676 continue;
20677 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20678 inside = !inside;
20679 }
20680 return inside;
20681 }
20682 }
20683 /* If we don't understand the format, pretend we're not in the hot-spot. */
20684 return 0;
20685 }
20686
20687 Lisp_Object
20688 find_hot_spot (map, x, y)
20689 Lisp_Object map;
20690 int x, y;
20691 {
20692 while (CONSP (map))
20693 {
20694 if (CONSP (XCAR (map))
20695 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20696 return XCAR (map);
20697 map = XCDR (map);
20698 }
20699
20700 return Qnil;
20701 }
20702
20703 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20704 3, 3, 0,
20705 doc: /* Lookup in image map MAP coordinates X and Y.
20706 An image map is an alist where each element has the format (AREA ID PLIST).
20707 An AREA is specified as either a rectangle, a circle, or a polygon:
20708 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20709 pixel coordinates of the upper left and bottom right corners.
20710 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20711 and the radius of the circle; r may be a float or integer.
20712 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20713 vector describes one corner in the polygon.
20714 Returns the alist element for the first matching AREA in MAP. */)
20715 (map, x, y)
20716 Lisp_Object map;
20717 Lisp_Object x, y;
20718 {
20719 if (NILP (map))
20720 return Qnil;
20721
20722 CHECK_NUMBER (x);
20723 CHECK_NUMBER (y);
20724
20725 return find_hot_spot (map, XINT (x), XINT (y));
20726 }
20727
20728
20729 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20730 static void
20731 define_frame_cursor1 (f, cursor, pointer)
20732 struct frame *f;
20733 Cursor cursor;
20734 Lisp_Object pointer;
20735 {
20736 if (!NILP (pointer))
20737 {
20738 if (EQ (pointer, Qarrow))
20739 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20740 else if (EQ (pointer, Qhand))
20741 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20742 else if (EQ (pointer, Qtext))
20743 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20744 else if (EQ (pointer, intern ("hdrag")))
20745 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20746 #ifdef HAVE_X_WINDOWS
20747 else if (EQ (pointer, intern ("vdrag")))
20748 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20749 #endif
20750 else if (EQ (pointer, intern ("hourglass")))
20751 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20752 else if (EQ (pointer, Qmodeline))
20753 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20754 else
20755 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20756 }
20757
20758 if (cursor != No_Cursor)
20759 rif->define_frame_cursor (f, cursor);
20760 }
20761
20762 /* Take proper action when mouse has moved to the mode or header line
20763 or marginal area AREA of window W, x-position X and y-position Y.
20764 X is relative to the start of the text display area of W, so the
20765 width of bitmap areas and scroll bars must be subtracted to get a
20766 position relative to the start of the mode line. */
20767
20768 static void
20769 note_mode_line_or_margin_highlight (w, x, y, area)
20770 struct window *w;
20771 int x, y;
20772 enum window_part area;
20773 {
20774 struct frame *f = XFRAME (w->frame);
20775 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20776 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20777 Lisp_Object pointer = Qnil;
20778 int charpos, dx, dy, width, height;
20779 Lisp_Object string, object = Qnil;
20780 Lisp_Object pos, help;
20781
20782 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20783 string = mode_line_string (w, area, &x, &y, &charpos,
20784 &object, &dx, &dy, &width, &height);
20785 else
20786 {
20787 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20788 string = marginal_area_string (w, area, &x, &y, &charpos,
20789 &object, &dx, &dy, &width, &height);
20790 }
20791
20792 help = Qnil;
20793
20794 if (IMAGEP (object))
20795 {
20796 Lisp_Object image_map, hotspot;
20797 if ((image_map = Fplist_get (XCDR (object), QCmap),
20798 !NILP (image_map))
20799 && (hotspot = find_hot_spot (image_map, dx, dy),
20800 CONSP (hotspot))
20801 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20802 {
20803 Lisp_Object area_id, plist;
20804
20805 area_id = XCAR (hotspot);
20806 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20807 If so, we could look for mouse-enter, mouse-leave
20808 properties in PLIST (and do something...). */
20809 if ((plist = XCDR (hotspot), CONSP (plist)))
20810 {
20811 pointer = Fplist_get (plist, Qpointer);
20812 if (NILP (pointer))
20813 pointer = Qhand;
20814 help = Fplist_get (plist, Qhelp_echo);
20815 if (!NILP (help))
20816 {
20817 help_echo_string = help;
20818 /* Is this correct? ++kfs */
20819 XSETWINDOW (help_echo_window, w);
20820 help_echo_object = w->buffer;
20821 help_echo_pos = charpos;
20822 }
20823 }
20824 if (NILP (pointer))
20825 pointer = Fplist_get (XCDR (object), QCpointer);
20826 }
20827 }
20828
20829 if (STRINGP (string))
20830 {
20831 pos = make_number (charpos);
20832 /* If we're on a string with `help-echo' text property, arrange
20833 for the help to be displayed. This is done by setting the
20834 global variable help_echo_string to the help string. */
20835 help = Fget_text_property (pos, Qhelp_echo, string);
20836 if (!NILP (help))
20837 {
20838 help_echo_string = help;
20839 XSETWINDOW (help_echo_window, w);
20840 help_echo_object = string;
20841 help_echo_pos = charpos;
20842 }
20843
20844 if (NILP (pointer))
20845 pointer = Fget_text_property (pos, Qpointer, string);
20846
20847 /* Change the mouse pointer according to what is under X/Y. */
20848 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20849 {
20850 Lisp_Object map;
20851 map = Fget_text_property (pos, Qlocal_map, string);
20852 if (!KEYMAPP (map))
20853 map = Fget_text_property (pos, Qkeymap, string);
20854 if (!KEYMAPP (map))
20855 cursor = dpyinfo->vertical_scroll_bar_cursor;
20856 }
20857 }
20858
20859 define_frame_cursor1 (f, cursor, pointer);
20860 }
20861
20862
20863 /* EXPORT:
20864 Take proper action when the mouse has moved to position X, Y on
20865 frame F as regards highlighting characters that have mouse-face
20866 properties. Also de-highlighting chars where the mouse was before.
20867 X and Y can be negative or out of range. */
20868
20869 void
20870 note_mouse_highlight (f, x, y)
20871 struct frame *f;
20872 int x, y;
20873 {
20874 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20875 enum window_part part;
20876 Lisp_Object window;
20877 struct window *w;
20878 Cursor cursor = No_Cursor;
20879 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20880 struct buffer *b;
20881
20882 /* When a menu is active, don't highlight because this looks odd. */
20883 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20884 if (popup_activated ())
20885 return;
20886 #endif
20887
20888 if (NILP (Vmouse_highlight)
20889 || !f->glyphs_initialized_p)
20890 return;
20891
20892 dpyinfo->mouse_face_mouse_x = x;
20893 dpyinfo->mouse_face_mouse_y = y;
20894 dpyinfo->mouse_face_mouse_frame = f;
20895
20896 if (dpyinfo->mouse_face_defer)
20897 return;
20898
20899 if (gc_in_progress)
20900 {
20901 dpyinfo->mouse_face_deferred_gc = 1;
20902 return;
20903 }
20904
20905 /* Which window is that in? */
20906 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20907
20908 /* If we were displaying active text in another window, clear that. */
20909 if (! EQ (window, dpyinfo->mouse_face_window))
20910 clear_mouse_face (dpyinfo);
20911
20912 /* Not on a window -> return. */
20913 if (!WINDOWP (window))
20914 return;
20915
20916 /* Reset help_echo_string. It will get recomputed below. */
20917 help_echo_string = Qnil;
20918
20919 /* Convert to window-relative pixel coordinates. */
20920 w = XWINDOW (window);
20921 frame_to_window_pixel_xy (w, &x, &y);
20922
20923 /* Handle tool-bar window differently since it doesn't display a
20924 buffer. */
20925 if (EQ (window, f->tool_bar_window))
20926 {
20927 note_tool_bar_highlight (f, x, y);
20928 return;
20929 }
20930
20931 /* Mouse is on the mode, header line or margin? */
20932 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20933 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20934 {
20935 note_mode_line_or_margin_highlight (w, x, y, part);
20936 return;
20937 }
20938
20939 if (part == ON_VERTICAL_BORDER)
20940 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20941 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
20942 || part == ON_SCROLL_BAR)
20943 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20944 else
20945 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20946
20947 /* Are we in a window whose display is up to date?
20948 And verify the buffer's text has not changed. */
20949 b = XBUFFER (w->buffer);
20950 if (part == ON_TEXT
20951 && EQ (w->window_end_valid, w->buffer)
20952 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20953 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20954 {
20955 int hpos, vpos, pos, i, dx, dy, area;
20956 struct glyph *glyph;
20957 Lisp_Object object;
20958 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20959 Lisp_Object *overlay_vec = NULL;
20960 int noverlays;
20961 struct buffer *obuf;
20962 int obegv, ozv, same_region;
20963
20964 /* Find the glyph under X/Y. */
20965 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20966
20967 /* Look for :pointer property on image. */
20968 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20969 {
20970 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20971 if (img != NULL && IMAGEP (img->spec))
20972 {
20973 Lisp_Object image_map, hotspot;
20974 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20975 !NILP (image_map))
20976 && (hotspot = find_hot_spot (image_map,
20977 glyph->slice.x + dx,
20978 glyph->slice.y + dy),
20979 CONSP (hotspot))
20980 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20981 {
20982 Lisp_Object area_id, plist;
20983
20984 area_id = XCAR (hotspot);
20985 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20986 If so, we could look for mouse-enter, mouse-leave
20987 properties in PLIST (and do something...). */
20988 if ((plist = XCDR (hotspot), CONSP (plist)))
20989 {
20990 pointer = Fplist_get (plist, Qpointer);
20991 if (NILP (pointer))
20992 pointer = Qhand;
20993 help_echo_string = Fplist_get (plist, Qhelp_echo);
20994 if (!NILP (help_echo_string))
20995 {
20996 help_echo_window = window;
20997 help_echo_object = glyph->object;
20998 help_echo_pos = glyph->charpos;
20999 }
21000 }
21001 }
21002 if (NILP (pointer))
21003 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21004 }
21005 }
21006
21007 /* Clear mouse face if X/Y not over text. */
21008 if (glyph == NULL
21009 || area != TEXT_AREA
21010 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21011 {
21012 if (clear_mouse_face (dpyinfo))
21013 cursor = No_Cursor;
21014 if (NILP (pointer))
21015 {
21016 if (area != TEXT_AREA)
21017 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21018 else
21019 pointer = Vvoid_text_area_pointer;
21020 }
21021 goto set_cursor;
21022 }
21023
21024 pos = glyph->charpos;
21025 object = glyph->object;
21026 if (!STRINGP (object) && !BUFFERP (object))
21027 goto set_cursor;
21028
21029 /* If we get an out-of-range value, return now; avoid an error. */
21030 if (BUFFERP (object) && pos > BUF_Z (b))
21031 goto set_cursor;
21032
21033 /* Make the window's buffer temporarily current for
21034 overlays_at and compute_char_face. */
21035 obuf = current_buffer;
21036 current_buffer = b;
21037 obegv = BEGV;
21038 ozv = ZV;
21039 BEGV = BEG;
21040 ZV = Z;
21041
21042 /* Is this char mouse-active or does it have help-echo? */
21043 position = make_number (pos);
21044
21045 if (BUFFERP (object))
21046 {
21047 /* Put all the overlays we want in a vector in overlay_vec. */
21048 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21049 /* Sort overlays into increasing priority order. */
21050 noverlays = sort_overlays (overlay_vec, noverlays, w);
21051 }
21052 else
21053 noverlays = 0;
21054
21055 same_region = (EQ (window, dpyinfo->mouse_face_window)
21056 && vpos >= dpyinfo->mouse_face_beg_row
21057 && vpos <= dpyinfo->mouse_face_end_row
21058 && (vpos > dpyinfo->mouse_face_beg_row
21059 || hpos >= dpyinfo->mouse_face_beg_col)
21060 && (vpos < dpyinfo->mouse_face_end_row
21061 || hpos < dpyinfo->mouse_face_end_col
21062 || dpyinfo->mouse_face_past_end));
21063
21064 if (same_region)
21065 cursor = No_Cursor;
21066
21067 /* Check mouse-face highlighting. */
21068 if (! same_region
21069 /* If there exists an overlay with mouse-face overlapping
21070 the one we are currently highlighting, we have to
21071 check if we enter the overlapping overlay, and then
21072 highlight only that. */
21073 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21074 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21075 {
21076 /* Find the highest priority overlay that has a mouse-face
21077 property. */
21078 overlay = Qnil;
21079 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21080 {
21081 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21082 if (!NILP (mouse_face))
21083 overlay = overlay_vec[i];
21084 }
21085
21086 /* If we're actually highlighting the same overlay as
21087 before, there's no need to do that again. */
21088 if (!NILP (overlay)
21089 && EQ (overlay, dpyinfo->mouse_face_overlay))
21090 goto check_help_echo;
21091
21092 dpyinfo->mouse_face_overlay = overlay;
21093
21094 /* Clear the display of the old active region, if any. */
21095 if (clear_mouse_face (dpyinfo))
21096 cursor = No_Cursor;
21097
21098 /* If no overlay applies, get a text property. */
21099 if (NILP (overlay))
21100 mouse_face = Fget_text_property (position, Qmouse_face, object);
21101
21102 /* Handle the overlay case. */
21103 if (!NILP (overlay))
21104 {
21105 /* Find the range of text around this char that
21106 should be active. */
21107 Lisp_Object before, after;
21108 int ignore;
21109
21110 before = Foverlay_start (overlay);
21111 after = Foverlay_end (overlay);
21112 /* Record this as the current active region. */
21113 fast_find_position (w, XFASTINT (before),
21114 &dpyinfo->mouse_face_beg_col,
21115 &dpyinfo->mouse_face_beg_row,
21116 &dpyinfo->mouse_face_beg_x,
21117 &dpyinfo->mouse_face_beg_y, Qnil);
21118
21119 dpyinfo->mouse_face_past_end
21120 = !fast_find_position (w, XFASTINT (after),
21121 &dpyinfo->mouse_face_end_col,
21122 &dpyinfo->mouse_face_end_row,
21123 &dpyinfo->mouse_face_end_x,
21124 &dpyinfo->mouse_face_end_y, Qnil);
21125 dpyinfo->mouse_face_window = window;
21126
21127 dpyinfo->mouse_face_face_id
21128 = face_at_buffer_position (w, pos, 0, 0,
21129 &ignore, pos + 1,
21130 !dpyinfo->mouse_face_hidden);
21131
21132 /* Display it as active. */
21133 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21134 cursor = No_Cursor;
21135 }
21136 /* Handle the text property case. */
21137 else if (!NILP (mouse_face) && BUFFERP (object))
21138 {
21139 /* Find the range of text around this char that
21140 should be active. */
21141 Lisp_Object before, after, beginning, end;
21142 int ignore;
21143
21144 beginning = Fmarker_position (w->start);
21145 end = make_number (BUF_Z (XBUFFER (object))
21146 - XFASTINT (w->window_end_pos));
21147 before
21148 = Fprevious_single_property_change (make_number (pos + 1),
21149 Qmouse_face,
21150 object, beginning);
21151 after
21152 = Fnext_single_property_change (position, Qmouse_face,
21153 object, end);
21154
21155 /* Record this as the current active region. */
21156 fast_find_position (w, XFASTINT (before),
21157 &dpyinfo->mouse_face_beg_col,
21158 &dpyinfo->mouse_face_beg_row,
21159 &dpyinfo->mouse_face_beg_x,
21160 &dpyinfo->mouse_face_beg_y, Qnil);
21161 dpyinfo->mouse_face_past_end
21162 = !fast_find_position (w, XFASTINT (after),
21163 &dpyinfo->mouse_face_end_col,
21164 &dpyinfo->mouse_face_end_row,
21165 &dpyinfo->mouse_face_end_x,
21166 &dpyinfo->mouse_face_end_y, Qnil);
21167 dpyinfo->mouse_face_window = window;
21168
21169 if (BUFFERP (object))
21170 dpyinfo->mouse_face_face_id
21171 = face_at_buffer_position (w, pos, 0, 0,
21172 &ignore, pos + 1,
21173 !dpyinfo->mouse_face_hidden);
21174
21175 /* Display it as active. */
21176 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21177 cursor = No_Cursor;
21178 }
21179 else if (!NILP (mouse_face) && STRINGP (object))
21180 {
21181 Lisp_Object b, e;
21182 int ignore;
21183
21184 b = Fprevious_single_property_change (make_number (pos + 1),
21185 Qmouse_face,
21186 object, Qnil);
21187 e = Fnext_single_property_change (position, Qmouse_face,
21188 object, Qnil);
21189 if (NILP (b))
21190 b = make_number (0);
21191 if (NILP (e))
21192 e = make_number (SCHARS (object) - 1);
21193 fast_find_string_pos (w, XINT (b), object,
21194 &dpyinfo->mouse_face_beg_col,
21195 &dpyinfo->mouse_face_beg_row,
21196 &dpyinfo->mouse_face_beg_x,
21197 &dpyinfo->mouse_face_beg_y, 0);
21198 fast_find_string_pos (w, XINT (e), object,
21199 &dpyinfo->mouse_face_end_col,
21200 &dpyinfo->mouse_face_end_row,
21201 &dpyinfo->mouse_face_end_x,
21202 &dpyinfo->mouse_face_end_y, 1);
21203 dpyinfo->mouse_face_past_end = 0;
21204 dpyinfo->mouse_face_window = window;
21205 dpyinfo->mouse_face_face_id
21206 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21207 glyph->face_id, 1);
21208 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21209 cursor = No_Cursor;
21210 }
21211 else if (STRINGP (object) && NILP (mouse_face))
21212 {
21213 /* A string which doesn't have mouse-face, but
21214 the text ``under'' it might have. */
21215 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21216 int start = MATRIX_ROW_START_CHARPOS (r);
21217
21218 pos = string_buffer_position (w, object, start);
21219 if (pos > 0)
21220 mouse_face = get_char_property_and_overlay (make_number (pos),
21221 Qmouse_face,
21222 w->buffer,
21223 &overlay);
21224 if (!NILP (mouse_face) && !NILP (overlay))
21225 {
21226 Lisp_Object before = Foverlay_start (overlay);
21227 Lisp_Object after = Foverlay_end (overlay);
21228 int ignore;
21229
21230 /* Note that we might not be able to find position
21231 BEFORE in the glyph matrix if the overlay is
21232 entirely covered by a `display' property. In
21233 this case, we overshoot. So let's stop in
21234 the glyph matrix before glyphs for OBJECT. */
21235 fast_find_position (w, XFASTINT (before),
21236 &dpyinfo->mouse_face_beg_col,
21237 &dpyinfo->mouse_face_beg_row,
21238 &dpyinfo->mouse_face_beg_x,
21239 &dpyinfo->mouse_face_beg_y,
21240 object);
21241
21242 dpyinfo->mouse_face_past_end
21243 = !fast_find_position (w, XFASTINT (after),
21244 &dpyinfo->mouse_face_end_col,
21245 &dpyinfo->mouse_face_end_row,
21246 &dpyinfo->mouse_face_end_x,
21247 &dpyinfo->mouse_face_end_y,
21248 Qnil);
21249 dpyinfo->mouse_face_window = window;
21250 dpyinfo->mouse_face_face_id
21251 = face_at_buffer_position (w, pos, 0, 0,
21252 &ignore, pos + 1,
21253 !dpyinfo->mouse_face_hidden);
21254
21255 /* Display it as active. */
21256 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21257 cursor = No_Cursor;
21258 }
21259 }
21260 }
21261
21262 check_help_echo:
21263
21264 /* Look for a `help-echo' property. */
21265 if (NILP (help_echo_string)) {
21266 Lisp_Object help, overlay;
21267
21268 /* Check overlays first. */
21269 help = overlay = Qnil;
21270 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21271 {
21272 overlay = overlay_vec[i];
21273 help = Foverlay_get (overlay, Qhelp_echo);
21274 }
21275
21276 if (!NILP (help))
21277 {
21278 help_echo_string = help;
21279 help_echo_window = window;
21280 help_echo_object = overlay;
21281 help_echo_pos = pos;
21282 }
21283 else
21284 {
21285 Lisp_Object object = glyph->object;
21286 int charpos = glyph->charpos;
21287
21288 /* Try text properties. */
21289 if (STRINGP (object)
21290 && charpos >= 0
21291 && charpos < SCHARS (object))
21292 {
21293 help = Fget_text_property (make_number (charpos),
21294 Qhelp_echo, object);
21295 if (NILP (help))
21296 {
21297 /* If the string itself doesn't specify a help-echo,
21298 see if the buffer text ``under'' it does. */
21299 struct glyph_row *r
21300 = MATRIX_ROW (w->current_matrix, vpos);
21301 int start = MATRIX_ROW_START_CHARPOS (r);
21302 int pos = string_buffer_position (w, object, start);
21303 if (pos > 0)
21304 {
21305 help = Fget_char_property (make_number (pos),
21306 Qhelp_echo, w->buffer);
21307 if (!NILP (help))
21308 {
21309 charpos = pos;
21310 object = w->buffer;
21311 }
21312 }
21313 }
21314 }
21315 else if (BUFFERP (object)
21316 && charpos >= BEGV
21317 && charpos < ZV)
21318 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21319 object);
21320
21321 if (!NILP (help))
21322 {
21323 help_echo_string = help;
21324 help_echo_window = window;
21325 help_echo_object = object;
21326 help_echo_pos = charpos;
21327 }
21328 }
21329 }
21330
21331 /* Look for a `pointer' property. */
21332 if (NILP (pointer))
21333 {
21334 /* Check overlays first. */
21335 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21336 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21337
21338 if (NILP (pointer))
21339 {
21340 Lisp_Object object = glyph->object;
21341 int charpos = glyph->charpos;
21342
21343 /* Try text properties. */
21344 if (STRINGP (object)
21345 && charpos >= 0
21346 && charpos < SCHARS (object))
21347 {
21348 pointer = Fget_text_property (make_number (charpos),
21349 Qpointer, object);
21350 if (NILP (pointer))
21351 {
21352 /* If the string itself doesn't specify a pointer,
21353 see if the buffer text ``under'' it does. */
21354 struct glyph_row *r
21355 = MATRIX_ROW (w->current_matrix, vpos);
21356 int start = MATRIX_ROW_START_CHARPOS (r);
21357 int pos = string_buffer_position (w, object, start);
21358 if (pos > 0)
21359 pointer = Fget_char_property (make_number (pos),
21360 Qpointer, w->buffer);
21361 }
21362 }
21363 else if (BUFFERP (object)
21364 && charpos >= BEGV
21365 && charpos < ZV)
21366 pointer = Fget_text_property (make_number (charpos),
21367 Qpointer, object);
21368 }
21369 }
21370
21371 BEGV = obegv;
21372 ZV = ozv;
21373 current_buffer = obuf;
21374 }
21375
21376 set_cursor:
21377
21378 define_frame_cursor1 (f, cursor, pointer);
21379 }
21380
21381
21382 /* EXPORT for RIF:
21383 Clear any mouse-face on window W. This function is part of the
21384 redisplay interface, and is called from try_window_id and similar
21385 functions to ensure the mouse-highlight is off. */
21386
21387 void
21388 x_clear_window_mouse_face (w)
21389 struct window *w;
21390 {
21391 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21392 Lisp_Object window;
21393
21394 BLOCK_INPUT;
21395 XSETWINDOW (window, w);
21396 if (EQ (window, dpyinfo->mouse_face_window))
21397 clear_mouse_face (dpyinfo);
21398 UNBLOCK_INPUT;
21399 }
21400
21401
21402 /* EXPORT:
21403 Just discard the mouse face information for frame F, if any.
21404 This is used when the size of F is changed. */
21405
21406 void
21407 cancel_mouse_face (f)
21408 struct frame *f;
21409 {
21410 Lisp_Object window;
21411 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21412
21413 window = dpyinfo->mouse_face_window;
21414 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21415 {
21416 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21417 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21418 dpyinfo->mouse_face_window = Qnil;
21419 }
21420 }
21421
21422
21423 #endif /* HAVE_WINDOW_SYSTEM */
21424
21425 \f
21426 /***********************************************************************
21427 Exposure Events
21428 ***********************************************************************/
21429
21430 #ifdef HAVE_WINDOW_SYSTEM
21431
21432 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21433 which intersects rectangle R. R is in window-relative coordinates. */
21434
21435 static void
21436 expose_area (w, row, r, area)
21437 struct window *w;
21438 struct glyph_row *row;
21439 XRectangle *r;
21440 enum glyph_row_area area;
21441 {
21442 struct glyph *first = row->glyphs[area];
21443 struct glyph *end = row->glyphs[area] + row->used[area];
21444 struct glyph *last;
21445 int first_x, start_x, x;
21446
21447 if (area == TEXT_AREA && row->fill_line_p)
21448 /* If row extends face to end of line write the whole line. */
21449 draw_glyphs (w, 0, row, area,
21450 0, row->used[area],
21451 DRAW_NORMAL_TEXT, 0);
21452 else
21453 {
21454 /* Set START_X to the window-relative start position for drawing glyphs of
21455 AREA. The first glyph of the text area can be partially visible.
21456 The first glyphs of other areas cannot. */
21457 start_x = window_box_left_offset (w, area);
21458 x = start_x;
21459 if (area == TEXT_AREA)
21460 x += row->x;
21461
21462 /* Find the first glyph that must be redrawn. */
21463 while (first < end
21464 && x + first->pixel_width < r->x)
21465 {
21466 x += first->pixel_width;
21467 ++first;
21468 }
21469
21470 /* Find the last one. */
21471 last = first;
21472 first_x = x;
21473 while (last < end
21474 && x < r->x + r->width)
21475 {
21476 x += last->pixel_width;
21477 ++last;
21478 }
21479
21480 /* Repaint. */
21481 if (last > first)
21482 draw_glyphs (w, first_x - start_x, row, area,
21483 first - row->glyphs[area], last - row->glyphs[area],
21484 DRAW_NORMAL_TEXT, 0);
21485 }
21486 }
21487
21488
21489 /* Redraw the parts of the glyph row ROW on window W intersecting
21490 rectangle R. R is in window-relative coordinates. Value is
21491 non-zero if mouse-face was overwritten. */
21492
21493 static int
21494 expose_line (w, row, r)
21495 struct window *w;
21496 struct glyph_row *row;
21497 XRectangle *r;
21498 {
21499 xassert (row->enabled_p);
21500
21501 if (row->mode_line_p || w->pseudo_window_p)
21502 draw_glyphs (w, 0, row, TEXT_AREA,
21503 0, row->used[TEXT_AREA],
21504 DRAW_NORMAL_TEXT, 0);
21505 else
21506 {
21507 if (row->used[LEFT_MARGIN_AREA])
21508 expose_area (w, row, r, LEFT_MARGIN_AREA);
21509 if (row->used[TEXT_AREA])
21510 expose_area (w, row, r, TEXT_AREA);
21511 if (row->used[RIGHT_MARGIN_AREA])
21512 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21513 draw_row_fringe_bitmaps (w, row);
21514 }
21515
21516 return row->mouse_face_p;
21517 }
21518
21519
21520 /* Redraw those parts of glyphs rows during expose event handling that
21521 overlap other rows. Redrawing of an exposed line writes over parts
21522 of lines overlapping that exposed line; this function fixes that.
21523
21524 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21525 row in W's current matrix that is exposed and overlaps other rows.
21526 LAST_OVERLAPPING_ROW is the last such row. */
21527
21528 static void
21529 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21530 struct window *w;
21531 struct glyph_row *first_overlapping_row;
21532 struct glyph_row *last_overlapping_row;
21533 {
21534 struct glyph_row *row;
21535
21536 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21537 if (row->overlapping_p)
21538 {
21539 xassert (row->enabled_p && !row->mode_line_p);
21540
21541 if (row->used[LEFT_MARGIN_AREA])
21542 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21543
21544 if (row->used[TEXT_AREA])
21545 x_fix_overlapping_area (w, row, TEXT_AREA);
21546
21547 if (row->used[RIGHT_MARGIN_AREA])
21548 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21549 }
21550 }
21551
21552
21553 /* Return non-zero if W's cursor intersects rectangle R. */
21554
21555 static int
21556 phys_cursor_in_rect_p (w, r)
21557 struct window *w;
21558 XRectangle *r;
21559 {
21560 XRectangle cr, result;
21561 struct glyph *cursor_glyph;
21562
21563 cursor_glyph = get_phys_cursor_glyph (w);
21564 if (cursor_glyph)
21565 {
21566 /* r is relative to W's box, but w->phys_cursor.x is relative
21567 to left edge of W's TEXT area. Adjust it. */
21568 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21569 cr.y = w->phys_cursor.y;
21570 cr.width = cursor_glyph->pixel_width;
21571 cr.height = w->phys_cursor_height;
21572 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21573 I assume the effect is the same -- and this is portable. */
21574 return x_intersect_rectangles (&cr, r, &result);
21575 }
21576 else
21577 return 0;
21578 }
21579
21580
21581 /* EXPORT:
21582 Draw a vertical window border to the right of window W if W doesn't
21583 have vertical scroll bars. */
21584
21585 void
21586 x_draw_vertical_border (w)
21587 struct window *w;
21588 {
21589 /* We could do better, if we knew what type of scroll-bar the adjacent
21590 windows (on either side) have... But we don't :-(
21591 However, I think this works ok. ++KFS 2003-04-25 */
21592
21593 /* Redraw borders between horizontally adjacent windows. Don't
21594 do it for frames with vertical scroll bars because either the
21595 right scroll bar of a window, or the left scroll bar of its
21596 neighbor will suffice as a border. */
21597 if (!WINDOW_RIGHTMOST_P (w)
21598 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21599 {
21600 int x0, x1, y0, y1;
21601
21602 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21603 y1 -= 1;
21604
21605 rif->draw_vertical_window_border (w, x1, y0, y1);
21606 }
21607 else if (!WINDOW_LEFTMOST_P (w)
21608 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21609 {
21610 int x0, x1, y0, y1;
21611
21612 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21613 y1 -= 1;
21614
21615 rif->draw_vertical_window_border (w, x0, y0, y1);
21616 }
21617 }
21618
21619
21620 /* Redraw the part of window W intersection rectangle FR. Pixel
21621 coordinates in FR are frame-relative. Call this function with
21622 input blocked. Value is non-zero if the exposure overwrites
21623 mouse-face. */
21624
21625 static int
21626 expose_window (w, fr)
21627 struct window *w;
21628 XRectangle *fr;
21629 {
21630 struct frame *f = XFRAME (w->frame);
21631 XRectangle wr, r;
21632 int mouse_face_overwritten_p = 0;
21633
21634 /* If window is not yet fully initialized, do nothing. This can
21635 happen when toolkit scroll bars are used and a window is split.
21636 Reconfiguring the scroll bar will generate an expose for a newly
21637 created window. */
21638 if (w->current_matrix == NULL)
21639 return 0;
21640
21641 /* When we're currently updating the window, display and current
21642 matrix usually don't agree. Arrange for a thorough display
21643 later. */
21644 if (w == updated_window)
21645 {
21646 SET_FRAME_GARBAGED (f);
21647 return 0;
21648 }
21649
21650 /* Frame-relative pixel rectangle of W. */
21651 wr.x = WINDOW_LEFT_EDGE_X (w);
21652 wr.y = WINDOW_TOP_EDGE_Y (w);
21653 wr.width = WINDOW_TOTAL_WIDTH (w);
21654 wr.height = WINDOW_TOTAL_HEIGHT (w);
21655
21656 if (x_intersect_rectangles (fr, &wr, &r))
21657 {
21658 int yb = window_text_bottom_y (w);
21659 struct glyph_row *row;
21660 int cursor_cleared_p;
21661 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21662
21663 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21664 r.x, r.y, r.width, r.height));
21665
21666 /* Convert to window coordinates. */
21667 r.x -= WINDOW_LEFT_EDGE_X (w);
21668 r.y -= WINDOW_TOP_EDGE_Y (w);
21669
21670 /* Turn off the cursor. */
21671 if (!w->pseudo_window_p
21672 && phys_cursor_in_rect_p (w, &r))
21673 {
21674 x_clear_cursor (w);
21675 cursor_cleared_p = 1;
21676 }
21677 else
21678 cursor_cleared_p = 0;
21679
21680 /* Update lines intersecting rectangle R. */
21681 first_overlapping_row = last_overlapping_row = NULL;
21682 for (row = w->current_matrix->rows;
21683 row->enabled_p;
21684 ++row)
21685 {
21686 int y0 = row->y;
21687 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21688
21689 if ((y0 >= r.y && y0 < r.y + r.height)
21690 || (y1 > r.y && y1 < r.y + r.height)
21691 || (r.y >= y0 && r.y < y1)
21692 || (r.y + r.height > y0 && r.y + r.height < y1))
21693 {
21694 if (row->overlapping_p)
21695 {
21696 if (first_overlapping_row == NULL)
21697 first_overlapping_row = row;
21698 last_overlapping_row = row;
21699 }
21700
21701 if (expose_line (w, row, &r))
21702 mouse_face_overwritten_p = 1;
21703 }
21704
21705 if (y1 >= yb)
21706 break;
21707 }
21708
21709 /* Display the mode line if there is one. */
21710 if (WINDOW_WANTS_MODELINE_P (w)
21711 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21712 row->enabled_p)
21713 && row->y < r.y + r.height)
21714 {
21715 if (expose_line (w, row, &r))
21716 mouse_face_overwritten_p = 1;
21717 }
21718
21719 if (!w->pseudo_window_p)
21720 {
21721 /* Fix the display of overlapping rows. */
21722 if (first_overlapping_row)
21723 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21724
21725 /* Draw border between windows. */
21726 x_draw_vertical_border (w);
21727
21728 /* Turn the cursor on again. */
21729 if (cursor_cleared_p)
21730 update_window_cursor (w, 1);
21731 }
21732 }
21733
21734 #ifdef HAVE_CARBON
21735 /* Display scroll bar for this window. */
21736 if (!NILP (w->vertical_scroll_bar))
21737 {
21738 /* ++KFS:
21739 If this doesn't work here (maybe some header files are missing),
21740 make a function in macterm.c and call it to do the job! */
21741 ControlHandle ch
21742 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21743
21744 Draw1Control (ch);
21745 }
21746 #endif
21747
21748 return mouse_face_overwritten_p;
21749 }
21750
21751
21752
21753 /* Redraw (parts) of all windows in the window tree rooted at W that
21754 intersect R. R contains frame pixel coordinates. Value is
21755 non-zero if the exposure overwrites mouse-face. */
21756
21757 static int
21758 expose_window_tree (w, r)
21759 struct window *w;
21760 XRectangle *r;
21761 {
21762 struct frame *f = XFRAME (w->frame);
21763 int mouse_face_overwritten_p = 0;
21764
21765 while (w && !FRAME_GARBAGED_P (f))
21766 {
21767 if (!NILP (w->hchild))
21768 mouse_face_overwritten_p
21769 |= expose_window_tree (XWINDOW (w->hchild), r);
21770 else if (!NILP (w->vchild))
21771 mouse_face_overwritten_p
21772 |= expose_window_tree (XWINDOW (w->vchild), r);
21773 else
21774 mouse_face_overwritten_p |= expose_window (w, r);
21775
21776 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21777 }
21778
21779 return mouse_face_overwritten_p;
21780 }
21781
21782
21783 /* EXPORT:
21784 Redisplay an exposed area of frame F. X and Y are the upper-left
21785 corner of the exposed rectangle. W and H are width and height of
21786 the exposed area. All are pixel values. W or H zero means redraw
21787 the entire frame. */
21788
21789 void
21790 expose_frame (f, x, y, w, h)
21791 struct frame *f;
21792 int x, y, w, h;
21793 {
21794 XRectangle r;
21795 int mouse_face_overwritten_p = 0;
21796
21797 TRACE ((stderr, "expose_frame "));
21798
21799 /* No need to redraw if frame will be redrawn soon. */
21800 if (FRAME_GARBAGED_P (f))
21801 {
21802 TRACE ((stderr, " garbaged\n"));
21803 return;
21804 }
21805
21806 #ifdef HAVE_CARBON
21807 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21808 or deactivated here, for unknown reasons, activated scroll bars
21809 are shown in deactivated frames in some instances. */
21810 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21811 activate_scroll_bars (f);
21812 else
21813 deactivate_scroll_bars (f);
21814 #endif
21815
21816 /* If basic faces haven't been realized yet, there is no point in
21817 trying to redraw anything. This can happen when we get an expose
21818 event while Emacs is starting, e.g. by moving another window. */
21819 if (FRAME_FACE_CACHE (f) == NULL
21820 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21821 {
21822 TRACE ((stderr, " no faces\n"));
21823 return;
21824 }
21825
21826 if (w == 0 || h == 0)
21827 {
21828 r.x = r.y = 0;
21829 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21830 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21831 }
21832 else
21833 {
21834 r.x = x;
21835 r.y = y;
21836 r.width = w;
21837 r.height = h;
21838 }
21839
21840 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21841 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21842
21843 if (WINDOWP (f->tool_bar_window))
21844 mouse_face_overwritten_p
21845 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21846
21847 #ifdef HAVE_X_WINDOWS
21848 #ifndef MSDOS
21849 #ifndef USE_X_TOOLKIT
21850 if (WINDOWP (f->menu_bar_window))
21851 mouse_face_overwritten_p
21852 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21853 #endif /* not USE_X_TOOLKIT */
21854 #endif
21855 #endif
21856
21857 /* Some window managers support a focus-follows-mouse style with
21858 delayed raising of frames. Imagine a partially obscured frame,
21859 and moving the mouse into partially obscured mouse-face on that
21860 frame. The visible part of the mouse-face will be highlighted,
21861 then the WM raises the obscured frame. With at least one WM, KDE
21862 2.1, Emacs is not getting any event for the raising of the frame
21863 (even tried with SubstructureRedirectMask), only Expose events.
21864 These expose events will draw text normally, i.e. not
21865 highlighted. Which means we must redo the highlight here.
21866 Subsume it under ``we love X''. --gerd 2001-08-15 */
21867 /* Included in Windows version because Windows most likely does not
21868 do the right thing if any third party tool offers
21869 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21870 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21871 {
21872 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21873 if (f == dpyinfo->mouse_face_mouse_frame)
21874 {
21875 int x = dpyinfo->mouse_face_mouse_x;
21876 int y = dpyinfo->mouse_face_mouse_y;
21877 clear_mouse_face (dpyinfo);
21878 note_mouse_highlight (f, x, y);
21879 }
21880 }
21881 }
21882
21883
21884 /* EXPORT:
21885 Determine the intersection of two rectangles R1 and R2. Return
21886 the intersection in *RESULT. Value is non-zero if RESULT is not
21887 empty. */
21888
21889 int
21890 x_intersect_rectangles (r1, r2, result)
21891 XRectangle *r1, *r2, *result;
21892 {
21893 XRectangle *left, *right;
21894 XRectangle *upper, *lower;
21895 int intersection_p = 0;
21896
21897 /* Rearrange so that R1 is the left-most rectangle. */
21898 if (r1->x < r2->x)
21899 left = r1, right = r2;
21900 else
21901 left = r2, right = r1;
21902
21903 /* X0 of the intersection is right.x0, if this is inside R1,
21904 otherwise there is no intersection. */
21905 if (right->x <= left->x + left->width)
21906 {
21907 result->x = right->x;
21908
21909 /* The right end of the intersection is the minimum of the
21910 the right ends of left and right. */
21911 result->width = (min (left->x + left->width, right->x + right->width)
21912 - result->x);
21913
21914 /* Same game for Y. */
21915 if (r1->y < r2->y)
21916 upper = r1, lower = r2;
21917 else
21918 upper = r2, lower = r1;
21919
21920 /* The upper end of the intersection is lower.y0, if this is inside
21921 of upper. Otherwise, there is no intersection. */
21922 if (lower->y <= upper->y + upper->height)
21923 {
21924 result->y = lower->y;
21925
21926 /* The lower end of the intersection is the minimum of the lower
21927 ends of upper and lower. */
21928 result->height = (min (lower->y + lower->height,
21929 upper->y + upper->height)
21930 - result->y);
21931 intersection_p = 1;
21932 }
21933 }
21934
21935 return intersection_p;
21936 }
21937
21938 #endif /* HAVE_WINDOW_SYSTEM */
21939
21940 \f
21941 /***********************************************************************
21942 Initialization
21943 ***********************************************************************/
21944
21945 void
21946 syms_of_xdisp ()
21947 {
21948 Vwith_echo_area_save_vector = Qnil;
21949 staticpro (&Vwith_echo_area_save_vector);
21950
21951 Vmessage_stack = Qnil;
21952 staticpro (&Vmessage_stack);
21953
21954 Qinhibit_redisplay = intern ("inhibit-redisplay");
21955 staticpro (&Qinhibit_redisplay);
21956
21957 message_dolog_marker1 = Fmake_marker ();
21958 staticpro (&message_dolog_marker1);
21959 message_dolog_marker2 = Fmake_marker ();
21960 staticpro (&message_dolog_marker2);
21961 message_dolog_marker3 = Fmake_marker ();
21962 staticpro (&message_dolog_marker3);
21963
21964 #if GLYPH_DEBUG
21965 defsubr (&Sdump_frame_glyph_matrix);
21966 defsubr (&Sdump_glyph_matrix);
21967 defsubr (&Sdump_glyph_row);
21968 defsubr (&Sdump_tool_bar_row);
21969 defsubr (&Strace_redisplay);
21970 defsubr (&Strace_to_stderr);
21971 #endif
21972 #ifdef HAVE_WINDOW_SYSTEM
21973 defsubr (&Stool_bar_lines_needed);
21974 defsubr (&Slookup_image_map);
21975 #endif
21976 defsubr (&Sformat_mode_line);
21977
21978 staticpro (&Qmenu_bar_update_hook);
21979 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21980
21981 staticpro (&Qoverriding_terminal_local_map);
21982 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21983
21984 staticpro (&Qoverriding_local_map);
21985 Qoverriding_local_map = intern ("overriding-local-map");
21986
21987 staticpro (&Qwindow_scroll_functions);
21988 Qwindow_scroll_functions = intern ("window-scroll-functions");
21989
21990 staticpro (&Qredisplay_end_trigger_functions);
21991 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21992
21993 staticpro (&Qinhibit_point_motion_hooks);
21994 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21995
21996 QCdata = intern (":data");
21997 staticpro (&QCdata);
21998 Qdisplay = intern ("display");
21999 staticpro (&Qdisplay);
22000 Qspace_width = intern ("space-width");
22001 staticpro (&Qspace_width);
22002 Qraise = intern ("raise");
22003 staticpro (&Qraise);
22004 Qslice = intern ("slice");
22005 staticpro (&Qslice);
22006 Qspace = intern ("space");
22007 staticpro (&Qspace);
22008 Qmargin = intern ("margin");
22009 staticpro (&Qmargin);
22010 Qpointer = intern ("pointer");
22011 staticpro (&Qpointer);
22012 Qleft_margin = intern ("left-margin");
22013 staticpro (&Qleft_margin);
22014 Qright_margin = intern ("right-margin");
22015 staticpro (&Qright_margin);
22016 Qcenter = intern ("center");
22017 staticpro (&Qcenter);
22018 Qline_height = intern ("line-height");
22019 staticpro (&Qline_height);
22020 Qtotal = intern ("total");
22021 staticpro (&Qtotal);
22022 QCalign_to = intern (":align-to");
22023 staticpro (&QCalign_to);
22024 QCrelative_width = intern (":relative-width");
22025 staticpro (&QCrelative_width);
22026 QCrelative_height = intern (":relative-height");
22027 staticpro (&QCrelative_height);
22028 QCeval = intern (":eval");
22029 staticpro (&QCeval);
22030 QCpropertize = intern (":propertize");
22031 staticpro (&QCpropertize);
22032 QCfile = intern (":file");
22033 staticpro (&QCfile);
22034 Qfontified = intern ("fontified");
22035 staticpro (&Qfontified);
22036 Qfontification_functions = intern ("fontification-functions");
22037 staticpro (&Qfontification_functions);
22038 Qtrailing_whitespace = intern ("trailing-whitespace");
22039 staticpro (&Qtrailing_whitespace);
22040 Qimage = intern ("image");
22041 staticpro (&Qimage);
22042 QCmap = intern (":map");
22043 staticpro (&QCmap);
22044 QCpointer = intern (":pointer");
22045 staticpro (&QCpointer);
22046 Qrect = intern ("rect");
22047 staticpro (&Qrect);
22048 Qcircle = intern ("circle");
22049 staticpro (&Qcircle);
22050 Qpoly = intern ("poly");
22051 staticpro (&Qpoly);
22052 Qmessage_truncate_lines = intern ("message-truncate-lines");
22053 staticpro (&Qmessage_truncate_lines);
22054 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22055 staticpro (&Qcursor_in_non_selected_windows);
22056 Qgrow_only = intern ("grow-only");
22057 staticpro (&Qgrow_only);
22058 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22059 staticpro (&Qinhibit_menubar_update);
22060 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22061 staticpro (&Qinhibit_eval_during_redisplay);
22062 Qposition = intern ("position");
22063 staticpro (&Qposition);
22064 Qbuffer_position = intern ("buffer-position");
22065 staticpro (&Qbuffer_position);
22066 Qobject = intern ("object");
22067 staticpro (&Qobject);
22068 Qbar = intern ("bar");
22069 staticpro (&Qbar);
22070 Qhbar = intern ("hbar");
22071 staticpro (&Qhbar);
22072 Qbox = intern ("box");
22073 staticpro (&Qbox);
22074 Qhollow = intern ("hollow");
22075 staticpro (&Qhollow);
22076 Qhand = intern ("hand");
22077 staticpro (&Qhand);
22078 Qarrow = intern ("arrow");
22079 staticpro (&Qarrow);
22080 Qtext = intern ("text");
22081 staticpro (&Qtext);
22082 Qrisky_local_variable = intern ("risky-local-variable");
22083 staticpro (&Qrisky_local_variable);
22084 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22085 staticpro (&Qinhibit_free_realized_faces);
22086
22087 list_of_error = Fcons (Fcons (intern ("error"),
22088 Fcons (intern ("void-variable"), Qnil)),
22089 Qnil);
22090 staticpro (&list_of_error);
22091
22092 Qlast_arrow_position = intern ("last-arrow-position");
22093 staticpro (&Qlast_arrow_position);
22094 Qlast_arrow_string = intern ("last-arrow-string");
22095 staticpro (&Qlast_arrow_string);
22096
22097 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22098 staticpro (&Qoverlay_arrow_string);
22099 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22100 staticpro (&Qoverlay_arrow_bitmap);
22101
22102 echo_buffer[0] = echo_buffer[1] = Qnil;
22103 staticpro (&echo_buffer[0]);
22104 staticpro (&echo_buffer[1]);
22105
22106 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22107 staticpro (&echo_area_buffer[0]);
22108 staticpro (&echo_area_buffer[1]);
22109
22110 Vmessages_buffer_name = build_string ("*Messages*");
22111 staticpro (&Vmessages_buffer_name);
22112
22113 mode_line_proptrans_alist = Qnil;
22114 staticpro (&mode_line_proptrans_alist);
22115
22116 mode_line_string_list = Qnil;
22117 staticpro (&mode_line_string_list);
22118
22119 help_echo_string = Qnil;
22120 staticpro (&help_echo_string);
22121 help_echo_object = Qnil;
22122 staticpro (&help_echo_object);
22123 help_echo_window = Qnil;
22124 staticpro (&help_echo_window);
22125 previous_help_echo_string = Qnil;
22126 staticpro (&previous_help_echo_string);
22127 help_echo_pos = -1;
22128
22129 #ifdef HAVE_WINDOW_SYSTEM
22130 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22131 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22132 For example, if a block cursor is over a tab, it will be drawn as
22133 wide as that tab on the display. */);
22134 x_stretch_cursor_p = 0;
22135 #endif
22136
22137 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22138 doc: /* *Non-nil means highlight trailing whitespace.
22139 The face used for trailing whitespace is `trailing-whitespace'. */);
22140 Vshow_trailing_whitespace = Qnil;
22141
22142 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22143 doc: /* *The pointer shape to show in void text areas.
22144 Nil means to show the text pointer. Other options are `arrow', `text',
22145 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22146 Vvoid_text_area_pointer = Qarrow;
22147
22148 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22149 doc: /* Non-nil means don't actually do any redisplay.
22150 This is used for internal purposes. */);
22151 Vinhibit_redisplay = Qnil;
22152
22153 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22154 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22155 Vglobal_mode_string = Qnil;
22156
22157 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22158 doc: /* Marker for where to display an arrow on top of the buffer text.
22159 This must be the beginning of a line in order to work.
22160 See also `overlay-arrow-string'. */);
22161 Voverlay_arrow_position = Qnil;
22162
22163 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22164 doc: /* String to display as an arrow in non-window frames.
22165 See also `overlay-arrow-position'. */);
22166 Voverlay_arrow_string = Qnil;
22167
22168 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22169 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22170 The symbols on this list are examined during redisplay to determine
22171 where to display overlay arrows. */);
22172 Voverlay_arrow_variable_list
22173 = Fcons (intern ("overlay-arrow-position"), Qnil);
22174
22175 DEFVAR_INT ("scroll-step", &scroll_step,
22176 doc: /* *The number of lines to try scrolling a window by when point moves out.
22177 If that fails to bring point back on frame, point is centered instead.
22178 If this is zero, point is always centered after it moves off frame.
22179 If you want scrolling to always be a line at a time, you should set
22180 `scroll-conservatively' to a large value rather than set this to 1. */);
22181
22182 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22183 doc: /* *Scroll up to this many lines, to bring point back on screen.
22184 A value of zero means to scroll the text to center point vertically
22185 in the window. */);
22186 scroll_conservatively = 0;
22187
22188 DEFVAR_INT ("scroll-margin", &scroll_margin,
22189 doc: /* *Number of lines of margin at the top and bottom of a window.
22190 Recenter the window whenever point gets within this many lines
22191 of the top or bottom of the window. */);
22192 scroll_margin = 0;
22193
22194 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22195 doc: /* Pixels per inch on current display.
22196 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22197 Vdisplay_pixels_per_inch = make_float (72.0);
22198
22199 #if GLYPH_DEBUG
22200 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22201 #endif
22202
22203 DEFVAR_BOOL ("truncate-partial-width-windows",
22204 &truncate_partial_width_windows,
22205 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22206 truncate_partial_width_windows = 1;
22207
22208 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22209 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22210 Any other value means to use the appropriate face, `mode-line',
22211 `header-line', or `menu' respectively. */);
22212 mode_line_inverse_video = 1;
22213
22214 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22215 doc: /* *Maximum buffer size for which line number should be displayed.
22216 If the buffer is bigger than this, the line number does not appear
22217 in the mode line. A value of nil means no limit. */);
22218 Vline_number_display_limit = Qnil;
22219
22220 DEFVAR_INT ("line-number-display-limit-width",
22221 &line_number_display_limit_width,
22222 doc: /* *Maximum line width (in characters) for line number display.
22223 If the average length of the lines near point is bigger than this, then the
22224 line number may be omitted from the mode line. */);
22225 line_number_display_limit_width = 200;
22226
22227 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22228 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22229 highlight_nonselected_windows = 0;
22230
22231 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22232 doc: /* Non-nil if more than one frame is visible on this display.
22233 Minibuffer-only frames don't count, but iconified frames do.
22234 This variable is not guaranteed to be accurate except while processing
22235 `frame-title-format' and `icon-title-format'. */);
22236
22237 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22238 doc: /* Template for displaying the title bar of visible frames.
22239 \(Assuming the window manager supports this feature.)
22240 This variable has the same structure as `mode-line-format' (which see),
22241 and is used only on frames for which no explicit name has been set
22242 \(see `modify-frame-parameters'). */);
22243
22244 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22245 doc: /* Template for displaying the title bar of an iconified frame.
22246 \(Assuming the window manager supports this feature.)
22247 This variable has the same structure as `mode-line-format' (which see),
22248 and is used only on frames for which no explicit name has been set
22249 \(see `modify-frame-parameters'). */);
22250 Vicon_title_format
22251 = Vframe_title_format
22252 = Fcons (intern ("multiple-frames"),
22253 Fcons (build_string ("%b"),
22254 Fcons (Fcons (empty_string,
22255 Fcons (intern ("invocation-name"),
22256 Fcons (build_string ("@"),
22257 Fcons (intern ("system-name"),
22258 Qnil)))),
22259 Qnil)));
22260
22261 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22262 doc: /* Maximum number of lines to keep in the message log buffer.
22263 If nil, disable message logging. If t, log messages but don't truncate
22264 the buffer when it becomes large. */);
22265 Vmessage_log_max = make_number (50);
22266
22267 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22268 doc: /* Functions called before redisplay, if window sizes have changed.
22269 The value should be a list of functions that take one argument.
22270 Just before redisplay, for each frame, if any of its windows have changed
22271 size since the last redisplay, or have been split or deleted,
22272 all the functions in the list are called, with the frame as argument. */);
22273 Vwindow_size_change_functions = Qnil;
22274
22275 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22276 doc: /* List of functions to call before redisplaying a window with scrolling.
22277 Each function is called with two arguments, the window
22278 and its new display-start position. Note that the value of `window-end'
22279 is not valid when these functions are called. */);
22280 Vwindow_scroll_functions = Qnil;
22281
22282 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22283 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22284 mouse_autoselect_window = 0;
22285
22286 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22287 doc: /* *Non-nil means automatically resize tool-bars.
22288 This increases a tool-bar's height if not all tool-bar items are visible.
22289 It decreases a tool-bar's height when it would display blank lines
22290 otherwise. */);
22291 auto_resize_tool_bars_p = 1;
22292
22293 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22294 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22295 auto_raise_tool_bar_buttons_p = 1;
22296
22297 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22298 doc: /* *Margin around tool-bar buttons in pixels.
22299 If an integer, use that for both horizontal and vertical margins.
22300 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22301 HORZ specifying the horizontal margin, and VERT specifying the
22302 vertical margin. */);
22303 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22304
22305 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22306 doc: /* *Relief thickness of tool-bar buttons. */);
22307 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22308
22309 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22310 doc: /* List of functions to call to fontify regions of text.
22311 Each function is called with one argument POS. Functions must
22312 fontify a region starting at POS in the current buffer, and give
22313 fontified regions the property `fontified'. */);
22314 Vfontification_functions = Qnil;
22315 Fmake_variable_buffer_local (Qfontification_functions);
22316
22317 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22318 &unibyte_display_via_language_environment,
22319 doc: /* *Non-nil means display unibyte text according to language environment.
22320 Specifically this means that unibyte non-ASCII characters
22321 are displayed by converting them to the equivalent multibyte characters
22322 according to the current language environment. As a result, they are
22323 displayed according to the current fontset. */);
22324 unibyte_display_via_language_environment = 0;
22325
22326 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22327 doc: /* *Maximum height for resizing mini-windows.
22328 If a float, it specifies a fraction of the mini-window frame's height.
22329 If an integer, it specifies a number of lines. */);
22330 Vmax_mini_window_height = make_float (0.25);
22331
22332 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22333 doc: /* *How to resize mini-windows.
22334 A value of nil means don't automatically resize mini-windows.
22335 A value of t means resize them to fit the text displayed in them.
22336 A value of `grow-only', the default, means let mini-windows grow
22337 only, until their display becomes empty, at which point the windows
22338 go back to their normal size. */);
22339 Vresize_mini_windows = Qgrow_only;
22340
22341 DEFVAR_LISP ("cursor-in-non-selected-windows",
22342 &Vcursor_in_non_selected_windows,
22343 doc: /* *Cursor type to display in non-selected windows.
22344 t means to use hollow box cursor. See `cursor-type' for other values. */);
22345 Vcursor_in_non_selected_windows = Qt;
22346
22347 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22348 doc: /* Alist specifying how to blink the cursor off.
22349 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22350 `cursor-type' frame-parameter or variable equals ON-STATE,
22351 comparing using `equal', Emacs uses OFF-STATE to specify
22352 how to blink it off. */);
22353 Vblink_cursor_alist = Qnil;
22354
22355 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22356 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22357 automatic_hscrolling_p = 1;
22358
22359 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22360 doc: /* *How many columns away from the window edge point is allowed to get
22361 before automatic hscrolling will horizontally scroll the window. */);
22362 hscroll_margin = 5;
22363
22364 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22365 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22366 When point is less than `automatic-hscroll-margin' columns from the window
22367 edge, automatic hscrolling will scroll the window by the amount of columns
22368 determined by this variable. If its value is a positive integer, scroll that
22369 many columns. If it's a positive floating-point number, it specifies the
22370 fraction of the window's width to scroll. If it's nil or zero, point will be
22371 centered horizontally after the scroll. Any other value, including negative
22372 numbers, are treated as if the value were zero.
22373
22374 Automatic hscrolling always moves point outside the scroll margin, so if
22375 point was more than scroll step columns inside the margin, the window will
22376 scroll more than the value given by the scroll step.
22377
22378 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22379 and `scroll-right' overrides this variable's effect. */);
22380 Vhscroll_step = make_number (0);
22381
22382 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22383 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22384 Bind this around calls to `message' to let it take effect. */);
22385 message_truncate_lines = 0;
22386
22387 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22388 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22389 Can be used to update submenus whose contents should vary. */);
22390 Vmenu_bar_update_hook = Qnil;
22391
22392 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22393 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22394 inhibit_menubar_update = 0;
22395
22396 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22397 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22398 inhibit_eval_during_redisplay = 0;
22399
22400 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22401 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22402 inhibit_free_realized_faces = 0;
22403
22404 #if GLYPH_DEBUG
22405 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22406 doc: /* Inhibit try_window_id display optimization. */);
22407 inhibit_try_window_id = 0;
22408
22409 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22410 doc: /* Inhibit try_window_reusing display optimization. */);
22411 inhibit_try_window_reusing = 0;
22412
22413 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22414 doc: /* Inhibit try_cursor_movement display optimization. */);
22415 inhibit_try_cursor_movement = 0;
22416 #endif /* GLYPH_DEBUG */
22417 }
22418
22419
22420 /* Initialize this module when Emacs starts. */
22421
22422 void
22423 init_xdisp ()
22424 {
22425 Lisp_Object root_window;
22426 struct window *mini_w;
22427
22428 current_header_line_height = current_mode_line_height = -1;
22429
22430 CHARPOS (this_line_start_pos) = 0;
22431
22432 mini_w = XWINDOW (minibuf_window);
22433 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22434
22435 if (!noninteractive)
22436 {
22437 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22438 int i;
22439
22440 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22441 set_window_height (root_window,
22442 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22443 0);
22444 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22445 set_window_height (minibuf_window, 1, 0);
22446
22447 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22448 mini_w->total_cols = make_number (FRAME_COLS (f));
22449
22450 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22451 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22452 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22453
22454 /* The default ellipsis glyphs `...'. */
22455 for (i = 0; i < 3; ++i)
22456 default_invis_vector[i] = make_number ('.');
22457 }
22458
22459 {
22460 /* Allocate the buffer for frame titles.
22461 Also used for `format-mode-line'. */
22462 int size = 100;
22463 frame_title_buf = (char *) xmalloc (size);
22464 frame_title_buf_end = frame_title_buf + size;
22465 frame_title_ptr = NULL;
22466 }
22467
22468 help_echo_showing_p = 0;
22469 }
22470
22471
22472 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22473 (do not change this comment) */