]> code.delx.au - gnu-emacs/blob - src/xdisp.c
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-69
[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 "character.h"
180 #include "charset.h"
181 #include "indent.h"
182 #include "commands.h"
183 #include "keymap.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "coding.h"
189 #include "process.h"
190 #include "region-cache.h"
191 #include "fontset.h"
192 #include "blockinput.h"
193
194 #ifdef HAVE_X_WINDOWS
195 #include "xterm.h"
196 #endif
197 #ifdef WINDOWSNT
198 #include "w32term.h"
199 #endif
200 #ifdef MAC_OS
201 #include "macterm.h"
202 #endif
203
204 #ifndef FRAME_X_OUTPUT
205 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
206 #endif
207
208 #define INFINITY 10000000
209
210 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
211 || defined (USE_GTK)
212 extern void set_frame_menubar P_ ((struct frame *f, int, int));
213 extern int pending_menu_activation;
214 #endif
215
216 extern int interrupt_input;
217 extern int command_loop_level;
218
219 extern Lisp_Object do_mouse_tracking;
220
221 extern int minibuffer_auto_raise;
222 extern Lisp_Object Vminibuffer_list;
223
224 extern Lisp_Object Qface;
225 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226
227 extern Lisp_Object Voverriding_local_map;
228 extern Lisp_Object Voverriding_local_map_menu_flag;
229 extern Lisp_Object Qmenu_item;
230 extern Lisp_Object Qwhen;
231 extern Lisp_Object Qhelp_echo;
232
233 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
234 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
235 Lisp_Object Qredisplay_end_trigger_functions;
236 Lisp_Object Qinhibit_point_motion_hooks;
237 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
238 Lisp_Object Qfontified;
239 Lisp_Object Qgrow_only;
240 Lisp_Object Qinhibit_eval_during_redisplay;
241 Lisp_Object Qbuffer_position, Qposition, Qobject;
242
243 /* Cursor shapes */
244 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245
246 /* Pointer shapes */
247 Lisp_Object Qarrow, Qhand, Qtext;
248
249 Lisp_Object Qrisky_local_variable;
250
251 /* Holds the list (error). */
252 Lisp_Object list_of_error;
253
254 /* Functions called to fontify regions of text. */
255
256 Lisp_Object Vfontification_functions;
257 Lisp_Object Qfontification_functions;
258
259 /* Non-zero means automatically select any window when the mouse
260 cursor moves into it. */
261 int mouse_autoselect_window;
262
263 /* Non-zero means draw tool bar buttons raised when the mouse moves
264 over them. */
265
266 int auto_raise_tool_bar_buttons_p;
267
268 /* Margin around tool bar buttons in pixels. */
269
270 Lisp_Object Vtool_bar_button_margin;
271
272 /* Thickness of shadow to draw around tool bar buttons. */
273
274 EMACS_INT tool_bar_button_relief;
275
276 /* Non-zero means automatically resize tool-bars so that all tool-bar
277 items are visible, and no blank lines remain. */
278
279 int auto_resize_tool_bars_p;
280
281 /* Non-zero means draw block and hollow cursor as wide as the glyph
282 under it. For example, if a block cursor is over a tab, it will be
283 drawn as wide as that tab on the display. */
284
285 int x_stretch_cursor_p;
286
287 /* Non-nil means don't actually do any redisplay. */
288
289 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
290
291 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
292
293 int inhibit_eval_during_redisplay;
294
295 /* Names of text properties relevant for redisplay. */
296
297 Lisp_Object Qdisplay;
298 extern Lisp_Object Qface, Qinvisible, Qwidth;
299
300 /* Symbols used in text property values. */
301
302 Lisp_Object Vdisplay_pixels_per_inch;
303 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
304 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
305 Lisp_Object Qslice;
306 Lisp_Object Qcenter;
307 Lisp_Object Qmargin, Qpointer;
308 Lisp_Object Qline_height, Qtotal;
309 extern Lisp_Object Qheight;
310 extern Lisp_Object QCwidth, QCheight, QCascent;
311 extern Lisp_Object Qscroll_bar;
312 extern Lisp_Object Qcursor;
313
314 /* Non-nil means highlight trailing whitespace. */
315
316 Lisp_Object Vshow_trailing_whitespace;
317
318 #ifdef HAVE_WINDOW_SYSTEM
319 extern Lisp_Object Voverflow_newline_into_fringe;
320
321 /* Test if overflow newline into fringe. Called with iterator IT
322 at or past right window margin, and with IT->current_x set. */
323
324 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
325 (!NILP (Voverflow_newline_into_fringe) \
326 && FRAME_WINDOW_P (it->f) \
327 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
328 && it->current_x == it->last_visible_x)
329
330 #endif /* HAVE_WINDOW_SYSTEM */
331
332 /* Non-nil means show the text cursor in void text areas
333 i.e. in blank areas after eol and eob. This used to be
334 the default in 21.3. */
335
336 Lisp_Object Vvoid_text_area_pointer;
337
338 /* Name of the face used to highlight trailing whitespace. */
339
340 Lisp_Object Qtrailing_whitespace;
341
342 /* The symbol `image' which is the car of the lists used to represent
343 images in Lisp. */
344
345 Lisp_Object Qimage;
346
347 /* The image map types. */
348 Lisp_Object QCmap, QCpointer;
349 Lisp_Object Qrect, Qcircle, Qpoly;
350
351 /* Non-zero means print newline to stdout before next mini-buffer
352 message. */
353
354 int noninteractive_need_newline;
355
356 /* Non-zero means print newline to message log before next message. */
357
358 static int message_log_need_newline;
359
360 /* Three markers that message_dolog uses.
361 It could allocate them itself, but that causes trouble
362 in handling memory-full errors. */
363 static Lisp_Object message_dolog_marker1;
364 static Lisp_Object message_dolog_marker2;
365 static Lisp_Object message_dolog_marker3;
366 \f
367 /* The buffer position of the first character appearing entirely or
368 partially on the line of the selected window which contains the
369 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
370 redisplay optimization in redisplay_internal. */
371
372 static struct text_pos this_line_start_pos;
373
374 /* Number of characters past the end of the line above, including the
375 terminating newline. */
376
377 static struct text_pos this_line_end_pos;
378
379 /* The vertical positions and the height of this line. */
380
381 static int this_line_vpos;
382 static int this_line_y;
383 static int this_line_pixel_height;
384
385 /* X position at which this display line starts. Usually zero;
386 negative if first character is partially visible. */
387
388 static int this_line_start_x;
389
390 /* Buffer that this_line_.* variables are referring to. */
391
392 static struct buffer *this_line_buffer;
393
394 /* Nonzero means truncate lines in all windows less wide than the
395 frame. */
396
397 int truncate_partial_width_windows;
398
399 /* A flag to control how to display unibyte 8-bit character. */
400
401 int unibyte_display_via_language_environment;
402
403 /* Nonzero means we have more than one non-mini-buffer-only frame.
404 Not guaranteed to be accurate except while parsing
405 frame-title-format. */
406
407 int multiple_frames;
408
409 Lisp_Object Vglobal_mode_string;
410
411
412 /* List of variables (symbols) which hold markers for overlay arrows.
413 The symbols on this list are examined during redisplay to determine
414 where to display overlay arrows. */
415
416 Lisp_Object Voverlay_arrow_variable_list;
417
418 /* Marker for where to display an arrow on top of the buffer text. */
419
420 Lisp_Object Voverlay_arrow_position;
421
422 /* String to display for the arrow. Only used on terminal frames. */
423
424 Lisp_Object Voverlay_arrow_string;
425
426 /* Values of those variables at last redisplay are stored as
427 properties on `overlay-arrow-position' symbol. However, if
428 Voverlay_arrow_position is a marker, last-arrow-position is its
429 numerical position. */
430
431 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
432
433 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
434 properties on a symbol in overlay-arrow-variable-list. */
435
436 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
437
438 /* Like mode-line-format, but for the title bar on a visible frame. */
439
440 Lisp_Object Vframe_title_format;
441
442 /* Like mode-line-format, but for the title bar on an iconified frame. */
443
444 Lisp_Object Vicon_title_format;
445
446 /* List of functions to call when a window's size changes. These
447 functions get one arg, a frame on which one or more windows' sizes
448 have changed. */
449
450 static Lisp_Object Vwindow_size_change_functions;
451
452 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
453
454 /* Nonzero if overlay arrow has been displayed once in this window. */
455
456 static int overlay_arrow_seen;
457
458 /* Nonzero means highlight the region even in nonselected windows. */
459
460 int highlight_nonselected_windows;
461
462 /* If cursor motion alone moves point off frame, try scrolling this
463 many lines up or down if that will bring it back. */
464
465 static EMACS_INT scroll_step;
466
467 /* Nonzero means scroll just far enough to bring point back on the
468 screen, when appropriate. */
469
470 static EMACS_INT scroll_conservatively;
471
472 /* Recenter the window whenever point gets within this many lines of
473 the top or bottom of the window. This value is translated into a
474 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
475 that there is really a fixed pixel height scroll margin. */
476
477 EMACS_INT scroll_margin;
478
479 /* Number of windows showing the buffer of the selected window (or
480 another buffer with the same base buffer). keyboard.c refers to
481 this. */
482
483 int buffer_shared;
484
485 /* Vector containing glyphs for an ellipsis `...'. */
486
487 static Lisp_Object default_invis_vector[3];
488
489 /* Zero means display the mode-line/header-line/menu-bar in the default face
490 (this slightly odd definition is for compatibility with previous versions
491 of emacs), non-zero means display them using their respective faces.
492
493 This variable is deprecated. */
494
495 int mode_line_inverse_video;
496
497 /* Prompt to display in front of the mini-buffer contents. */
498
499 Lisp_Object minibuf_prompt;
500
501 /* Width of current mini-buffer prompt. Only set after display_line
502 of the line that contains the prompt. */
503
504 int minibuf_prompt_width;
505
506 /* This is the window where the echo area message was displayed. It
507 is always a mini-buffer window, but it may not be the same window
508 currently active as a mini-buffer. */
509
510 Lisp_Object echo_area_window;
511
512 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
513 pushes the current message and the value of
514 message_enable_multibyte on the stack, the function restore_message
515 pops the stack and displays MESSAGE again. */
516
517 Lisp_Object Vmessage_stack;
518
519 /* Nonzero means multibyte characters were enabled when the echo area
520 message was specified. */
521
522 int message_enable_multibyte;
523
524 /* Nonzero if we should redraw the mode lines on the next redisplay. */
525
526 int update_mode_lines;
527
528 /* Nonzero if window sizes or contents have changed since last
529 redisplay that finished. */
530
531 int windows_or_buffers_changed;
532
533 /* Nonzero means a frame's cursor type has been changed. */
534
535 int cursor_type_changed;
536
537 /* Nonzero after display_mode_line if %l was used and it displayed a
538 line number. */
539
540 int line_number_displayed;
541
542 /* Maximum buffer size for which to display line numbers. */
543
544 Lisp_Object Vline_number_display_limit;
545
546 /* Line width to consider when repositioning for line number display. */
547
548 static EMACS_INT line_number_display_limit_width;
549
550 /* Number of lines to keep in the message log buffer. t means
551 infinite. nil means don't log at all. */
552
553 Lisp_Object Vmessage_log_max;
554
555 /* The name of the *Messages* buffer, a string. */
556
557 static Lisp_Object Vmessages_buffer_name;
558
559 /* Current, index 0, and last displayed echo area message. Either
560 buffers from echo_buffers, or nil to indicate no message. */
561
562 Lisp_Object echo_area_buffer[2];
563
564 /* The buffers referenced from echo_area_buffer. */
565
566 static Lisp_Object echo_buffer[2];
567
568 /* A vector saved used in with_area_buffer to reduce consing. */
569
570 static Lisp_Object Vwith_echo_area_save_vector;
571
572 /* Non-zero means display_echo_area should display the last echo area
573 message again. Set by redisplay_preserve_echo_area. */
574
575 static int display_last_displayed_message_p;
576
577 /* Nonzero if echo area is being used by print; zero if being used by
578 message. */
579
580 int message_buf_print;
581
582 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
583
584 Lisp_Object Qinhibit_menubar_update;
585 int inhibit_menubar_update;
586
587 /* Maximum height for resizing mini-windows. Either a float
588 specifying a fraction of the available height, or an integer
589 specifying a number of lines. */
590
591 Lisp_Object Vmax_mini_window_height;
592
593 /* Non-zero means messages should be displayed with truncated
594 lines instead of being continued. */
595
596 int message_truncate_lines;
597 Lisp_Object Qmessage_truncate_lines;
598
599 /* Set to 1 in clear_message to make redisplay_internal aware
600 of an emptied echo area. */
601
602 static int message_cleared_p;
603
604 /* Non-zero means we want a hollow cursor in windows that are not
605 selected. Zero means there's no cursor in such windows. */
606
607 Lisp_Object Vcursor_in_non_selected_windows;
608 Lisp_Object Qcursor_in_non_selected_windows;
609
610 /* How to blink the default frame cursor off. */
611 Lisp_Object Vblink_cursor_alist;
612
613 /* A scratch glyph row with contents used for generating truncation
614 glyphs. Also used in direct_output_for_insert. */
615
616 #define MAX_SCRATCH_GLYPHS 100
617 struct glyph_row scratch_glyph_row;
618 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
619
620 /* Ascent and height of the last line processed by move_it_to. */
621
622 static int last_max_ascent, last_height;
623
624 /* Non-zero if there's a help-echo in the echo area. */
625
626 int help_echo_showing_p;
627
628 /* If >= 0, computed, exact values of mode-line and header-line height
629 to use in the macros CURRENT_MODE_LINE_HEIGHT and
630 CURRENT_HEADER_LINE_HEIGHT. */
631
632 int current_mode_line_height, current_header_line_height;
633
634 /* The maximum distance to look ahead for text properties. Values
635 that are too small let us call compute_char_face and similar
636 functions too often which is expensive. Values that are too large
637 let us call compute_char_face and alike too often because we
638 might not be interested in text properties that far away. */
639
640 #define TEXT_PROP_DISTANCE_LIMIT 100
641
642 #if GLYPH_DEBUG
643
644 /* Variables to turn off display optimizations from Lisp. */
645
646 int inhibit_try_window_id, inhibit_try_window_reusing;
647 int inhibit_try_cursor_movement;
648
649 /* Non-zero means print traces of redisplay if compiled with
650 GLYPH_DEBUG != 0. */
651
652 int trace_redisplay_p;
653
654 #endif /* GLYPH_DEBUG */
655
656 #ifdef DEBUG_TRACE_MOVE
657 /* Non-zero means trace with TRACE_MOVE to stderr. */
658 int trace_move;
659
660 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
661 #else
662 #define TRACE_MOVE(x) (void) 0
663 #endif
664
665 /* Non-zero means automatically scroll windows horizontally to make
666 point visible. */
667
668 int automatic_hscrolling_p;
669
670 /* How close to the margin can point get before the window is scrolled
671 horizontally. */
672 EMACS_INT hscroll_margin;
673
674 /* How much to scroll horizontally when point is inside the above margin. */
675 Lisp_Object Vhscroll_step;
676
677 /* The variable `resize-mini-windows'. If nil, don't resize
678 mini-windows. If t, always resize them to fit the text they
679 display. If `grow-only', let mini-windows grow only until they
680 become empty. */
681
682 Lisp_Object Vresize_mini_windows;
683
684 /* Buffer being redisplayed -- for redisplay_window_error. */
685
686 struct buffer *displayed_buffer;
687
688 /* Value returned from text property handlers (see below). */
689
690 enum prop_handled
691 {
692 HANDLED_NORMALLY,
693 HANDLED_RECOMPUTE_PROPS,
694 HANDLED_OVERLAY_STRING_CONSUMED,
695 HANDLED_RETURN
696 };
697
698 /* A description of text properties that redisplay is interested
699 in. */
700
701 struct props
702 {
703 /* The name of the property. */
704 Lisp_Object *name;
705
706 /* A unique index for the property. */
707 enum prop_idx idx;
708
709 /* A handler function called to set up iterator IT from the property
710 at IT's current position. Value is used to steer handle_stop. */
711 enum prop_handled (*handler) P_ ((struct it *it));
712 };
713
714 static enum prop_handled handle_face_prop P_ ((struct it *));
715 static enum prop_handled handle_invisible_prop P_ ((struct it *));
716 static enum prop_handled handle_display_prop P_ ((struct it *));
717 static enum prop_handled handle_composition_prop P_ ((struct it *));
718 static enum prop_handled handle_overlay_change P_ ((struct it *));
719 static enum prop_handled handle_fontified_prop P_ ((struct it *));
720 static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
721
722 /* Properties handled by iterators. */
723
724 static struct props it_props[] =
725 {
726 {&Qauto_composed, AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
727 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
728 /* Handle `face' before `display' because some sub-properties of
729 `display' need to know the face. */
730 {&Qface, FACE_PROP_IDX, handle_face_prop},
731 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
732 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
733 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
734 {NULL, 0, NULL}
735 };
736
737 /* Value is the position described by X. If X is a marker, value is
738 the marker_position of X. Otherwise, value is X. */
739
740 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
741
742 /* Enumeration returned by some move_it_.* functions internally. */
743
744 enum move_it_result
745 {
746 /* Not used. Undefined value. */
747 MOVE_UNDEFINED,
748
749 /* Move ended at the requested buffer position or ZV. */
750 MOVE_POS_MATCH_OR_ZV,
751
752 /* Move ended at the requested X pixel position. */
753 MOVE_X_REACHED,
754
755 /* Move within a line ended at the end of a line that must be
756 continued. */
757 MOVE_LINE_CONTINUED,
758
759 /* Move within a line ended at the end of a line that would
760 be displayed truncated. */
761 MOVE_LINE_TRUNCATED,
762
763 /* Move within a line ended at a line end. */
764 MOVE_NEWLINE_OR_CR
765 };
766
767 /* This counter is used to clear the face cache every once in a while
768 in redisplay_internal. It is incremented for each redisplay.
769 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
770 cleared. */
771
772 #define CLEAR_FACE_CACHE_COUNT 500
773 static int clear_face_cache_count;
774
775 /* Record the previous terminal frame we displayed. */
776
777 static struct frame *previous_terminal_frame;
778
779 /* Non-zero while redisplay_internal is in progress. */
780
781 int redisplaying_p;
782
783 /* Non-zero means don't free realized faces. Bound while freeing
784 realized faces is dangerous because glyph matrices might still
785 reference them. */
786
787 int inhibit_free_realized_faces;
788 Lisp_Object Qinhibit_free_realized_faces;
789
790 /* If a string, XTread_socket generates an event to display that string.
791 (The display is done in read_char.) */
792
793 Lisp_Object help_echo_string;
794 Lisp_Object help_echo_window;
795 Lisp_Object help_echo_object;
796 int help_echo_pos;
797
798 /* Temporary variable for XTread_socket. */
799
800 Lisp_Object previous_help_echo_string;
801
802 /* Null glyph slice */
803
804 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
805
806 \f
807 /* Function prototypes. */
808
809 static void setup_for_ellipsis P_ ((struct it *));
810 static void mark_window_display_accurate_1 P_ ((struct window *, int));
811 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
812 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
813 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
814 static int redisplay_mode_lines P_ ((Lisp_Object, int));
815 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
816
817 #if 0
818 static int invisible_text_between_p P_ ((struct it *, int, int));
819 #endif
820
821 static int next_element_from_ellipsis P_ ((struct it *));
822 static void pint2str P_ ((char *, int, int));
823 static void pint2hrstr P_ ((char *, int, int));
824 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
825 struct text_pos));
826 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
827 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
828 static void store_frame_title_char P_ ((char));
829 static int store_frame_title P_ ((const unsigned char *, int, int));
830 static void x_consider_frame_title P_ ((Lisp_Object));
831 static void handle_stop P_ ((struct it *));
832 static int tool_bar_lines_needed P_ ((struct frame *));
833 static int single_display_prop_intangible_p P_ ((Lisp_Object));
834 static void ensure_echo_area_buffers P_ ((void));
835 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
836 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
837 static int with_echo_area_buffer P_ ((struct window *, int,
838 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
839 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
840 static void clear_garbaged_frames P_ ((void));
841 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
842 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
843 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
844 static int display_echo_area P_ ((struct window *));
845 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
846 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
847 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
848 static int string_char_and_length P_ ((const unsigned char *, int, int *));
849 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
850 struct text_pos));
851 static int compute_window_start_on_continuation_line P_ ((struct window *));
852 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
853 static void insert_left_trunc_glyphs P_ ((struct it *));
854 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
855 Lisp_Object));
856 static void extend_face_to_end_of_line P_ ((struct it *));
857 static int append_space_for_newline P_ ((struct it *, int));
858 static int make_cursor_line_fully_visible P_ ((struct window *, int));
859 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
860 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
861 static int trailing_whitespace_p P_ ((int));
862 static int message_log_check_duplicate P_ ((int, int, int, int));
863 static void push_it P_ ((struct it *));
864 static void pop_it P_ ((struct it *));
865 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
866 static void select_frame_for_redisplay P_ ((Lisp_Object));
867 static void redisplay_internal P_ ((int));
868 static int echo_area_display P_ ((int));
869 static void redisplay_windows P_ ((Lisp_Object));
870 static void redisplay_window P_ ((Lisp_Object, int));
871 static Lisp_Object redisplay_window_error ();
872 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
873 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
874 static void update_menu_bar P_ ((struct frame *, int));
875 static int try_window_reusing_current_matrix P_ ((struct window *));
876 static int try_window_id P_ ((struct window *));
877 static int display_line P_ ((struct it *));
878 static int display_mode_lines P_ ((struct window *));
879 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
880 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
881 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
882 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
883 static void display_menu_bar P_ ((struct window *));
884 static int display_count_lines P_ ((int, int, int, int, int *));
885 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
886 int, int, struct it *, int, int, int, int));
887 static void compute_line_metrics P_ ((struct it *));
888 static void run_redisplay_end_trigger_hook P_ ((struct it *));
889 static int get_overlay_strings P_ ((struct it *, int));
890 static void next_overlay_string P_ ((struct it *));
891 static void reseat P_ ((struct it *, struct text_pos, int));
892 static void reseat_1 P_ ((struct it *, struct text_pos, int));
893 static void back_to_previous_visible_line_start P_ ((struct it *));
894 static void reseat_at_previous_visible_line_start P_ ((struct it *));
895 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
896 static int next_element_from_display_vector P_ ((struct it *));
897 static int next_element_from_string P_ ((struct it *));
898 static int next_element_from_c_string P_ ((struct it *));
899 static int next_element_from_buffer P_ ((struct it *));
900 static int next_element_from_composition P_ ((struct it *));
901 static int next_element_from_image P_ ((struct it *));
902 static int next_element_from_stretch P_ ((struct it *));
903 static void load_overlay_strings P_ ((struct it *, int));
904 static int init_from_display_pos P_ ((struct it *, struct window *,
905 struct display_pos *));
906 static void reseat_to_string P_ ((struct it *, unsigned char *,
907 Lisp_Object, int, int, int, int));
908 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
909 int, int, int));
910 void move_it_vertically_backward P_ ((struct it *, int));
911 static void init_to_row_start P_ ((struct it *, struct window *,
912 struct glyph_row *));
913 static int init_to_row_end P_ ((struct it *, struct window *,
914 struct glyph_row *));
915 static void back_to_previous_line_start P_ ((struct it *));
916 static int forward_to_next_line_start P_ ((struct it *, int *));
917 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
918 Lisp_Object, int));
919 static struct text_pos string_pos P_ ((int, Lisp_Object));
920 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
921 static int number_of_chars P_ ((unsigned char *, int));
922 static void compute_stop_pos P_ ((struct it *));
923 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
924 Lisp_Object));
925 static int face_before_or_after_it_pos P_ ((struct it *, int));
926 static int next_overlay_change P_ ((int));
927 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
928 Lisp_Object, struct text_pos *,
929 int));
930 static int underlying_face_id P_ ((struct it *));
931 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
932 struct window *));
933
934 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
935 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
936
937 #ifdef HAVE_WINDOW_SYSTEM
938
939 static void update_tool_bar P_ ((struct frame *, int));
940 static void build_desired_tool_bar_string P_ ((struct frame *f));
941 static int redisplay_tool_bar P_ ((struct frame *));
942 static void display_tool_bar_line P_ ((struct it *));
943 static void notice_overwritten_cursor P_ ((struct window *,
944 enum glyph_row_area,
945 int, int, int, int));
946
947
948
949 #endif /* HAVE_WINDOW_SYSTEM */
950
951 \f
952 /***********************************************************************
953 Window display dimensions
954 ***********************************************************************/
955
956 /* Return the bottom boundary y-position for text lines in window W.
957 This is the first y position at which a line cannot start.
958 It is relative to the top of the window.
959
960 This is the height of W minus the height of a mode line, if any. */
961
962 INLINE int
963 window_text_bottom_y (w)
964 struct window *w;
965 {
966 int height = WINDOW_TOTAL_HEIGHT (w);
967
968 if (WINDOW_WANTS_MODELINE_P (w))
969 height -= CURRENT_MODE_LINE_HEIGHT (w);
970 return height;
971 }
972
973 /* Return the pixel width of display area AREA of window W. AREA < 0
974 means return the total width of W, not including fringes to
975 the left and right of the window. */
976
977 INLINE int
978 window_box_width (w, area)
979 struct window *w;
980 int area;
981 {
982 int cols = XFASTINT (w->total_cols);
983 int pixels = 0;
984
985 if (!w->pseudo_window_p)
986 {
987 cols -= WINDOW_SCROLL_BAR_COLS (w);
988
989 if (area == TEXT_AREA)
990 {
991 if (INTEGERP (w->left_margin_cols))
992 cols -= XFASTINT (w->left_margin_cols);
993 if (INTEGERP (w->right_margin_cols))
994 cols -= XFASTINT (w->right_margin_cols);
995 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
996 }
997 else if (area == LEFT_MARGIN_AREA)
998 {
999 cols = (INTEGERP (w->left_margin_cols)
1000 ? XFASTINT (w->left_margin_cols) : 0);
1001 pixels = 0;
1002 }
1003 else if (area == RIGHT_MARGIN_AREA)
1004 {
1005 cols = (INTEGERP (w->right_margin_cols)
1006 ? XFASTINT (w->right_margin_cols) : 0);
1007 pixels = 0;
1008 }
1009 }
1010
1011 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1012 }
1013
1014
1015 /* Return the pixel height of the display area of window W, not
1016 including mode lines of W, if any. */
1017
1018 INLINE int
1019 window_box_height (w)
1020 struct window *w;
1021 {
1022 struct frame *f = XFRAME (w->frame);
1023 int height = WINDOW_TOTAL_HEIGHT (w);
1024
1025 xassert (height >= 0);
1026
1027 /* Note: the code below that determines the mode-line/header-line
1028 height is essentially the same as that contained in the macro
1029 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1030 the appropriate glyph row has its `mode_line_p' flag set,
1031 and if it doesn't, uses estimate_mode_line_height instead. */
1032
1033 if (WINDOW_WANTS_MODELINE_P (w))
1034 {
1035 struct glyph_row *ml_row
1036 = (w->current_matrix && w->current_matrix->rows
1037 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1038 : 0);
1039 if (ml_row && ml_row->mode_line_p)
1040 height -= ml_row->height;
1041 else
1042 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1043 }
1044
1045 if (WINDOW_WANTS_HEADER_LINE_P (w))
1046 {
1047 struct glyph_row *hl_row
1048 = (w->current_matrix && w->current_matrix->rows
1049 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1050 : 0);
1051 if (hl_row && hl_row->mode_line_p)
1052 height -= hl_row->height;
1053 else
1054 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1055 }
1056
1057 /* With a very small font and a mode-line that's taller than
1058 default, we might end up with a negative height. */
1059 return max (0, height);
1060 }
1061
1062 /* Return the window-relative coordinate of the left edge of display
1063 area AREA of window W. AREA < 0 means return the left edge of the
1064 whole window, to the right of the left fringe of W. */
1065
1066 INLINE int
1067 window_box_left_offset (w, area)
1068 struct window *w;
1069 int area;
1070 {
1071 int x;
1072
1073 if (w->pseudo_window_p)
1074 return 0;
1075
1076 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1077
1078 if (area == TEXT_AREA)
1079 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1080 + window_box_width (w, LEFT_MARGIN_AREA));
1081 else if (area == RIGHT_MARGIN_AREA)
1082 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1083 + window_box_width (w, LEFT_MARGIN_AREA)
1084 + window_box_width (w, TEXT_AREA)
1085 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1086 ? 0
1087 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1088 else if (area == LEFT_MARGIN_AREA
1089 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1090 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1091
1092 return x;
1093 }
1094
1095
1096 /* Return the window-relative coordinate of the right edge of display
1097 area AREA of window W. AREA < 0 means return the left edge of the
1098 whole window, to the left of the right fringe of W. */
1099
1100 INLINE int
1101 window_box_right_offset (w, area)
1102 struct window *w;
1103 int area;
1104 {
1105 return window_box_left_offset (w, area) + window_box_width (w, area);
1106 }
1107
1108 /* Return the frame-relative coordinate of the left edge of display
1109 area AREA of window W. AREA < 0 means return the left edge of the
1110 whole window, to the right of the left fringe of W. */
1111
1112 INLINE int
1113 window_box_left (w, area)
1114 struct window *w;
1115 int area;
1116 {
1117 struct frame *f = XFRAME (w->frame);
1118 int x;
1119
1120 if (w->pseudo_window_p)
1121 return FRAME_INTERNAL_BORDER_WIDTH (f);
1122
1123 x = (WINDOW_LEFT_EDGE_X (w)
1124 + window_box_left_offset (w, area));
1125
1126 return x;
1127 }
1128
1129
1130 /* Return the frame-relative coordinate of the right edge of display
1131 area AREA of window W. AREA < 0 means return the left edge of the
1132 whole window, to the left of the right fringe of W. */
1133
1134 INLINE int
1135 window_box_right (w, area)
1136 struct window *w;
1137 int area;
1138 {
1139 return window_box_left (w, area) + window_box_width (w, area);
1140 }
1141
1142 /* Get the bounding box of the display area AREA of window W, without
1143 mode lines, in frame-relative coordinates. AREA < 0 means the
1144 whole window, not including the left and right fringes of
1145 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1146 coordinates of the upper-left corner of the box. Return in
1147 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1148
1149 INLINE void
1150 window_box (w, area, box_x, box_y, box_width, box_height)
1151 struct window *w;
1152 int area;
1153 int *box_x, *box_y, *box_width, *box_height;
1154 {
1155 if (box_width)
1156 *box_width = window_box_width (w, area);
1157 if (box_height)
1158 *box_height = window_box_height (w);
1159 if (box_x)
1160 *box_x = window_box_left (w, area);
1161 if (box_y)
1162 {
1163 *box_y = WINDOW_TOP_EDGE_Y (w);
1164 if (WINDOW_WANTS_HEADER_LINE_P (w))
1165 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1166 }
1167 }
1168
1169
1170 /* Get the bounding box of the display area AREA of window W, without
1171 mode lines. AREA < 0 means the whole window, not including the
1172 left and right fringe of the window. Return in *TOP_LEFT_X
1173 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1174 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1175 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1176 box. */
1177
1178 INLINE void
1179 window_box_edges (w, area, top_left_x, top_left_y,
1180 bottom_right_x, bottom_right_y)
1181 struct window *w;
1182 int area;
1183 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1184 {
1185 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1186 bottom_right_y);
1187 *bottom_right_x += *top_left_x;
1188 *bottom_right_y += *top_left_y;
1189 }
1190
1191
1192 \f
1193 /***********************************************************************
1194 Utilities
1195 ***********************************************************************/
1196
1197 /* Return the bottom y-position of the line the iterator IT is in.
1198 This can modify IT's settings. */
1199
1200 int
1201 line_bottom_y (it)
1202 struct it *it;
1203 {
1204 int line_height = it->max_ascent + it->max_descent;
1205 int line_top_y = it->current_y;
1206
1207 if (line_height == 0)
1208 {
1209 if (last_height)
1210 line_height = last_height;
1211 else if (IT_CHARPOS (*it) < ZV)
1212 {
1213 move_it_by_lines (it, 1, 1);
1214 line_height = (it->max_ascent || it->max_descent
1215 ? it->max_ascent + it->max_descent
1216 : last_height);
1217 }
1218 else
1219 {
1220 struct glyph_row *row = it->glyph_row;
1221
1222 /* Use the default character height. */
1223 it->glyph_row = NULL;
1224 it->what = IT_CHARACTER;
1225 it->c = ' ';
1226 it->len = 1;
1227 PRODUCE_GLYPHS (it);
1228 line_height = it->ascent + it->descent;
1229 it->glyph_row = row;
1230 }
1231 }
1232
1233 return line_top_y + line_height;
1234 }
1235
1236
1237 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1238 1 if POS is visible and the line containing POS is fully visible.
1239 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1240 and header-lines heights. */
1241
1242 int
1243 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1244 struct window *w;
1245 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1246 {
1247 struct it it;
1248 struct text_pos top;
1249 int visible_p;
1250 struct buffer *old_buffer = NULL;
1251
1252 if (XBUFFER (w->buffer) != current_buffer)
1253 {
1254 old_buffer = current_buffer;
1255 set_buffer_internal_1 (XBUFFER (w->buffer));
1256 }
1257
1258 *fully = visible_p = 0;
1259 SET_TEXT_POS_FROM_MARKER (top, w->start);
1260
1261 /* Compute exact mode line heights, if requested. */
1262 if (exact_mode_line_heights_p)
1263 {
1264 if (WINDOW_WANTS_MODELINE_P (w))
1265 current_mode_line_height
1266 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1267 current_buffer->mode_line_format);
1268
1269 if (WINDOW_WANTS_HEADER_LINE_P (w))
1270 current_header_line_height
1271 = display_mode_line (w, HEADER_LINE_FACE_ID,
1272 current_buffer->header_line_format);
1273 }
1274
1275 start_display (&it, w, top);
1276 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1277 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1278
1279 /* Note that we may overshoot because of invisible text. */
1280 if (IT_CHARPOS (it) >= charpos)
1281 {
1282 int top_y = it.current_y;
1283 int bottom_y = line_bottom_y (&it);
1284 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1285
1286 if (top_y < window_top_y)
1287 visible_p = bottom_y > window_top_y;
1288 else if (top_y < it.last_visible_y)
1289 {
1290 visible_p = 1;
1291 *fully = bottom_y <= it.last_visible_y;
1292 }
1293 if (visible_p && x)
1294 {
1295 *x = it.current_x;
1296 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1297 }
1298 }
1299 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1300 {
1301 struct it it2;
1302
1303 it2 = it;
1304 move_it_by_lines (&it, 1, 0);
1305 if (charpos < IT_CHARPOS (it))
1306 {
1307 visible_p = 1;
1308 if (x)
1309 {
1310 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1311 *x = it2.current_x;
1312 *y = it2.current_y + it2.max_ascent - it2.ascent;
1313 }
1314 }
1315 }
1316
1317 if (old_buffer)
1318 set_buffer_internal_1 (old_buffer);
1319
1320 current_header_line_height = current_mode_line_height = -1;
1321
1322 return visible_p;
1323 }
1324
1325
1326 /* Return the next character from STR which is MAXLEN bytes long.
1327 Return in *LEN the length of the character. This is like
1328 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1329 we find one, we return a `?', but with the length of the invalid
1330 character. */
1331
1332 static INLINE int
1333 string_char_and_length (str, maxlen, len)
1334 const unsigned char *str;
1335 int maxlen, *len;
1336 {
1337 int c;
1338
1339 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1340 if (!CHAR_VALID_P (c, 1))
1341 /* We may not change the length here because other places in Emacs
1342 don't use this function, i.e. they silently accept invalid
1343 characters. */
1344 c = '?';
1345
1346 return c;
1347 }
1348
1349
1350
1351 /* Given a position POS containing a valid character and byte position
1352 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1353
1354 static struct text_pos
1355 string_pos_nchars_ahead (pos, string, nchars)
1356 struct text_pos pos;
1357 Lisp_Object string;
1358 int nchars;
1359 {
1360 xassert (STRINGP (string) && nchars >= 0);
1361
1362 if (STRING_MULTIBYTE (string))
1363 {
1364 int rest = SBYTES (string) - BYTEPOS (pos);
1365 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1366 int len;
1367
1368 while (nchars--)
1369 {
1370 string_char_and_length (p, rest, &len);
1371 p += len, rest -= len;
1372 xassert (rest >= 0);
1373 CHARPOS (pos) += 1;
1374 BYTEPOS (pos) += len;
1375 }
1376 }
1377 else
1378 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1379
1380 return pos;
1381 }
1382
1383
1384 /* Value is the text position, i.e. character and byte position,
1385 for character position CHARPOS in STRING. */
1386
1387 static INLINE struct text_pos
1388 string_pos (charpos, string)
1389 int charpos;
1390 Lisp_Object string;
1391 {
1392 struct text_pos pos;
1393 xassert (STRINGP (string));
1394 xassert (charpos >= 0);
1395 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1396 return pos;
1397 }
1398
1399
1400 /* Value is a text position, i.e. character and byte position, for
1401 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1402 means recognize multibyte characters. */
1403
1404 static struct text_pos
1405 c_string_pos (charpos, s, multibyte_p)
1406 int charpos;
1407 unsigned char *s;
1408 int multibyte_p;
1409 {
1410 struct text_pos pos;
1411
1412 xassert (s != NULL);
1413 xassert (charpos >= 0);
1414
1415 if (multibyte_p)
1416 {
1417 int rest = strlen (s), len;
1418
1419 SET_TEXT_POS (pos, 0, 0);
1420 while (charpos--)
1421 {
1422 string_char_and_length (s, rest, &len);
1423 s += len, rest -= len;
1424 xassert (rest >= 0);
1425 CHARPOS (pos) += 1;
1426 BYTEPOS (pos) += len;
1427 }
1428 }
1429 else
1430 SET_TEXT_POS (pos, charpos, charpos);
1431
1432 return pos;
1433 }
1434
1435
1436 /* Value is the number of characters in C string S. MULTIBYTE_P
1437 non-zero means recognize multibyte characters. */
1438
1439 static int
1440 number_of_chars (s, multibyte_p)
1441 unsigned char *s;
1442 int multibyte_p;
1443 {
1444 int nchars;
1445
1446 if (multibyte_p)
1447 {
1448 int rest = strlen (s), len;
1449 unsigned char *p = (unsigned char *) s;
1450
1451 for (nchars = 0; rest > 0; ++nchars)
1452 {
1453 string_char_and_length (p, rest, &len);
1454 rest -= len, p += len;
1455 }
1456 }
1457 else
1458 nchars = strlen (s);
1459
1460 return nchars;
1461 }
1462
1463
1464 /* Compute byte position NEWPOS->bytepos corresponding to
1465 NEWPOS->charpos. POS is a known position in string STRING.
1466 NEWPOS->charpos must be >= POS.charpos. */
1467
1468 static void
1469 compute_string_pos (newpos, pos, string)
1470 struct text_pos *newpos, pos;
1471 Lisp_Object string;
1472 {
1473 xassert (STRINGP (string));
1474 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1475
1476 if (STRING_MULTIBYTE (string))
1477 *newpos = string_pos_nchars_ahead (pos, string,
1478 CHARPOS (*newpos) - CHARPOS (pos));
1479 else
1480 BYTEPOS (*newpos) = CHARPOS (*newpos);
1481 }
1482
1483 /* EXPORT:
1484 Return an estimation of the pixel height of mode or top lines on
1485 frame F. FACE_ID specifies what line's height to estimate. */
1486
1487 int
1488 estimate_mode_line_height (f, face_id)
1489 struct frame *f;
1490 enum face_id face_id;
1491 {
1492 #ifdef HAVE_WINDOW_SYSTEM
1493 if (FRAME_WINDOW_P (f))
1494 {
1495 int height = FONT_HEIGHT (FRAME_FONT (f));
1496
1497 /* This function is called so early when Emacs starts that the face
1498 cache and mode line face are not yet initialized. */
1499 if (FRAME_FACE_CACHE (f))
1500 {
1501 struct face *face = FACE_FROM_ID (f, face_id);
1502 if (face)
1503 {
1504 if (face->font)
1505 height = FONT_HEIGHT (face->font);
1506 if (face->box_line_width > 0)
1507 height += 2 * face->box_line_width;
1508 }
1509 }
1510
1511 return height;
1512 }
1513 #endif
1514
1515 return 1;
1516 }
1517
1518 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1519 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1520 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1521 not force the value into range. */
1522
1523 void
1524 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1525 FRAME_PTR f;
1526 register int pix_x, pix_y;
1527 int *x, *y;
1528 NativeRectangle *bounds;
1529 int noclip;
1530 {
1531
1532 #ifdef HAVE_WINDOW_SYSTEM
1533 if (FRAME_WINDOW_P (f))
1534 {
1535 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1536 even for negative values. */
1537 if (pix_x < 0)
1538 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1539 if (pix_y < 0)
1540 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1541
1542 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1543 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1544
1545 if (bounds)
1546 STORE_NATIVE_RECT (*bounds,
1547 FRAME_COL_TO_PIXEL_X (f, pix_x),
1548 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1549 FRAME_COLUMN_WIDTH (f) - 1,
1550 FRAME_LINE_HEIGHT (f) - 1);
1551
1552 if (!noclip)
1553 {
1554 if (pix_x < 0)
1555 pix_x = 0;
1556 else if (pix_x > FRAME_TOTAL_COLS (f))
1557 pix_x = FRAME_TOTAL_COLS (f);
1558
1559 if (pix_y < 0)
1560 pix_y = 0;
1561 else if (pix_y > FRAME_LINES (f))
1562 pix_y = FRAME_LINES (f);
1563 }
1564 }
1565 #endif
1566
1567 *x = pix_x;
1568 *y = pix_y;
1569 }
1570
1571
1572 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1573 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1574 can't tell the positions because W's display is not up to date,
1575 return 0. */
1576
1577 int
1578 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1579 struct window *w;
1580 int hpos, vpos;
1581 int *frame_x, *frame_y;
1582 {
1583 #ifdef HAVE_WINDOW_SYSTEM
1584 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1585 {
1586 int success_p;
1587
1588 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1589 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1590
1591 if (display_completed)
1592 {
1593 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1594 struct glyph *glyph = row->glyphs[TEXT_AREA];
1595 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1596
1597 hpos = row->x;
1598 vpos = row->y;
1599 while (glyph < end)
1600 {
1601 hpos += glyph->pixel_width;
1602 ++glyph;
1603 }
1604
1605 /* If first glyph is partially visible, its first visible position is still 0. */
1606 if (hpos < 0)
1607 hpos = 0;
1608
1609 success_p = 1;
1610 }
1611 else
1612 {
1613 hpos = vpos = 0;
1614 success_p = 0;
1615 }
1616
1617 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1618 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1619 return success_p;
1620 }
1621 #endif
1622
1623 *frame_x = hpos;
1624 *frame_y = vpos;
1625 return 1;
1626 }
1627
1628
1629 #ifdef HAVE_WINDOW_SYSTEM
1630
1631 /* Find the glyph under window-relative coordinates X/Y in window W.
1632 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1633 strings. Return in *HPOS and *VPOS the row and column number of
1634 the glyph found. Return in *AREA the glyph area containing X.
1635 Value is a pointer to the glyph found or null if X/Y is not on
1636 text, or we can't tell because W's current matrix is not up to
1637 date. */
1638
1639 static struct glyph *
1640 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1641 struct window *w;
1642 int x, y;
1643 int *hpos, *vpos, *dx, *dy, *area;
1644 {
1645 struct glyph *glyph, *end;
1646 struct glyph_row *row = NULL;
1647 int x0, i;
1648
1649 /* Find row containing Y. Give up if some row is not enabled. */
1650 for (i = 0; i < w->current_matrix->nrows; ++i)
1651 {
1652 row = MATRIX_ROW (w->current_matrix, i);
1653 if (!row->enabled_p)
1654 return NULL;
1655 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1656 break;
1657 }
1658
1659 *vpos = i;
1660 *hpos = 0;
1661
1662 /* Give up if Y is not in the window. */
1663 if (i == w->current_matrix->nrows)
1664 return NULL;
1665
1666 /* Get the glyph area containing X. */
1667 if (w->pseudo_window_p)
1668 {
1669 *area = TEXT_AREA;
1670 x0 = 0;
1671 }
1672 else
1673 {
1674 if (x < window_box_left_offset (w, TEXT_AREA))
1675 {
1676 *area = LEFT_MARGIN_AREA;
1677 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1678 }
1679 else if (x < window_box_right_offset (w, TEXT_AREA))
1680 {
1681 *area = TEXT_AREA;
1682 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1683 }
1684 else
1685 {
1686 *area = RIGHT_MARGIN_AREA;
1687 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1688 }
1689 }
1690
1691 /* Find glyph containing X. */
1692 glyph = row->glyphs[*area];
1693 end = glyph + row->used[*area];
1694 x -= x0;
1695 while (glyph < end && x >= glyph->pixel_width)
1696 {
1697 x -= glyph->pixel_width;
1698 ++glyph;
1699 }
1700
1701 if (glyph == end)
1702 return NULL;
1703
1704 if (dx)
1705 {
1706 *dx = x;
1707 *dy = y - (row->y + row->ascent - glyph->ascent);
1708 }
1709
1710 *hpos = glyph - row->glyphs[*area];
1711 return glyph;
1712 }
1713
1714
1715 /* EXPORT:
1716 Convert frame-relative x/y to coordinates relative to window W.
1717 Takes pseudo-windows into account. */
1718
1719 void
1720 frame_to_window_pixel_xy (w, x, y)
1721 struct window *w;
1722 int *x, *y;
1723 {
1724 if (w->pseudo_window_p)
1725 {
1726 /* A pseudo-window is always full-width, and starts at the
1727 left edge of the frame, plus a frame border. */
1728 struct frame *f = XFRAME (w->frame);
1729 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1730 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1731 }
1732 else
1733 {
1734 *x -= WINDOW_LEFT_EDGE_X (w);
1735 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1736 }
1737 }
1738
1739 /* EXPORT:
1740 Return in *R the clipping rectangle for glyph string S. */
1741
1742 void
1743 get_glyph_string_clip_rect (s, nr)
1744 struct glyph_string *s;
1745 NativeRectangle *nr;
1746 {
1747 XRectangle r;
1748
1749 if (s->row->full_width_p)
1750 {
1751 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1752 r.x = WINDOW_LEFT_EDGE_X (s->w);
1753 r.width = WINDOW_TOTAL_WIDTH (s->w);
1754
1755 /* Unless displaying a mode or menu bar line, which are always
1756 fully visible, clip to the visible part of the row. */
1757 if (s->w->pseudo_window_p)
1758 r.height = s->row->visible_height;
1759 else
1760 r.height = s->height;
1761 }
1762 else
1763 {
1764 /* This is a text line that may be partially visible. */
1765 r.x = window_box_left (s->w, s->area);
1766 r.width = window_box_width (s->w, s->area);
1767 r.height = s->row->visible_height;
1768 }
1769
1770 /* If S draws overlapping rows, it's sufficient to use the top and
1771 bottom of the window for clipping because this glyph string
1772 intentionally draws over other lines. */
1773 if (s->for_overlaps_p)
1774 {
1775 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1776 r.height = window_text_bottom_y (s->w) - r.y;
1777 }
1778 else
1779 {
1780 /* Don't use S->y for clipping because it doesn't take partially
1781 visible lines into account. For example, it can be negative for
1782 partially visible lines at the top of a window. */
1783 if (!s->row->full_width_p
1784 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1785 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1786 else
1787 r.y = max (0, s->row->y);
1788
1789 /* If drawing a tool-bar window, draw it over the internal border
1790 at the top of the window. */
1791 if (s->w == XWINDOW (s->f->tool_bar_window))
1792 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1793 }
1794
1795 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1796
1797 /* If drawing the cursor, don't let glyph draw outside its
1798 advertised boundaries. Cleartype does this under some circumstances. */
1799 if (s->hl == DRAW_CURSOR)
1800 {
1801 struct glyph *glyph = s->first_glyph;
1802 int height;
1803
1804 if (s->x > r.x)
1805 {
1806 r.width -= s->x - r.x;
1807 r.x = s->x;
1808 }
1809 r.width = min (r.width, glyph->pixel_width);
1810
1811 /* Don't draw cursor glyph taller than our actual glyph. */
1812 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1813 if (height < r.height)
1814 {
1815 int max_y = r.y + r.height;
1816 r.y = min (max_y, s->ybase + glyph->descent - height);
1817 r.height = min (max_y - r.y, height);
1818 }
1819 }
1820
1821 #ifdef CONVERT_FROM_XRECT
1822 CONVERT_FROM_XRECT (r, *nr);
1823 #else
1824 *nr = r;
1825 #endif
1826 }
1827
1828 #endif /* HAVE_WINDOW_SYSTEM */
1829
1830 \f
1831 /***********************************************************************
1832 Lisp form evaluation
1833 ***********************************************************************/
1834
1835 /* Error handler for safe_eval and safe_call. */
1836
1837 static Lisp_Object
1838 safe_eval_handler (arg)
1839 Lisp_Object arg;
1840 {
1841 add_to_log ("Error during redisplay: %s", arg, Qnil);
1842 return Qnil;
1843 }
1844
1845
1846 /* Evaluate SEXPR and return the result, or nil if something went
1847 wrong. Prevent redisplay during the evaluation. */
1848
1849 Lisp_Object
1850 safe_eval (sexpr)
1851 Lisp_Object sexpr;
1852 {
1853 Lisp_Object val;
1854
1855 if (inhibit_eval_during_redisplay)
1856 val = Qnil;
1857 else
1858 {
1859 int count = SPECPDL_INDEX ();
1860 struct gcpro gcpro1;
1861
1862 GCPRO1 (sexpr);
1863 specbind (Qinhibit_redisplay, Qt);
1864 /* Use Qt to ensure debugger does not run,
1865 so there is no possibility of wanting to redisplay. */
1866 val = internal_condition_case_1 (Feval, sexpr, Qt,
1867 safe_eval_handler);
1868 UNGCPRO;
1869 val = unbind_to (count, val);
1870 }
1871
1872 return val;
1873 }
1874
1875
1876 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1877 Return the result, or nil if something went wrong. Prevent
1878 redisplay during the evaluation. */
1879
1880 Lisp_Object
1881 safe_call (nargs, args)
1882 int nargs;
1883 Lisp_Object *args;
1884 {
1885 Lisp_Object val;
1886
1887 if (inhibit_eval_during_redisplay)
1888 val = Qnil;
1889 else
1890 {
1891 int count = SPECPDL_INDEX ();
1892 struct gcpro gcpro1;
1893
1894 GCPRO1 (args[0]);
1895 gcpro1.nvars = nargs;
1896 specbind (Qinhibit_redisplay, Qt);
1897 /* Use Qt to ensure debugger does not run,
1898 so there is no possibility of wanting to redisplay. */
1899 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1900 safe_eval_handler);
1901 UNGCPRO;
1902 val = unbind_to (count, val);
1903 }
1904
1905 return val;
1906 }
1907
1908
1909 /* Call function FN with one argument ARG.
1910 Return the result, or nil if something went wrong. */
1911
1912 Lisp_Object
1913 safe_call1 (fn, arg)
1914 Lisp_Object fn, arg;
1915 {
1916 Lisp_Object args[2];
1917 args[0] = fn;
1918 args[1] = arg;
1919 return safe_call (2, args);
1920 }
1921
1922
1923 \f
1924 /***********************************************************************
1925 Debugging
1926 ***********************************************************************/
1927
1928 #if 0
1929
1930 /* Define CHECK_IT to perform sanity checks on iterators.
1931 This is for debugging. It is too slow to do unconditionally. */
1932
1933 static void
1934 check_it (it)
1935 struct it *it;
1936 {
1937 if (it->method == next_element_from_string)
1938 {
1939 xassert (STRINGP (it->string));
1940 xassert (IT_STRING_CHARPOS (*it) >= 0);
1941 }
1942 else
1943 {
1944 xassert (IT_STRING_CHARPOS (*it) < 0);
1945 if (it->method == next_element_from_buffer)
1946 {
1947 /* Check that character and byte positions agree. */
1948 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1949 }
1950 }
1951
1952 if (it->dpvec)
1953 xassert (it->current.dpvec_index >= 0);
1954 else
1955 xassert (it->current.dpvec_index < 0);
1956 }
1957
1958 #define CHECK_IT(IT) check_it ((IT))
1959
1960 #else /* not 0 */
1961
1962 #define CHECK_IT(IT) (void) 0
1963
1964 #endif /* not 0 */
1965
1966
1967 #if GLYPH_DEBUG
1968
1969 /* Check that the window end of window W is what we expect it
1970 to be---the last row in the current matrix displaying text. */
1971
1972 static void
1973 check_window_end (w)
1974 struct window *w;
1975 {
1976 if (!MINI_WINDOW_P (w)
1977 && !NILP (w->window_end_valid))
1978 {
1979 struct glyph_row *row;
1980 xassert ((row = MATRIX_ROW (w->current_matrix,
1981 XFASTINT (w->window_end_vpos)),
1982 !row->enabled_p
1983 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1984 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1985 }
1986 }
1987
1988 #define CHECK_WINDOW_END(W) check_window_end ((W))
1989
1990 #else /* not GLYPH_DEBUG */
1991
1992 #define CHECK_WINDOW_END(W) (void) 0
1993
1994 #endif /* not GLYPH_DEBUG */
1995
1996
1997 \f
1998 /***********************************************************************
1999 Iterator initialization
2000 ***********************************************************************/
2001
2002 /* Initialize IT for displaying current_buffer in window W, starting
2003 at character position CHARPOS. CHARPOS < 0 means that no buffer
2004 position is specified which is useful when the iterator is assigned
2005 a position later. BYTEPOS is the byte position corresponding to
2006 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2007
2008 If ROW is not null, calls to produce_glyphs with IT as parameter
2009 will produce glyphs in that row.
2010
2011 BASE_FACE_ID is the id of a base face to use. It must be one of
2012 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2013 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2014 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2015
2016 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2017 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2018 will be initialized to use the corresponding mode line glyph row of
2019 the desired matrix of W. */
2020
2021 void
2022 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2023 struct it *it;
2024 struct window *w;
2025 int charpos, bytepos;
2026 struct glyph_row *row;
2027 enum face_id base_face_id;
2028 {
2029 int highlight_region_p;
2030
2031 /* Some precondition checks. */
2032 xassert (w != NULL && it != NULL);
2033 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2034 && charpos <= ZV));
2035
2036 /* If face attributes have been changed since the last redisplay,
2037 free realized faces now because they depend on face definitions
2038 that might have changed. Don't free faces while there might be
2039 desired matrices pending which reference these faces. */
2040 if (face_change_count && !inhibit_free_realized_faces)
2041 {
2042 face_change_count = 0;
2043 free_all_realized_faces (Qnil);
2044 }
2045
2046 /* Use one of the mode line rows of W's desired matrix if
2047 appropriate. */
2048 if (row == NULL)
2049 {
2050 if (base_face_id == MODE_LINE_FACE_ID
2051 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2052 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2053 else if (base_face_id == HEADER_LINE_FACE_ID)
2054 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2055 }
2056
2057 /* Clear IT. */
2058 bzero (it, sizeof *it);
2059 it->current.overlay_string_index = -1;
2060 it->current.dpvec_index = -1;
2061 it->base_face_id = base_face_id;
2062 it->string = Qnil;
2063 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2064
2065 /* The window in which we iterate over current_buffer: */
2066 XSETWINDOW (it->window, w);
2067 it->w = w;
2068 it->f = XFRAME (w->frame);
2069
2070 /* Extra space between lines (on window systems only). */
2071 if (base_face_id == DEFAULT_FACE_ID
2072 && FRAME_WINDOW_P (it->f))
2073 {
2074 if (NATNUMP (current_buffer->extra_line_spacing))
2075 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2076 else if (FLOATP (current_buffer->extra_line_spacing))
2077 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2078 * FRAME_LINE_HEIGHT (it->f));
2079 else if (it->f->extra_line_spacing > 0)
2080 it->extra_line_spacing = it->f->extra_line_spacing;
2081 }
2082
2083 /* If realized faces have been removed, e.g. because of face
2084 attribute changes of named faces, recompute them. When running
2085 in batch mode, the face cache of Vterminal_frame is null. If
2086 we happen to get called, make a dummy face cache. */
2087 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2088 init_frame_faces (it->f);
2089 if (FRAME_FACE_CACHE (it->f)->used == 0)
2090 recompute_basic_faces (it->f);
2091
2092 /* Current value of the `slice', `space-width', and 'height' properties. */
2093 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2094 it->space_width = Qnil;
2095 it->font_height = Qnil;
2096 it->override_ascent = -1;
2097
2098 /* Are control characters displayed as `^C'? */
2099 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2100
2101 /* -1 means everything between a CR and the following line end
2102 is invisible. >0 means lines indented more than this value are
2103 invisible. */
2104 it->selective = (INTEGERP (current_buffer->selective_display)
2105 ? XFASTINT (current_buffer->selective_display)
2106 : (!NILP (current_buffer->selective_display)
2107 ? -1 : 0));
2108 it->selective_display_ellipsis_p
2109 = !NILP (current_buffer->selective_display_ellipses);
2110
2111 /* Display table to use. */
2112 it->dp = window_display_table (w);
2113
2114 /* Are multibyte characters enabled in current_buffer? */
2115 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2116
2117 /* Non-zero if we should highlight the region. */
2118 highlight_region_p
2119 = (!NILP (Vtransient_mark_mode)
2120 && !NILP (current_buffer->mark_active)
2121 && XMARKER (current_buffer->mark)->buffer != 0);
2122
2123 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2124 start and end of a visible region in window IT->w. Set both to
2125 -1 to indicate no region. */
2126 if (highlight_region_p
2127 /* Maybe highlight only in selected window. */
2128 && (/* Either show region everywhere. */
2129 highlight_nonselected_windows
2130 /* Or show region in the selected window. */
2131 || w == XWINDOW (selected_window)
2132 /* Or show the region if we are in the mini-buffer and W is
2133 the window the mini-buffer refers to. */
2134 || (MINI_WINDOW_P (XWINDOW (selected_window))
2135 && WINDOWP (minibuf_selected_window)
2136 && w == XWINDOW (minibuf_selected_window))))
2137 {
2138 int charpos = marker_position (current_buffer->mark);
2139 it->region_beg_charpos = min (PT, charpos);
2140 it->region_end_charpos = max (PT, charpos);
2141 }
2142 else
2143 it->region_beg_charpos = it->region_end_charpos = -1;
2144
2145 /* Get the position at which the redisplay_end_trigger hook should
2146 be run, if it is to be run at all. */
2147 if (MARKERP (w->redisplay_end_trigger)
2148 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2149 it->redisplay_end_trigger_charpos
2150 = marker_position (w->redisplay_end_trigger);
2151 else if (INTEGERP (w->redisplay_end_trigger))
2152 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2153
2154 /* Correct bogus values of tab_width. */
2155 it->tab_width = XINT (current_buffer->tab_width);
2156 if (it->tab_width <= 0 || it->tab_width > 1000)
2157 it->tab_width = 8;
2158
2159 /* Are lines in the display truncated? */
2160 it->truncate_lines_p
2161 = (base_face_id != DEFAULT_FACE_ID
2162 || XINT (it->w->hscroll)
2163 || (truncate_partial_width_windows
2164 && !WINDOW_FULL_WIDTH_P (it->w))
2165 || !NILP (current_buffer->truncate_lines));
2166
2167 /* Get dimensions of truncation and continuation glyphs. These are
2168 displayed as fringe bitmaps under X, so we don't need them for such
2169 frames. */
2170 if (!FRAME_WINDOW_P (it->f))
2171 {
2172 if (it->truncate_lines_p)
2173 {
2174 /* We will need the truncation glyph. */
2175 xassert (it->glyph_row == NULL);
2176 produce_special_glyphs (it, IT_TRUNCATION);
2177 it->truncation_pixel_width = it->pixel_width;
2178 }
2179 else
2180 {
2181 /* We will need the continuation glyph. */
2182 xassert (it->glyph_row == NULL);
2183 produce_special_glyphs (it, IT_CONTINUATION);
2184 it->continuation_pixel_width = it->pixel_width;
2185 }
2186
2187 /* Reset these values to zero because the produce_special_glyphs
2188 above has changed them. */
2189 it->pixel_width = it->ascent = it->descent = 0;
2190 it->phys_ascent = it->phys_descent = 0;
2191 }
2192
2193 /* Set this after getting the dimensions of truncation and
2194 continuation glyphs, so that we don't produce glyphs when calling
2195 produce_special_glyphs, above. */
2196 it->glyph_row = row;
2197 it->area = TEXT_AREA;
2198
2199 /* Get the dimensions of the display area. The display area
2200 consists of the visible window area plus a horizontally scrolled
2201 part to the left of the window. All x-values are relative to the
2202 start of this total display area. */
2203 if (base_face_id != DEFAULT_FACE_ID)
2204 {
2205 /* Mode lines, menu bar in terminal frames. */
2206 it->first_visible_x = 0;
2207 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2208 }
2209 else
2210 {
2211 it->first_visible_x
2212 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2213 it->last_visible_x = (it->first_visible_x
2214 + window_box_width (w, TEXT_AREA));
2215
2216 /* If we truncate lines, leave room for the truncator glyph(s) at
2217 the right margin. Otherwise, leave room for the continuation
2218 glyph(s). Truncation and continuation glyphs are not inserted
2219 for window-based redisplay. */
2220 if (!FRAME_WINDOW_P (it->f))
2221 {
2222 if (it->truncate_lines_p)
2223 it->last_visible_x -= it->truncation_pixel_width;
2224 else
2225 it->last_visible_x -= it->continuation_pixel_width;
2226 }
2227
2228 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2229 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2230 }
2231
2232 /* Leave room for a border glyph. */
2233 if (!FRAME_WINDOW_P (it->f)
2234 && !WINDOW_RIGHTMOST_P (it->w))
2235 it->last_visible_x -= 1;
2236
2237 it->last_visible_y = window_text_bottom_y (w);
2238
2239 /* For mode lines and alike, arrange for the first glyph having a
2240 left box line if the face specifies a box. */
2241 if (base_face_id != DEFAULT_FACE_ID)
2242 {
2243 struct face *face;
2244
2245 it->face_id = base_face_id;
2246
2247 /* If we have a boxed mode line, make the first character appear
2248 with a left box line. */
2249 face = FACE_FROM_ID (it->f, base_face_id);
2250 if (face->box != FACE_NO_BOX)
2251 it->start_of_box_run_p = 1;
2252 }
2253
2254 /* If a buffer position was specified, set the iterator there,
2255 getting overlays and face properties from that position. */
2256 if (charpos >= BUF_BEG (current_buffer))
2257 {
2258 it->end_charpos = ZV;
2259 it->face_id = -1;
2260 IT_CHARPOS (*it) = charpos;
2261
2262 /* Compute byte position if not specified. */
2263 if (bytepos < charpos)
2264 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2265 else
2266 IT_BYTEPOS (*it) = bytepos;
2267
2268 it->start = it->current;
2269
2270 /* Compute faces etc. */
2271 reseat (it, it->current.pos, 1);
2272 }
2273
2274 CHECK_IT (it);
2275 }
2276
2277
2278 /* Initialize IT for the display of window W with window start POS. */
2279
2280 void
2281 start_display (it, w, pos)
2282 struct it *it;
2283 struct window *w;
2284 struct text_pos pos;
2285 {
2286 struct glyph_row *row;
2287 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2288
2289 row = w->desired_matrix->rows + first_vpos;
2290 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2291 it->first_vpos = first_vpos;
2292
2293 if (!it->truncate_lines_p)
2294 {
2295 int start_at_line_beg_p;
2296 int first_y = it->current_y;
2297
2298 /* If window start is not at a line start, skip forward to POS to
2299 get the correct continuation lines width. */
2300 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2301 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2302 if (!start_at_line_beg_p)
2303 {
2304 int new_x;
2305
2306 reseat_at_previous_visible_line_start (it);
2307 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2308
2309 new_x = it->current_x + it->pixel_width;
2310
2311 /* If lines are continued, this line may end in the middle
2312 of a multi-glyph character (e.g. a control character
2313 displayed as \003, or in the middle of an overlay
2314 string). In this case move_it_to above will not have
2315 taken us to the start of the continuation line but to the
2316 end of the continued line. */
2317 if (it->current_x > 0
2318 && !it->truncate_lines_p /* Lines are continued. */
2319 && (/* And glyph doesn't fit on the line. */
2320 new_x > it->last_visible_x
2321 /* Or it fits exactly and we're on a window
2322 system frame. */
2323 || (new_x == it->last_visible_x
2324 && FRAME_WINDOW_P (it->f))))
2325 {
2326 if (it->current.dpvec_index >= 0
2327 || it->current.overlay_string_index >= 0)
2328 {
2329 set_iterator_to_next (it, 1);
2330 move_it_in_display_line_to (it, -1, -1, 0);
2331 }
2332
2333 it->continuation_lines_width += it->current_x;
2334 }
2335
2336 /* We're starting a new display line, not affected by the
2337 height of the continued line, so clear the appropriate
2338 fields in the iterator structure. */
2339 it->max_ascent = it->max_descent = 0;
2340 it->max_phys_ascent = it->max_phys_descent = 0;
2341
2342 it->current_y = first_y;
2343 it->vpos = 0;
2344 it->current_x = it->hpos = 0;
2345 }
2346 }
2347
2348 #if 0 /* Don't assert the following because start_display is sometimes
2349 called intentionally with a window start that is not at a
2350 line start. Please leave this code in as a comment. */
2351
2352 /* Window start should be on a line start, now. */
2353 xassert (it->continuation_lines_width
2354 || IT_CHARPOS (it) == BEGV
2355 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2356 #endif /* 0 */
2357 }
2358
2359
2360 /* Return 1 if POS is a position in ellipses displayed for invisible
2361 text. W is the window we display, for text property lookup. */
2362
2363 static int
2364 in_ellipses_for_invisible_text_p (pos, w)
2365 struct display_pos *pos;
2366 struct window *w;
2367 {
2368 Lisp_Object prop, window;
2369 int ellipses_p = 0;
2370 int charpos = CHARPOS (pos->pos);
2371
2372 /* If POS specifies a position in a display vector, this might
2373 be for an ellipsis displayed for invisible text. We won't
2374 get the iterator set up for delivering that ellipsis unless
2375 we make sure that it gets aware of the invisible text. */
2376 if (pos->dpvec_index >= 0
2377 && pos->overlay_string_index < 0
2378 && CHARPOS (pos->string_pos) < 0
2379 && charpos > BEGV
2380 && (XSETWINDOW (window, w),
2381 prop = Fget_char_property (make_number (charpos),
2382 Qinvisible, window),
2383 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2384 {
2385 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2386 window);
2387 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2388 }
2389
2390 return ellipses_p;
2391 }
2392
2393
2394 /* Initialize IT for stepping through current_buffer in window W,
2395 starting at position POS that includes overlay string and display
2396 vector/ control character translation position information. Value
2397 is zero if there are overlay strings with newlines at POS. */
2398
2399 static int
2400 init_from_display_pos (it, w, pos)
2401 struct it *it;
2402 struct window *w;
2403 struct display_pos *pos;
2404 {
2405 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2406 int i, overlay_strings_with_newlines = 0;
2407
2408 /* If POS specifies a position in a display vector, this might
2409 be for an ellipsis displayed for invisible text. We won't
2410 get the iterator set up for delivering that ellipsis unless
2411 we make sure that it gets aware of the invisible text. */
2412 if (in_ellipses_for_invisible_text_p (pos, w))
2413 {
2414 --charpos;
2415 bytepos = 0;
2416 }
2417
2418 /* Keep in mind: the call to reseat in init_iterator skips invisible
2419 text, so we might end up at a position different from POS. This
2420 is only a problem when POS is a row start after a newline and an
2421 overlay starts there with an after-string, and the overlay has an
2422 invisible property. Since we don't skip invisible text in
2423 display_line and elsewhere immediately after consuming the
2424 newline before the row start, such a POS will not be in a string,
2425 but the call to init_iterator below will move us to the
2426 after-string. */
2427 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2428
2429 for (i = 0; i < it->n_overlay_strings; ++i)
2430 {
2431 const char *s = SDATA (it->overlay_strings[i]);
2432 const char *e = s + SBYTES (it->overlay_strings[i]);
2433
2434 while (s < e && *s != '\n')
2435 ++s;
2436
2437 if (s < e)
2438 {
2439 overlay_strings_with_newlines = 1;
2440 break;
2441 }
2442 }
2443
2444 /* If position is within an overlay string, set up IT to the right
2445 overlay string. */
2446 if (pos->overlay_string_index >= 0)
2447 {
2448 int relative_index;
2449
2450 /* If the first overlay string happens to have a `display'
2451 property for an image, the iterator will be set up for that
2452 image, and we have to undo that setup first before we can
2453 correct the overlay string index. */
2454 if (it->method == next_element_from_image)
2455 pop_it (it);
2456
2457 /* We already have the first chunk of overlay strings in
2458 IT->overlay_strings. Load more until the one for
2459 pos->overlay_string_index is in IT->overlay_strings. */
2460 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2461 {
2462 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2463 it->current.overlay_string_index = 0;
2464 while (n--)
2465 {
2466 load_overlay_strings (it, 0);
2467 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2468 }
2469 }
2470
2471 it->current.overlay_string_index = pos->overlay_string_index;
2472 relative_index = (it->current.overlay_string_index
2473 % OVERLAY_STRING_CHUNK_SIZE);
2474 it->string = it->overlay_strings[relative_index];
2475 xassert (STRINGP (it->string));
2476 it->current.string_pos = pos->string_pos;
2477 it->method = next_element_from_string;
2478 }
2479
2480 #if 0 /* This is bogus because POS not having an overlay string
2481 position does not mean it's after the string. Example: A
2482 line starting with a before-string and initialization of IT
2483 to the previous row's end position. */
2484 else if (it->current.overlay_string_index >= 0)
2485 {
2486 /* If POS says we're already after an overlay string ending at
2487 POS, make sure to pop the iterator because it will be in
2488 front of that overlay string. When POS is ZV, we've thereby
2489 also ``processed'' overlay strings at ZV. */
2490 while (it->sp)
2491 pop_it (it);
2492 it->current.overlay_string_index = -1;
2493 it->method = next_element_from_buffer;
2494 if (CHARPOS (pos->pos) == ZV)
2495 it->overlay_strings_at_end_processed_p = 1;
2496 }
2497 #endif /* 0 */
2498
2499 if (CHARPOS (pos->string_pos) >= 0)
2500 {
2501 /* Recorded position is not in an overlay string, but in another
2502 string. This can only be a string from a `display' property.
2503 IT should already be filled with that string. */
2504 it->current.string_pos = pos->string_pos;
2505 xassert (STRINGP (it->string));
2506 }
2507
2508 /* Restore position in display vector translations, control
2509 character translations or ellipses. */
2510 if (pos->dpvec_index >= 0)
2511 {
2512 if (it->dpvec == NULL)
2513 get_next_display_element (it);
2514 xassert (it->dpvec && it->current.dpvec_index == 0);
2515 it->current.dpvec_index = pos->dpvec_index;
2516 }
2517
2518 CHECK_IT (it);
2519 return !overlay_strings_with_newlines;
2520 }
2521
2522
2523 /* Initialize IT for stepping through current_buffer in window W
2524 starting at ROW->start. */
2525
2526 static void
2527 init_to_row_start (it, w, row)
2528 struct it *it;
2529 struct window *w;
2530 struct glyph_row *row;
2531 {
2532 init_from_display_pos (it, w, &row->start);
2533 it->start = row->start;
2534 it->continuation_lines_width = row->continuation_lines_width;
2535 CHECK_IT (it);
2536 }
2537
2538
2539 /* Initialize IT for stepping through current_buffer in window W
2540 starting in the line following ROW, i.e. starting at ROW->end.
2541 Value is zero if there are overlay strings with newlines at ROW's
2542 end position. */
2543
2544 static int
2545 init_to_row_end (it, w, row)
2546 struct it *it;
2547 struct window *w;
2548 struct glyph_row *row;
2549 {
2550 int success = 0;
2551
2552 if (init_from_display_pos (it, w, &row->end))
2553 {
2554 if (row->continued_p)
2555 it->continuation_lines_width
2556 = row->continuation_lines_width + row->pixel_width;
2557 CHECK_IT (it);
2558 success = 1;
2559 }
2560
2561 return success;
2562 }
2563
2564
2565
2566 \f
2567 /***********************************************************************
2568 Text properties
2569 ***********************************************************************/
2570
2571 /* Called when IT reaches IT->stop_charpos. Handle text property and
2572 overlay changes. Set IT->stop_charpos to the next position where
2573 to stop. */
2574
2575 static void
2576 handle_stop (it)
2577 struct it *it;
2578 {
2579 enum prop_handled handled;
2580 int handle_overlay_change_p = 1;
2581 struct props *p;
2582
2583 it->dpvec = NULL;
2584 it->current.dpvec_index = -1;
2585
2586 do
2587 {
2588 handled = HANDLED_NORMALLY;
2589
2590 /* Call text property handlers. */
2591 for (p = it_props; p->handler; ++p)
2592 {
2593 handled = p->handler (it);
2594
2595 if (handled == HANDLED_RECOMPUTE_PROPS)
2596 break;
2597 else if (handled == HANDLED_RETURN)
2598 return;
2599 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2600 handle_overlay_change_p = 0;
2601 }
2602
2603 if (handled != HANDLED_RECOMPUTE_PROPS)
2604 {
2605 /* Don't check for overlay strings below when set to deliver
2606 characters from a display vector. */
2607 if (it->method == next_element_from_display_vector)
2608 handle_overlay_change_p = 0;
2609
2610 /* Handle overlay changes. */
2611 if (handle_overlay_change_p)
2612 handled = handle_overlay_change (it);
2613
2614 /* Determine where to stop next. */
2615 if (handled == HANDLED_NORMALLY)
2616 compute_stop_pos (it);
2617 }
2618 }
2619 while (handled == HANDLED_RECOMPUTE_PROPS);
2620 }
2621
2622
2623 /* Compute IT->stop_charpos from text property and overlay change
2624 information for IT's current position. */
2625
2626 static void
2627 compute_stop_pos (it)
2628 struct it *it;
2629 {
2630 register INTERVAL iv, next_iv;
2631 Lisp_Object object, limit, position;
2632
2633 /* If nowhere else, stop at the end. */
2634 it->stop_charpos = it->end_charpos;
2635
2636 if (STRINGP (it->string))
2637 {
2638 /* Strings are usually short, so don't limit the search for
2639 properties. */
2640 object = it->string;
2641 limit = Qnil;
2642 position = make_number (IT_STRING_CHARPOS (*it));
2643 }
2644 else
2645 {
2646 int charpos;
2647
2648 /* If next overlay change is in front of the current stop pos
2649 (which is IT->end_charpos), stop there. Note: value of
2650 next_overlay_change is point-max if no overlay change
2651 follows. */
2652 charpos = next_overlay_change (IT_CHARPOS (*it));
2653 if (charpos < it->stop_charpos)
2654 it->stop_charpos = charpos;
2655
2656 /* If showing the region, we have to stop at the region
2657 start or end because the face might change there. */
2658 if (it->region_beg_charpos > 0)
2659 {
2660 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2661 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2662 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2663 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2664 }
2665
2666 /* Set up variables for computing the stop position from text
2667 property changes. */
2668 XSETBUFFER (object, current_buffer);
2669 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2670 position = make_number (IT_CHARPOS (*it));
2671
2672 }
2673
2674 /* Get the interval containing IT's position. Value is a null
2675 interval if there isn't such an interval. */
2676 iv = validate_interval_range (object, &position, &position, 0);
2677 if (!NULL_INTERVAL_P (iv))
2678 {
2679 Lisp_Object values_here[LAST_PROP_IDX];
2680 struct props *p;
2681
2682 /* Get properties here. */
2683 for (p = it_props; p->handler; ++p)
2684 values_here[p->idx] = textget (iv->plist, *p->name);
2685
2686 /* Look for an interval following iv that has different
2687 properties. */
2688 for (next_iv = next_interval (iv);
2689 (!NULL_INTERVAL_P (next_iv)
2690 && (NILP (limit)
2691 || XFASTINT (limit) > next_iv->position));
2692 next_iv = next_interval (next_iv))
2693 {
2694 for (p = it_props; p->handler; ++p)
2695 {
2696 Lisp_Object new_value;
2697
2698 new_value = textget (next_iv->plist, *p->name);
2699 if (!EQ (values_here[p->idx], new_value))
2700 break;
2701 }
2702
2703 if (p->handler)
2704 break;
2705 }
2706
2707 if (!NULL_INTERVAL_P (next_iv))
2708 {
2709 if (INTEGERP (limit)
2710 && next_iv->position >= XFASTINT (limit))
2711 /* No text property change up to limit. */
2712 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2713 else
2714 /* Text properties change in next_iv. */
2715 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2716 }
2717 }
2718
2719 xassert (STRINGP (it->string)
2720 || (it->stop_charpos >= BEGV
2721 && it->stop_charpos >= IT_CHARPOS (*it)));
2722 }
2723
2724
2725 /* Return the position of the next overlay change after POS in
2726 current_buffer. Value is point-max if no overlay change
2727 follows. This is like `next-overlay-change' but doesn't use
2728 xmalloc. */
2729
2730 static int
2731 next_overlay_change (pos)
2732 int pos;
2733 {
2734 int noverlays;
2735 int endpos;
2736 Lisp_Object *overlays;
2737 int i;
2738
2739 /* Get all overlays at the given position. */
2740 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2741
2742 /* If any of these overlays ends before endpos,
2743 use its ending point instead. */
2744 for (i = 0; i < noverlays; ++i)
2745 {
2746 Lisp_Object oend;
2747 int oendpos;
2748
2749 oend = OVERLAY_END (overlays[i]);
2750 oendpos = OVERLAY_POSITION (oend);
2751 endpos = min (endpos, oendpos);
2752 }
2753
2754 return endpos;
2755 }
2756
2757
2758 \f
2759 /***********************************************************************
2760 Fontification
2761 ***********************************************************************/
2762
2763 /* Handle changes in the `fontified' property of the current buffer by
2764 calling hook functions from Qfontification_functions to fontify
2765 regions of text. */
2766
2767 static enum prop_handled
2768 handle_fontified_prop (it)
2769 struct it *it;
2770 {
2771 Lisp_Object prop, pos;
2772 enum prop_handled handled = HANDLED_NORMALLY;
2773
2774 /* Get the value of the `fontified' property at IT's current buffer
2775 position. (The `fontified' property doesn't have a special
2776 meaning in strings.) If the value is nil, call functions from
2777 Qfontification_functions. */
2778 if (!STRINGP (it->string)
2779 && it->s == NULL
2780 && !NILP (Vfontification_functions)
2781 && !NILP (Vrun_hooks)
2782 && (pos = make_number (IT_CHARPOS (*it)),
2783 prop = Fget_char_property (pos, Qfontified, Qnil),
2784 NILP (prop)))
2785 {
2786 int count = SPECPDL_INDEX ();
2787 Lisp_Object val;
2788
2789 val = Vfontification_functions;
2790 specbind (Qfontification_functions, Qnil);
2791
2792 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2793 safe_call1 (val, pos);
2794 else
2795 {
2796 Lisp_Object globals, fn;
2797 struct gcpro gcpro1, gcpro2;
2798
2799 globals = Qnil;
2800 GCPRO2 (val, globals);
2801
2802 for (; CONSP (val); val = XCDR (val))
2803 {
2804 fn = XCAR (val);
2805
2806 if (EQ (fn, Qt))
2807 {
2808 /* A value of t indicates this hook has a local
2809 binding; it means to run the global binding too.
2810 In a global value, t should not occur. If it
2811 does, we must ignore it to avoid an endless
2812 loop. */
2813 for (globals = Fdefault_value (Qfontification_functions);
2814 CONSP (globals);
2815 globals = XCDR (globals))
2816 {
2817 fn = XCAR (globals);
2818 if (!EQ (fn, Qt))
2819 safe_call1 (fn, pos);
2820 }
2821 }
2822 else
2823 safe_call1 (fn, pos);
2824 }
2825
2826 UNGCPRO;
2827 }
2828
2829 unbind_to (count, Qnil);
2830
2831 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2832 something. This avoids an endless loop if they failed to
2833 fontify the text for which reason ever. */
2834 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2835 handled = HANDLED_RECOMPUTE_PROPS;
2836 }
2837
2838 return handled;
2839 }
2840
2841
2842 \f
2843 /***********************************************************************
2844 Faces
2845 ***********************************************************************/
2846
2847 /* Set up iterator IT from face properties at its current position.
2848 Called from handle_stop. */
2849
2850 static enum prop_handled
2851 handle_face_prop (it)
2852 struct it *it;
2853 {
2854 int new_face_id, next_stop;
2855
2856 if (!STRINGP (it->string))
2857 {
2858 new_face_id
2859 = face_at_buffer_position (it->w,
2860 IT_CHARPOS (*it),
2861 it->region_beg_charpos,
2862 it->region_end_charpos,
2863 &next_stop,
2864 (IT_CHARPOS (*it)
2865 + TEXT_PROP_DISTANCE_LIMIT),
2866 0);
2867
2868 /* Is this a start of a run of characters with box face?
2869 Caveat: this can be called for a freshly initialized
2870 iterator; face_id is -1 in this case. We know that the new
2871 face will not change until limit, i.e. if the new face has a
2872 box, all characters up to limit will have one. But, as
2873 usual, we don't know whether limit is really the end. */
2874 if (new_face_id != it->face_id)
2875 {
2876 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2877
2878 /* If new face has a box but old face has not, this is
2879 the start of a run of characters with box, i.e. it has
2880 a shadow on the left side. The value of face_id of the
2881 iterator will be -1 if this is the initial call that gets
2882 the face. In this case, we have to look in front of IT's
2883 position and see whether there is a face != new_face_id. */
2884 it->start_of_box_run_p
2885 = (new_face->box != FACE_NO_BOX
2886 && (it->face_id >= 0
2887 || IT_CHARPOS (*it) == BEG
2888 || new_face_id != face_before_it_pos (it)));
2889 it->face_box_p = new_face->box != FACE_NO_BOX;
2890 }
2891 }
2892 else
2893 {
2894 int base_face_id, bufpos;
2895
2896 if (it->current.overlay_string_index >= 0)
2897 bufpos = IT_CHARPOS (*it);
2898 else
2899 bufpos = 0;
2900
2901 /* For strings from a buffer, i.e. overlay strings or strings
2902 from a `display' property, use the face at IT's current
2903 buffer position as the base face to merge with, so that
2904 overlay strings appear in the same face as surrounding
2905 text, unless they specify their own faces. */
2906 base_face_id = underlying_face_id (it);
2907
2908 new_face_id = face_at_string_position (it->w,
2909 it->string,
2910 IT_STRING_CHARPOS (*it),
2911 bufpos,
2912 it->region_beg_charpos,
2913 it->region_end_charpos,
2914 &next_stop,
2915 base_face_id, 0);
2916
2917 #if 0 /* This shouldn't be neccessary. Let's check it. */
2918 /* If IT is used to display a mode line we would really like to
2919 use the mode line face instead of the frame's default face. */
2920 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2921 && new_face_id == DEFAULT_FACE_ID)
2922 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2923 #endif
2924
2925 /* Is this a start of a run of characters with box? Caveat:
2926 this can be called for a freshly allocated iterator; face_id
2927 is -1 is this case. We know that the new face will not
2928 change until the next check pos, i.e. if the new face has a
2929 box, all characters up to that position will have a
2930 box. But, as usual, we don't know whether that position
2931 is really the end. */
2932 if (new_face_id != it->face_id)
2933 {
2934 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2935 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2936
2937 /* If new face has a box but old face hasn't, this is the
2938 start of a run of characters with box, i.e. it has a
2939 shadow on the left side. */
2940 it->start_of_box_run_p
2941 = new_face->box && (old_face == NULL || !old_face->box);
2942 it->face_box_p = new_face->box != FACE_NO_BOX;
2943 }
2944 }
2945
2946 it->face_id = new_face_id;
2947 return HANDLED_NORMALLY;
2948 }
2949
2950
2951 /* Return the ID of the face ``underlying'' IT's current position,
2952 which is in a string. If the iterator is associated with a
2953 buffer, return the face at IT's current buffer position.
2954 Otherwise, use the iterator's base_face_id. */
2955
2956 static int
2957 underlying_face_id (it)
2958 struct it *it;
2959 {
2960 int face_id = it->base_face_id, i;
2961
2962 xassert (STRINGP (it->string));
2963
2964 for (i = it->sp - 1; i >= 0; --i)
2965 if (NILP (it->stack[i].string))
2966 face_id = it->stack[i].face_id;
2967
2968 return face_id;
2969 }
2970
2971
2972 /* Compute the face one character before or after the current position
2973 of IT. BEFORE_P non-zero means get the face in front of IT's
2974 position. Value is the id of the face. */
2975
2976 static int
2977 face_before_or_after_it_pos (it, before_p)
2978 struct it *it;
2979 int before_p;
2980 {
2981 int face_id, limit;
2982 int next_check_charpos;
2983 struct text_pos pos;
2984
2985 xassert (it->s == NULL);
2986
2987 if (STRINGP (it->string))
2988 {
2989 int bufpos, base_face_id;
2990
2991 /* No face change past the end of the string (for the case
2992 we are padding with spaces). No face change before the
2993 string start. */
2994 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2995 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2996 return it->face_id;
2997
2998 /* Set pos to the position before or after IT's current position. */
2999 if (before_p)
3000 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3001 else
3002 /* For composition, we must check the character after the
3003 composition. */
3004 pos = (it->what == IT_COMPOSITION
3005 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3006 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3007
3008 if (it->current.overlay_string_index >= 0)
3009 bufpos = IT_CHARPOS (*it);
3010 else
3011 bufpos = 0;
3012
3013 base_face_id = underlying_face_id (it);
3014
3015 /* Get the face for ASCII, or unibyte. */
3016 face_id = face_at_string_position (it->w,
3017 it->string,
3018 CHARPOS (pos),
3019 bufpos,
3020 it->region_beg_charpos,
3021 it->region_end_charpos,
3022 &next_check_charpos,
3023 base_face_id, 0);
3024
3025 /* Correct the face for charsets different from ASCII. Do it
3026 for the multibyte case only. The face returned above is
3027 suitable for unibyte text if IT->string is unibyte. */
3028 if (STRING_MULTIBYTE (it->string))
3029 {
3030 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3031 int rest = SBYTES (it->string) - BYTEPOS (pos);
3032 int c, len;
3033 struct face *face = FACE_FROM_ID (it->f, face_id);
3034
3035 c = string_char_and_length (p, rest, &len);
3036 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3037 }
3038 }
3039 else
3040 {
3041 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3042 || (IT_CHARPOS (*it) <= BEGV && before_p))
3043 return it->face_id;
3044
3045 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3046 pos = it->current.pos;
3047
3048 if (before_p)
3049 DEC_TEXT_POS (pos, it->multibyte_p);
3050 else
3051 {
3052 if (it->what == IT_COMPOSITION)
3053 /* For composition, we must check the position after the
3054 composition. */
3055 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3056 else
3057 INC_TEXT_POS (pos, it->multibyte_p);
3058 }
3059
3060 /* Determine face for CHARSET_ASCII, or unibyte. */
3061 face_id = face_at_buffer_position (it->w,
3062 CHARPOS (pos),
3063 it->region_beg_charpos,
3064 it->region_end_charpos,
3065 &next_check_charpos,
3066 limit, 0);
3067
3068 /* Correct the face for charsets different from ASCII. Do it
3069 for the multibyte case only. The face returned above is
3070 suitable for unibyte text if current_buffer is unibyte. */
3071 if (it->multibyte_p)
3072 {
3073 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3074 struct face *face = FACE_FROM_ID (it->f, face_id);
3075 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3076 }
3077 }
3078
3079 return face_id;
3080 }
3081
3082
3083 \f
3084 /***********************************************************************
3085 Invisible text
3086 ***********************************************************************/
3087
3088 /* Set up iterator IT from invisible properties at its current
3089 position. Called from handle_stop. */
3090
3091 static enum prop_handled
3092 handle_invisible_prop (it)
3093 struct it *it;
3094 {
3095 enum prop_handled handled = HANDLED_NORMALLY;
3096
3097 if (STRINGP (it->string))
3098 {
3099 extern Lisp_Object Qinvisible;
3100 Lisp_Object prop, end_charpos, limit, charpos;
3101
3102 /* Get the value of the invisible text property at the
3103 current position. Value will be nil if there is no such
3104 property. */
3105 charpos = make_number (IT_STRING_CHARPOS (*it));
3106 prop = Fget_text_property (charpos, Qinvisible, it->string);
3107
3108 if (!NILP (prop)
3109 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3110 {
3111 handled = HANDLED_RECOMPUTE_PROPS;
3112
3113 /* Get the position at which the next change of the
3114 invisible text property can be found in IT->string.
3115 Value will be nil if the property value is the same for
3116 all the rest of IT->string. */
3117 XSETINT (limit, SCHARS (it->string));
3118 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3119 it->string, limit);
3120
3121 /* Text at current position is invisible. The next
3122 change in the property is at position end_charpos.
3123 Move IT's current position to that position. */
3124 if (INTEGERP (end_charpos)
3125 && XFASTINT (end_charpos) < XFASTINT (limit))
3126 {
3127 struct text_pos old;
3128 old = it->current.string_pos;
3129 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3130 compute_string_pos (&it->current.string_pos, old, it->string);
3131 }
3132 else
3133 {
3134 /* The rest of the string is invisible. If this is an
3135 overlay string, proceed with the next overlay string
3136 or whatever comes and return a character from there. */
3137 if (it->current.overlay_string_index >= 0)
3138 {
3139 next_overlay_string (it);
3140 /* Don't check for overlay strings when we just
3141 finished processing them. */
3142 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3143 }
3144 else
3145 {
3146 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3147 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3148 }
3149 }
3150 }
3151 }
3152 else
3153 {
3154 int invis_p, newpos, next_stop, start_charpos;
3155 Lisp_Object pos, prop, overlay;
3156
3157 /* First of all, is there invisible text at this position? */
3158 start_charpos = IT_CHARPOS (*it);
3159 pos = make_number (IT_CHARPOS (*it));
3160 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3161 &overlay);
3162 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3163
3164 /* If we are on invisible text, skip over it. */
3165 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3166 {
3167 /* Record whether we have to display an ellipsis for the
3168 invisible text. */
3169 int display_ellipsis_p = invis_p == 2;
3170
3171 handled = HANDLED_RECOMPUTE_PROPS;
3172
3173 /* Loop skipping over invisible text. The loop is left at
3174 ZV or with IT on the first char being visible again. */
3175 do
3176 {
3177 /* Try to skip some invisible text. Return value is the
3178 position reached which can be equal to IT's position
3179 if there is nothing invisible here. This skips both
3180 over invisible text properties and overlays with
3181 invisible property. */
3182 newpos = skip_invisible (IT_CHARPOS (*it),
3183 &next_stop, ZV, it->window);
3184
3185 /* If we skipped nothing at all we weren't at invisible
3186 text in the first place. If everything to the end of
3187 the buffer was skipped, end the loop. */
3188 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3189 invis_p = 0;
3190 else
3191 {
3192 /* We skipped some characters but not necessarily
3193 all there are. Check if we ended up on visible
3194 text. Fget_char_property returns the property of
3195 the char before the given position, i.e. if we
3196 get invis_p = 0, this means that the char at
3197 newpos is visible. */
3198 pos = make_number (newpos);
3199 prop = Fget_char_property (pos, Qinvisible, it->window);
3200 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3201 }
3202
3203 /* If we ended up on invisible text, proceed to
3204 skip starting with next_stop. */
3205 if (invis_p)
3206 IT_CHARPOS (*it) = next_stop;
3207 }
3208 while (invis_p);
3209
3210 /* The position newpos is now either ZV or on visible text. */
3211 IT_CHARPOS (*it) = newpos;
3212 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3213
3214 /* If there are before-strings at the start of invisible
3215 text, and the text is invisible because of a text
3216 property, arrange to show before-strings because 20.x did
3217 it that way. (If the text is invisible because of an
3218 overlay property instead of a text property, this is
3219 already handled in the overlay code.) */
3220 if (NILP (overlay)
3221 && get_overlay_strings (it, start_charpos))
3222 {
3223 handled = HANDLED_RECOMPUTE_PROPS;
3224 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3225 }
3226 else if (display_ellipsis_p)
3227 setup_for_ellipsis (it);
3228 }
3229 }
3230
3231 return handled;
3232 }
3233
3234
3235 /* Make iterator IT return `...' next. */
3236
3237 static void
3238 setup_for_ellipsis (it)
3239 struct it *it;
3240 {
3241 if (it->dp
3242 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3243 {
3244 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3245 it->dpvec = v->contents;
3246 it->dpend = v->contents + v->size;
3247 }
3248 else
3249 {
3250 /* Default `...'. */
3251 it->dpvec = default_invis_vector;
3252 it->dpend = default_invis_vector + 3;
3253 }
3254
3255 /* The ellipsis display does not replace the display of the
3256 character at the new position. Indicate this by setting
3257 IT->dpvec_char_len to zero. */
3258 it->dpvec_char_len = 0;
3259
3260 it->current.dpvec_index = 0;
3261 it->method = next_element_from_display_vector;
3262 }
3263
3264
3265 \f
3266 /***********************************************************************
3267 'display' property
3268 ***********************************************************************/
3269
3270 /* Set up iterator IT from `display' property at its current position.
3271 Called from handle_stop. */
3272
3273 static enum prop_handled
3274 handle_display_prop (it)
3275 struct it *it;
3276 {
3277 Lisp_Object prop, object;
3278 struct text_pos *position;
3279 int display_replaced_p = 0;
3280
3281 if (STRINGP (it->string))
3282 {
3283 object = it->string;
3284 position = &it->current.string_pos;
3285 }
3286 else
3287 {
3288 object = it->w->buffer;
3289 position = &it->current.pos;
3290 }
3291
3292 /* Reset those iterator values set from display property values. */
3293 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3294 it->space_width = Qnil;
3295 it->font_height = Qnil;
3296 it->voffset = 0;
3297
3298 /* We don't support recursive `display' properties, i.e. string
3299 values that have a string `display' property, that have a string
3300 `display' property etc. */
3301 if (!it->string_from_display_prop_p)
3302 it->area = TEXT_AREA;
3303
3304 prop = Fget_char_property (make_number (position->charpos),
3305 Qdisplay, object);
3306 if (NILP (prop))
3307 return HANDLED_NORMALLY;
3308
3309 if (CONSP (prop)
3310 /* Simple properties. */
3311 && !EQ (XCAR (prop), Qimage)
3312 && !EQ (XCAR (prop), Qspace)
3313 && !EQ (XCAR (prop), Qwhen)
3314 && !EQ (XCAR (prop), Qslice)
3315 && !EQ (XCAR (prop), Qspace_width)
3316 && !EQ (XCAR (prop), Qheight)
3317 && !EQ (XCAR (prop), Qraise)
3318 /* Marginal area specifications. */
3319 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3320 && !EQ (XCAR (prop), Qleft_fringe)
3321 && !EQ (XCAR (prop), Qright_fringe)
3322 && !NILP (XCAR (prop)))
3323 {
3324 for (; CONSP (prop); prop = XCDR (prop))
3325 {
3326 if (handle_single_display_prop (it, XCAR (prop), object,
3327 position, display_replaced_p))
3328 display_replaced_p = 1;
3329 }
3330 }
3331 else if (VECTORP (prop))
3332 {
3333 int i;
3334 for (i = 0; i < ASIZE (prop); ++i)
3335 if (handle_single_display_prop (it, AREF (prop, i), object,
3336 position, display_replaced_p))
3337 display_replaced_p = 1;
3338 }
3339 else
3340 {
3341 if (handle_single_display_prop (it, prop, object, position, 0))
3342 display_replaced_p = 1;
3343 }
3344
3345 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3346 }
3347
3348
3349 /* Value is the position of the end of the `display' property starting
3350 at START_POS in OBJECT. */
3351
3352 static struct text_pos
3353 display_prop_end (it, object, start_pos)
3354 struct it *it;
3355 Lisp_Object object;
3356 struct text_pos start_pos;
3357 {
3358 Lisp_Object end;
3359 struct text_pos end_pos;
3360
3361 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3362 Qdisplay, object, Qnil);
3363 CHARPOS (end_pos) = XFASTINT (end);
3364 if (STRINGP (object))
3365 compute_string_pos (&end_pos, start_pos, it->string);
3366 else
3367 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3368
3369 return end_pos;
3370 }
3371
3372
3373 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3374 is the object in which the `display' property was found. *POSITION
3375 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3376 means that we previously saw a display sub-property which already
3377 replaced text display with something else, for example an image;
3378 ignore such properties after the first one has been processed.
3379
3380 If PROP is a `space' or `image' sub-property, set *POSITION to the
3381 end position of the `display' property.
3382
3383 Value is non-zero if something was found which replaces the display
3384 of buffer or string text. */
3385
3386 static int
3387 handle_single_display_prop (it, prop, object, position,
3388 display_replaced_before_p)
3389 struct it *it;
3390 Lisp_Object prop;
3391 Lisp_Object object;
3392 struct text_pos *position;
3393 int display_replaced_before_p;
3394 {
3395 Lisp_Object value;
3396 int replaces_text_display_p = 0;
3397 Lisp_Object form;
3398
3399 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3400 evaluated. If the result is nil, VALUE is ignored. */
3401 form = Qt;
3402 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3403 {
3404 prop = XCDR (prop);
3405 if (!CONSP (prop))
3406 return 0;
3407 form = XCAR (prop);
3408 prop = XCDR (prop);
3409 }
3410
3411 if (!NILP (form) && !EQ (form, Qt))
3412 {
3413 int count = SPECPDL_INDEX ();
3414 struct gcpro gcpro1;
3415
3416 /* Bind `object' to the object having the `display' property, a
3417 buffer or string. Bind `position' to the position in the
3418 object where the property was found, and `buffer-position'
3419 to the current position in the buffer. */
3420 specbind (Qobject, object);
3421 specbind (Qposition, make_number (CHARPOS (*position)));
3422 specbind (Qbuffer_position,
3423 make_number (STRINGP (object)
3424 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3425 GCPRO1 (form);
3426 form = safe_eval (form);
3427 UNGCPRO;
3428 unbind_to (count, Qnil);
3429 }
3430
3431 if (NILP (form))
3432 return 0;
3433
3434 if (CONSP (prop)
3435 && EQ (XCAR (prop), Qheight)
3436 && CONSP (XCDR (prop)))
3437 {
3438 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3439 return 0;
3440
3441 /* `(height HEIGHT)'. */
3442 it->font_height = XCAR (XCDR (prop));
3443 if (!NILP (it->font_height))
3444 {
3445 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3446 int new_height = -1;
3447
3448 if (CONSP (it->font_height)
3449 && (EQ (XCAR (it->font_height), Qplus)
3450 || EQ (XCAR (it->font_height), Qminus))
3451 && CONSP (XCDR (it->font_height))
3452 && INTEGERP (XCAR (XCDR (it->font_height))))
3453 {
3454 /* `(+ N)' or `(- N)' where N is an integer. */
3455 int steps = XINT (XCAR (XCDR (it->font_height)));
3456 if (EQ (XCAR (it->font_height), Qplus))
3457 steps = - steps;
3458 it->face_id = smaller_face (it->f, it->face_id, steps);
3459 }
3460 else if (FUNCTIONP (it->font_height))
3461 {
3462 /* Call function with current height as argument.
3463 Value is the new height. */
3464 Lisp_Object height;
3465 height = safe_call1 (it->font_height,
3466 face->lface[LFACE_HEIGHT_INDEX]);
3467 if (NUMBERP (height))
3468 new_height = XFLOATINT (height);
3469 }
3470 else if (NUMBERP (it->font_height))
3471 {
3472 /* Value is a multiple of the canonical char height. */
3473 struct face *face;
3474
3475 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3476 new_height = (XFLOATINT (it->font_height)
3477 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3478 }
3479 else
3480 {
3481 /* Evaluate IT->font_height with `height' bound to the
3482 current specified height to get the new height. */
3483 Lisp_Object value;
3484 int count = SPECPDL_INDEX ();
3485
3486 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3487 value = safe_eval (it->font_height);
3488 unbind_to (count, Qnil);
3489
3490 if (NUMBERP (value))
3491 new_height = XFLOATINT (value);
3492 }
3493
3494 if (new_height > 0)
3495 it->face_id = face_with_height (it->f, it->face_id, new_height);
3496 }
3497 }
3498 else if (CONSP (prop)
3499 && EQ (XCAR (prop), Qspace_width)
3500 && CONSP (XCDR (prop)))
3501 {
3502 /* `(space_width WIDTH)'. */
3503 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3504 return 0;
3505
3506 value = XCAR (XCDR (prop));
3507 if (NUMBERP (value) && XFLOATINT (value) > 0)
3508 it->space_width = value;
3509 }
3510 else if (CONSP (prop)
3511 && EQ (XCAR (prop), Qslice))
3512 {
3513 /* `(slice X Y WIDTH HEIGHT)'. */
3514 Lisp_Object tem;
3515
3516 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3517 return 0;
3518
3519 if (tem = XCDR (prop), CONSP (tem))
3520 {
3521 it->slice.x = XCAR (tem);
3522 if (tem = XCDR (tem), CONSP (tem))
3523 {
3524 it->slice.y = XCAR (tem);
3525 if (tem = XCDR (tem), CONSP (tem))
3526 {
3527 it->slice.width = XCAR (tem);
3528 if (tem = XCDR (tem), CONSP (tem))
3529 it->slice.height = XCAR (tem);
3530 }
3531 }
3532 }
3533 }
3534 else if (CONSP (prop)
3535 && EQ (XCAR (prop), Qraise)
3536 && CONSP (XCDR (prop)))
3537 {
3538 /* `(raise FACTOR)'. */
3539 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3540 return 0;
3541
3542 #ifdef HAVE_WINDOW_SYSTEM
3543 value = XCAR (XCDR (prop));
3544 if (NUMBERP (value))
3545 {
3546 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3547 it->voffset = - (XFLOATINT (value)
3548 * (FONT_HEIGHT (face->font)));
3549 }
3550 #endif /* HAVE_WINDOW_SYSTEM */
3551 }
3552 else if (!it->string_from_display_prop_p)
3553 {
3554 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3555 VALUE) or `((margin nil) VALUE)' or VALUE. */
3556 Lisp_Object location, value;
3557 struct text_pos start_pos;
3558 int valid_p;
3559
3560 /* Characters having this form of property are not displayed, so
3561 we have to find the end of the property. */
3562 start_pos = *position;
3563 *position = display_prop_end (it, object, start_pos);
3564 value = Qnil;
3565
3566 /* Let's stop at the new position and assume that all
3567 text properties change there. */
3568 it->stop_charpos = position->charpos;
3569
3570 if (CONSP (prop)
3571 && (EQ (XCAR (prop), Qleft_fringe)
3572 || EQ (XCAR (prop), Qright_fringe))
3573 && CONSP (XCDR (prop)))
3574 {
3575 unsigned face_id = DEFAULT_FACE_ID;
3576 int fringe_bitmap;
3577
3578 /* Save current settings of IT so that we can restore them
3579 when we are finished with the glyph property value. */
3580
3581 /* `(left-fringe BITMAP FACE)'. */
3582 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3583 return 0;
3584
3585 #ifdef HAVE_WINDOW_SYSTEM
3586 value = XCAR (XCDR (prop));
3587 if (!SYMBOLP (value)
3588 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3589 return 0;
3590
3591 if (CONSP (XCDR (XCDR (prop))))
3592 {
3593 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3594
3595 face_id = lookup_named_face (it->f, face_name);
3596 if (face_id < 0)
3597 return 0;
3598 }
3599
3600 push_it (it);
3601
3602 it->area = TEXT_AREA;
3603 it->what = IT_IMAGE;
3604 it->image_id = -1; /* no image */
3605 it->position = start_pos;
3606 it->object = NILP (object) ? it->w->buffer : object;
3607 it->method = next_element_from_image;
3608 it->face_id = face_id;
3609
3610 /* Say that we haven't consumed the characters with
3611 `display' property yet. The call to pop_it in
3612 set_iterator_to_next will clean this up. */
3613 *position = start_pos;
3614
3615 if (EQ (XCAR (prop), Qleft_fringe))
3616 {
3617 it->left_user_fringe_bitmap = fringe_bitmap;
3618 it->left_user_fringe_face_id = face_id;
3619 }
3620 else
3621 {
3622 it->right_user_fringe_bitmap = fringe_bitmap;
3623 it->right_user_fringe_face_id = face_id;
3624 }
3625 #endif /* HAVE_WINDOW_SYSTEM */
3626 return 1;
3627 }
3628
3629 location = Qunbound;
3630 if (CONSP (prop) && CONSP (XCAR (prop)))
3631 {
3632 Lisp_Object tem;
3633
3634 value = XCDR (prop);
3635 if (CONSP (value))
3636 value = XCAR (value);
3637
3638 tem = XCAR (prop);
3639 if (EQ (XCAR (tem), Qmargin)
3640 && (tem = XCDR (tem),
3641 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3642 (NILP (tem)
3643 || EQ (tem, Qleft_margin)
3644 || EQ (tem, Qright_margin))))
3645 location = tem;
3646 }
3647
3648 if (EQ (location, Qunbound))
3649 {
3650 location = Qnil;
3651 value = prop;
3652 }
3653
3654 valid_p = (STRINGP (value)
3655 #ifdef HAVE_WINDOW_SYSTEM
3656 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3657 #endif /* not HAVE_WINDOW_SYSTEM */
3658 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3659
3660 if ((EQ (location, Qleft_margin)
3661 || EQ (location, Qright_margin)
3662 || NILP (location))
3663 && valid_p
3664 && !display_replaced_before_p)
3665 {
3666 replaces_text_display_p = 1;
3667
3668 /* Save current settings of IT so that we can restore them
3669 when we are finished with the glyph property value. */
3670 push_it (it);
3671
3672 if (NILP (location))
3673 it->area = TEXT_AREA;
3674 else if (EQ (location, Qleft_margin))
3675 it->area = LEFT_MARGIN_AREA;
3676 else
3677 it->area = RIGHT_MARGIN_AREA;
3678
3679 if (STRINGP (value))
3680 {
3681 it->string = value;
3682 it->multibyte_p = STRING_MULTIBYTE (it->string);
3683 it->current.overlay_string_index = -1;
3684 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3685 it->end_charpos = it->string_nchars = SCHARS (it->string);
3686 it->method = next_element_from_string;
3687 it->stop_charpos = 0;
3688 it->string_from_display_prop_p = 1;
3689 /* Say that we haven't consumed the characters with
3690 `display' property yet. The call to pop_it in
3691 set_iterator_to_next will clean this up. */
3692 *position = start_pos;
3693 }
3694 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3695 {
3696 it->method = next_element_from_stretch;
3697 it->object = value;
3698 it->current.pos = it->position = start_pos;
3699 }
3700 #ifdef HAVE_WINDOW_SYSTEM
3701 else
3702 {
3703 it->what = IT_IMAGE;
3704 it->image_id = lookup_image (it->f, value);
3705 it->position = start_pos;
3706 it->object = NILP (object) ? it->w->buffer : object;
3707 it->method = next_element_from_image;
3708
3709 /* Say that we haven't consumed the characters with
3710 `display' property yet. The call to pop_it in
3711 set_iterator_to_next will clean this up. */
3712 *position = start_pos;
3713 }
3714 #endif /* HAVE_WINDOW_SYSTEM */
3715 }
3716 else
3717 /* Invalid property or property not supported. Restore
3718 the position to what it was before. */
3719 *position = start_pos;
3720 }
3721
3722 return replaces_text_display_p;
3723 }
3724
3725
3726 /* Check if PROP is a display sub-property value whose text should be
3727 treated as intangible. */
3728
3729 static int
3730 single_display_prop_intangible_p (prop)
3731 Lisp_Object prop;
3732 {
3733 /* Skip over `when FORM'. */
3734 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3735 {
3736 prop = XCDR (prop);
3737 if (!CONSP (prop))
3738 return 0;
3739 prop = XCDR (prop);
3740 }
3741
3742 if (STRINGP (prop))
3743 return 1;
3744
3745 if (!CONSP (prop))
3746 return 0;
3747
3748 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3749 we don't need to treat text as intangible. */
3750 if (EQ (XCAR (prop), Qmargin))
3751 {
3752 prop = XCDR (prop);
3753 if (!CONSP (prop))
3754 return 0;
3755
3756 prop = XCDR (prop);
3757 if (!CONSP (prop)
3758 || EQ (XCAR (prop), Qleft_margin)
3759 || EQ (XCAR (prop), Qright_margin))
3760 return 0;
3761 }
3762
3763 return (CONSP (prop)
3764 && (EQ (XCAR (prop), Qimage)
3765 || EQ (XCAR (prop), Qspace)));
3766 }
3767
3768
3769 /* Check if PROP is a display property value whose text should be
3770 treated as intangible. */
3771
3772 int
3773 display_prop_intangible_p (prop)
3774 Lisp_Object prop;
3775 {
3776 if (CONSP (prop)
3777 && CONSP (XCAR (prop))
3778 && !EQ (Qmargin, XCAR (XCAR (prop))))
3779 {
3780 /* A list of sub-properties. */
3781 while (CONSP (prop))
3782 {
3783 if (single_display_prop_intangible_p (XCAR (prop)))
3784 return 1;
3785 prop = XCDR (prop);
3786 }
3787 }
3788 else if (VECTORP (prop))
3789 {
3790 /* A vector of sub-properties. */
3791 int i;
3792 for (i = 0; i < ASIZE (prop); ++i)
3793 if (single_display_prop_intangible_p (AREF (prop, i)))
3794 return 1;
3795 }
3796 else
3797 return single_display_prop_intangible_p (prop);
3798
3799 return 0;
3800 }
3801
3802
3803 /* Return 1 if PROP is a display sub-property value containing STRING. */
3804
3805 static int
3806 single_display_prop_string_p (prop, string)
3807 Lisp_Object prop, string;
3808 {
3809 if (EQ (string, prop))
3810 return 1;
3811
3812 /* Skip over `when FORM'. */
3813 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3814 {
3815 prop = XCDR (prop);
3816 if (!CONSP (prop))
3817 return 0;
3818 prop = XCDR (prop);
3819 }
3820
3821 if (CONSP (prop))
3822 /* Skip over `margin LOCATION'. */
3823 if (EQ (XCAR (prop), Qmargin))
3824 {
3825 prop = XCDR (prop);
3826 if (!CONSP (prop))
3827 return 0;
3828
3829 prop = XCDR (prop);
3830 if (!CONSP (prop))
3831 return 0;
3832 }
3833
3834 return CONSP (prop) && EQ (XCAR (prop), string);
3835 }
3836
3837
3838 /* Return 1 if STRING appears in the `display' property PROP. */
3839
3840 static int
3841 display_prop_string_p (prop, string)
3842 Lisp_Object prop, string;
3843 {
3844 if (CONSP (prop)
3845 && CONSP (XCAR (prop))
3846 && !EQ (Qmargin, XCAR (XCAR (prop))))
3847 {
3848 /* A list of sub-properties. */
3849 while (CONSP (prop))
3850 {
3851 if (single_display_prop_string_p (XCAR (prop), string))
3852 return 1;
3853 prop = XCDR (prop);
3854 }
3855 }
3856 else if (VECTORP (prop))
3857 {
3858 /* A vector of sub-properties. */
3859 int i;
3860 for (i = 0; i < ASIZE (prop); ++i)
3861 if (single_display_prop_string_p (AREF (prop, i), string))
3862 return 1;
3863 }
3864 else
3865 return single_display_prop_string_p (prop, string);
3866
3867 return 0;
3868 }
3869
3870
3871 /* Determine from which buffer position in W's buffer STRING comes
3872 from. AROUND_CHARPOS is an approximate position where it could
3873 be from. Value is the buffer position or 0 if it couldn't be
3874 determined.
3875
3876 W's buffer must be current.
3877
3878 This function is necessary because we don't record buffer positions
3879 in glyphs generated from strings (to keep struct glyph small).
3880 This function may only use code that doesn't eval because it is
3881 called asynchronously from note_mouse_highlight. */
3882
3883 int
3884 string_buffer_position (w, string, around_charpos)
3885 struct window *w;
3886 Lisp_Object string;
3887 int around_charpos;
3888 {
3889 Lisp_Object limit, prop, pos;
3890 const int MAX_DISTANCE = 1000;
3891 int found = 0;
3892
3893 pos = make_number (around_charpos);
3894 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3895 while (!found && !EQ (pos, limit))
3896 {
3897 prop = Fget_char_property (pos, Qdisplay, Qnil);
3898 if (!NILP (prop) && display_prop_string_p (prop, string))
3899 found = 1;
3900 else
3901 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3902 }
3903
3904 if (!found)
3905 {
3906 pos = make_number (around_charpos);
3907 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3908 while (!found && !EQ (pos, limit))
3909 {
3910 prop = Fget_char_property (pos, Qdisplay, Qnil);
3911 if (!NILP (prop) && display_prop_string_p (prop, string))
3912 found = 1;
3913 else
3914 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3915 limit);
3916 }
3917 }
3918
3919 return found ? XINT (pos) : 0;
3920 }
3921
3922
3923 \f
3924 /***********************************************************************
3925 `composition' property
3926 ***********************************************************************/
3927
3928 static enum prop_handled
3929 handle_auto_composed_prop (it)
3930 struct it *it;
3931 {
3932 enum prop_handled handled = HANDLED_NORMALLY;
3933
3934 if (FUNCTIONP (Vauto_composition_function))
3935 {
3936 Lisp_Object val;
3937 EMACS_INT pos, this_pos;
3938
3939 if (STRINGP (it->string))
3940 pos = IT_STRING_CHARPOS (*it);
3941 else
3942 pos = IT_CHARPOS (*it);
3943 this_pos = pos;
3944
3945 val =Fget_char_property (make_number (pos), Qauto_composed, it->string);
3946 if (! NILP (val))
3947 {
3948 Lisp_Object limit = Qnil, next;
3949
3950 /* As Fnext_single_char_property_change is very slow, we
3951 limit the search to the current line. */
3952 if (STRINGP (it->string))
3953 limit = make_number (SCHARS (it->string));
3954 else
3955 limit = make_number (find_next_newline_no_quit (pos, 1));
3956
3957 next = (Fnext_single_property_change
3958 (make_number (pos), Qauto_composed, it->string, limit));
3959 if (XINT (next) < XINT (limit))
3960 {
3961 /* The current point is auto-composed, but there exist
3962 characters not yet composed beyond the auto-composed
3963 region. There's a possiblity that the last
3964 characters in the region may be newly composed. */
3965 int charpos = XINT (next) - 1, bytepos, c;
3966
3967 if (STRINGP (it->string))
3968 {
3969 bytepos = string_char_to_byte (it->string, charpos);
3970 c = SDATA (it->string)[bytepos];
3971 }
3972 else
3973 {
3974 bytepos = CHAR_TO_BYTE (charpos);
3975 c = FETCH_BYTE (bytepos);
3976 }
3977 if (c != '\n')
3978 /* If the last character is not newline, it may be
3979 composed with the following characters. */
3980 val = Qnil, pos = charpos + 1;
3981 }
3982 }
3983 if (NILP (val))
3984 {
3985 int count = SPECPDL_INDEX ();
3986 Lisp_Object args[3];
3987
3988 args[0] = Vauto_composition_function;
3989 specbind (Qauto_composition_function, Qnil);
3990 args[1] = make_number (pos);
3991 args[2] = it->string;
3992 safe_call (3, args);
3993 unbind_to (count, Qnil);
3994
3995 if (this_pos == pos)
3996 {
3997 val = Fget_char_property (args[1], Qauto_composed, it->string);
3998 /* Return HANDLED_RECOMPUTE_PROPS only if function composed
3999 something. This avoids an endless loop if they failed to
4000 fontify the text for which reason ever. */
4001 if (! NILP (val))
4002 handled = HANDLED_RECOMPUTE_PROPS;
4003 }
4004 else
4005 handled = HANDLED_RECOMPUTE_PROPS;
4006 }
4007 }
4008
4009 return handled;
4010 }
4011
4012 /* Set up iterator IT from `composition' property at its current
4013 position. Called from handle_stop. */
4014
4015 static enum prop_handled
4016 handle_composition_prop (it)
4017 struct it *it;
4018 {
4019 Lisp_Object prop, string;
4020 EMACS_INT pos, pos_byte, start, end;
4021 enum prop_handled handled = HANDLED_NORMALLY;
4022
4023 if (STRINGP (it->string))
4024 {
4025 pos = IT_STRING_CHARPOS (*it);
4026 pos_byte = IT_STRING_BYTEPOS (*it);
4027 string = it->string;
4028 }
4029 else
4030 {
4031 pos = IT_CHARPOS (*it);
4032 pos_byte = IT_BYTEPOS (*it);
4033 string = Qnil;
4034 }
4035
4036 /* If there's a valid composition and point is not inside of the
4037 composition (in the case that the composition is from the current
4038 buffer), draw a glyph composed from the composition components. */
4039 if (find_composition (pos, -1, &start, &end, &prop, string)
4040 && COMPOSITION_VALID_P (start, end, prop)
4041 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4042 {
4043 int id;
4044
4045 if (start != pos)
4046 {
4047 if (STRINGP (it->string))
4048 pos_byte = string_char_to_byte (it->string, start);
4049 else
4050 pos_byte = CHAR_TO_BYTE (start);
4051 }
4052 id = get_composition_id (start, pos_byte, end - start, prop, string);
4053
4054 if (id >= 0)
4055 {
4056 it->method = next_element_from_composition;
4057 it->cmp_id = id;
4058 it->cmp_len = COMPOSITION_LENGTH (prop);
4059 /* For a terminal, draw only the first character of the
4060 components. */
4061 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4062 it->len = (STRINGP (it->string)
4063 ? string_char_to_byte (it->string, end)
4064 : CHAR_TO_BYTE (end)) - pos_byte;
4065 it->stop_charpos = end;
4066 handled = HANDLED_RETURN;
4067 }
4068 }
4069
4070 return handled;
4071 }
4072
4073
4074 \f
4075 /***********************************************************************
4076 Overlay strings
4077 ***********************************************************************/
4078
4079 /* The following structure is used to record overlay strings for
4080 later sorting in load_overlay_strings. */
4081
4082 struct overlay_entry
4083 {
4084 Lisp_Object overlay;
4085 Lisp_Object string;
4086 int priority;
4087 int after_string_p;
4088 };
4089
4090
4091 /* Set up iterator IT from overlay strings at its current position.
4092 Called from handle_stop. */
4093
4094 static enum prop_handled
4095 handle_overlay_change (it)
4096 struct it *it;
4097 {
4098 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4099 return HANDLED_RECOMPUTE_PROPS;
4100 else
4101 return HANDLED_NORMALLY;
4102 }
4103
4104
4105 /* Set up the next overlay string for delivery by IT, if there is an
4106 overlay string to deliver. Called by set_iterator_to_next when the
4107 end of the current overlay string is reached. If there are more
4108 overlay strings to display, IT->string and
4109 IT->current.overlay_string_index are set appropriately here.
4110 Otherwise IT->string is set to nil. */
4111
4112 static void
4113 next_overlay_string (it)
4114 struct it *it;
4115 {
4116 ++it->current.overlay_string_index;
4117 if (it->current.overlay_string_index == it->n_overlay_strings)
4118 {
4119 /* No more overlay strings. Restore IT's settings to what
4120 they were before overlay strings were processed, and
4121 continue to deliver from current_buffer. */
4122 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4123
4124 pop_it (it);
4125 xassert (it->stop_charpos >= BEGV
4126 && it->stop_charpos <= it->end_charpos);
4127 it->string = Qnil;
4128 it->current.overlay_string_index = -1;
4129 SET_TEXT_POS (it->current.string_pos, -1, -1);
4130 it->n_overlay_strings = 0;
4131 it->method = next_element_from_buffer;
4132
4133 /* If we're at the end of the buffer, record that we have
4134 processed the overlay strings there already, so that
4135 next_element_from_buffer doesn't try it again. */
4136 if (IT_CHARPOS (*it) >= it->end_charpos)
4137 it->overlay_strings_at_end_processed_p = 1;
4138
4139 /* If we have to display `...' for invisible text, set
4140 the iterator up for that. */
4141 if (display_ellipsis_p)
4142 setup_for_ellipsis (it);
4143 }
4144 else
4145 {
4146 /* There are more overlay strings to process. If
4147 IT->current.overlay_string_index has advanced to a position
4148 where we must load IT->overlay_strings with more strings, do
4149 it. */
4150 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4151
4152 if (it->current.overlay_string_index && i == 0)
4153 load_overlay_strings (it, 0);
4154
4155 /* Initialize IT to deliver display elements from the overlay
4156 string. */
4157 it->string = it->overlay_strings[i];
4158 it->multibyte_p = STRING_MULTIBYTE (it->string);
4159 SET_TEXT_POS (it->current.string_pos, 0, 0);
4160 it->method = next_element_from_string;
4161 it->stop_charpos = 0;
4162 }
4163
4164 CHECK_IT (it);
4165 }
4166
4167
4168 /* Compare two overlay_entry structures E1 and E2. Used as a
4169 comparison function for qsort in load_overlay_strings. Overlay
4170 strings for the same position are sorted so that
4171
4172 1. All after-strings come in front of before-strings, except
4173 when they come from the same overlay.
4174
4175 2. Within after-strings, strings are sorted so that overlay strings
4176 from overlays with higher priorities come first.
4177
4178 2. Within before-strings, strings are sorted so that overlay
4179 strings from overlays with higher priorities come last.
4180
4181 Value is analogous to strcmp. */
4182
4183
4184 static int
4185 compare_overlay_entries (e1, e2)
4186 void *e1, *e2;
4187 {
4188 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4189 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4190 int result;
4191
4192 if (entry1->after_string_p != entry2->after_string_p)
4193 {
4194 /* Let after-strings appear in front of before-strings if
4195 they come from different overlays. */
4196 if (EQ (entry1->overlay, entry2->overlay))
4197 result = entry1->after_string_p ? 1 : -1;
4198 else
4199 result = entry1->after_string_p ? -1 : 1;
4200 }
4201 else if (entry1->after_string_p)
4202 /* After-strings sorted in order of decreasing priority. */
4203 result = entry2->priority - entry1->priority;
4204 else
4205 /* Before-strings sorted in order of increasing priority. */
4206 result = entry1->priority - entry2->priority;
4207
4208 return result;
4209 }
4210
4211
4212 /* Load the vector IT->overlay_strings with overlay strings from IT's
4213 current buffer position, or from CHARPOS if that is > 0. Set
4214 IT->n_overlays to the total number of overlay strings found.
4215
4216 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4217 a time. On entry into load_overlay_strings,
4218 IT->current.overlay_string_index gives the number of overlay
4219 strings that have already been loaded by previous calls to this
4220 function.
4221
4222 IT->add_overlay_start contains an additional overlay start
4223 position to consider for taking overlay strings from, if non-zero.
4224 This position comes into play when the overlay has an `invisible'
4225 property, and both before and after-strings. When we've skipped to
4226 the end of the overlay, because of its `invisible' property, we
4227 nevertheless want its before-string to appear.
4228 IT->add_overlay_start will contain the overlay start position
4229 in this case.
4230
4231 Overlay strings are sorted so that after-string strings come in
4232 front of before-string strings. Within before and after-strings,
4233 strings are sorted by overlay priority. See also function
4234 compare_overlay_entries. */
4235
4236 static void
4237 load_overlay_strings (it, charpos)
4238 struct it *it;
4239 int charpos;
4240 {
4241 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4242 Lisp_Object overlay, window, str, invisible;
4243 struct Lisp_Overlay *ov;
4244 int start, end;
4245 int size = 20;
4246 int n = 0, i, j, invis_p;
4247 struct overlay_entry *entries
4248 = (struct overlay_entry *) alloca (size * sizeof *entries);
4249
4250 if (charpos <= 0)
4251 charpos = IT_CHARPOS (*it);
4252
4253 /* Append the overlay string STRING of overlay OVERLAY to vector
4254 `entries' which has size `size' and currently contains `n'
4255 elements. AFTER_P non-zero means STRING is an after-string of
4256 OVERLAY. */
4257 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4258 do \
4259 { \
4260 Lisp_Object priority; \
4261 \
4262 if (n == size) \
4263 { \
4264 int new_size = 2 * size; \
4265 struct overlay_entry *old = entries; \
4266 entries = \
4267 (struct overlay_entry *) alloca (new_size \
4268 * sizeof *entries); \
4269 bcopy (old, entries, size * sizeof *entries); \
4270 size = new_size; \
4271 } \
4272 \
4273 entries[n].string = (STRING); \
4274 entries[n].overlay = (OVERLAY); \
4275 priority = Foverlay_get ((OVERLAY), Qpriority); \
4276 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4277 entries[n].after_string_p = (AFTER_P); \
4278 ++n; \
4279 } \
4280 while (0)
4281
4282 /* Process overlay before the overlay center. */
4283 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4284 {
4285 XSETMISC (overlay, ov);
4286 xassert (OVERLAYP (overlay));
4287 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4288 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4289
4290 if (end < charpos)
4291 break;
4292
4293 /* Skip this overlay if it doesn't start or end at IT's current
4294 position. */
4295 if (end != charpos && start != charpos)
4296 continue;
4297
4298 /* Skip this overlay if it doesn't apply to IT->w. */
4299 window = Foverlay_get (overlay, Qwindow);
4300 if (WINDOWP (window) && XWINDOW (window) != it->w)
4301 continue;
4302
4303 /* If the text ``under'' the overlay is invisible, both before-
4304 and after-strings from this overlay are visible; start and
4305 end position are indistinguishable. */
4306 invisible = Foverlay_get (overlay, Qinvisible);
4307 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4308
4309 /* If overlay has a non-empty before-string, record it. */
4310 if ((start == charpos || (end == charpos && invis_p))
4311 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4312 && SCHARS (str))
4313 RECORD_OVERLAY_STRING (overlay, str, 0);
4314
4315 /* If overlay has a non-empty after-string, record it. */
4316 if ((end == charpos || (start == charpos && invis_p))
4317 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4318 && SCHARS (str))
4319 RECORD_OVERLAY_STRING (overlay, str, 1);
4320 }
4321
4322 /* Process overlays after the overlay center. */
4323 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4324 {
4325 XSETMISC (overlay, ov);
4326 xassert (OVERLAYP (overlay));
4327 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4328 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4329
4330 if (start > charpos)
4331 break;
4332
4333 /* Skip this overlay if it doesn't start or end at IT's current
4334 position. */
4335 if (end != charpos && start != charpos)
4336 continue;
4337
4338 /* Skip this overlay if it doesn't apply to IT->w. */
4339 window = Foverlay_get (overlay, Qwindow);
4340 if (WINDOWP (window) && XWINDOW (window) != it->w)
4341 continue;
4342
4343 /* If the text ``under'' the overlay is invisible, it has a zero
4344 dimension, and both before- and after-strings apply. */
4345 invisible = Foverlay_get (overlay, Qinvisible);
4346 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4347
4348 /* If overlay has a non-empty before-string, record it. */
4349 if ((start == charpos || (end == charpos && invis_p))
4350 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4351 && SCHARS (str))
4352 RECORD_OVERLAY_STRING (overlay, str, 0);
4353
4354 /* If overlay has a non-empty after-string, record it. */
4355 if ((end == charpos || (start == charpos && invis_p))
4356 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4357 && SCHARS (str))
4358 RECORD_OVERLAY_STRING (overlay, str, 1);
4359 }
4360
4361 #undef RECORD_OVERLAY_STRING
4362
4363 /* Sort entries. */
4364 if (n > 1)
4365 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4366
4367 /* Record the total number of strings to process. */
4368 it->n_overlay_strings = n;
4369
4370 /* IT->current.overlay_string_index is the number of overlay strings
4371 that have already been consumed by IT. Copy some of the
4372 remaining overlay strings to IT->overlay_strings. */
4373 i = 0;
4374 j = it->current.overlay_string_index;
4375 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4376 it->overlay_strings[i++] = entries[j++].string;
4377
4378 CHECK_IT (it);
4379 }
4380
4381
4382 /* Get the first chunk of overlay strings at IT's current buffer
4383 position, or at CHARPOS if that is > 0. Value is non-zero if at
4384 least one overlay string was found. */
4385
4386 static int
4387 get_overlay_strings (it, charpos)
4388 struct it *it;
4389 int charpos;
4390 {
4391 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4392 process. This fills IT->overlay_strings with strings, and sets
4393 IT->n_overlay_strings to the total number of strings to process.
4394 IT->pos.overlay_string_index has to be set temporarily to zero
4395 because load_overlay_strings needs this; it must be set to -1
4396 when no overlay strings are found because a zero value would
4397 indicate a position in the first overlay string. */
4398 it->current.overlay_string_index = 0;
4399 load_overlay_strings (it, charpos);
4400
4401 /* If we found overlay strings, set up IT to deliver display
4402 elements from the first one. Otherwise set up IT to deliver
4403 from current_buffer. */
4404 if (it->n_overlay_strings)
4405 {
4406 /* Make sure we know settings in current_buffer, so that we can
4407 restore meaningful values when we're done with the overlay
4408 strings. */
4409 compute_stop_pos (it);
4410 xassert (it->face_id >= 0);
4411
4412 /* Save IT's settings. They are restored after all overlay
4413 strings have been processed. */
4414 xassert (it->sp == 0);
4415 push_it (it);
4416
4417 /* Set up IT to deliver display elements from the first overlay
4418 string. */
4419 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4420 it->string = it->overlay_strings[0];
4421 it->stop_charpos = 0;
4422 xassert (STRINGP (it->string));
4423 it->end_charpos = SCHARS (it->string);
4424 it->multibyte_p = STRING_MULTIBYTE (it->string);
4425 it->method = next_element_from_string;
4426 }
4427 else
4428 {
4429 it->string = Qnil;
4430 it->current.overlay_string_index = -1;
4431 it->method = next_element_from_buffer;
4432 }
4433
4434 CHECK_IT (it);
4435
4436 /* Value is non-zero if we found at least one overlay string. */
4437 return STRINGP (it->string);
4438 }
4439
4440
4441 \f
4442 /***********************************************************************
4443 Saving and restoring state
4444 ***********************************************************************/
4445
4446 /* Save current settings of IT on IT->stack. Called, for example,
4447 before setting up IT for an overlay string, to be able to restore
4448 IT's settings to what they were after the overlay string has been
4449 processed. */
4450
4451 static void
4452 push_it (it)
4453 struct it *it;
4454 {
4455 struct iterator_stack_entry *p;
4456
4457 xassert (it->sp < 2);
4458 p = it->stack + it->sp;
4459
4460 p->stop_charpos = it->stop_charpos;
4461 xassert (it->face_id >= 0);
4462 p->face_id = it->face_id;
4463 p->string = it->string;
4464 p->pos = it->current;
4465 p->end_charpos = it->end_charpos;
4466 p->string_nchars = it->string_nchars;
4467 p->area = it->area;
4468 p->multibyte_p = it->multibyte_p;
4469 p->slice = it->slice;
4470 p->space_width = it->space_width;
4471 p->font_height = it->font_height;
4472 p->voffset = it->voffset;
4473 p->string_from_display_prop_p = it->string_from_display_prop_p;
4474 p->display_ellipsis_p = 0;
4475 ++it->sp;
4476 }
4477
4478
4479 /* Restore IT's settings from IT->stack. Called, for example, when no
4480 more overlay strings must be processed, and we return to delivering
4481 display elements from a buffer, or when the end of a string from a
4482 `display' property is reached and we return to delivering display
4483 elements from an overlay string, or from a buffer. */
4484
4485 static void
4486 pop_it (it)
4487 struct it *it;
4488 {
4489 struct iterator_stack_entry *p;
4490
4491 xassert (it->sp > 0);
4492 --it->sp;
4493 p = it->stack + it->sp;
4494 it->stop_charpos = p->stop_charpos;
4495 it->face_id = p->face_id;
4496 it->string = p->string;
4497 it->current = p->pos;
4498 it->end_charpos = p->end_charpos;
4499 it->string_nchars = p->string_nchars;
4500 it->area = p->area;
4501 it->multibyte_p = p->multibyte_p;
4502 it->slice = p->slice;
4503 it->space_width = p->space_width;
4504 it->font_height = p->font_height;
4505 it->voffset = p->voffset;
4506 it->string_from_display_prop_p = p->string_from_display_prop_p;
4507 }
4508
4509
4510 \f
4511 /***********************************************************************
4512 Moving over lines
4513 ***********************************************************************/
4514
4515 /* Set IT's current position to the previous line start. */
4516
4517 static void
4518 back_to_previous_line_start (it)
4519 struct it *it;
4520 {
4521 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4522 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4523 }
4524
4525
4526 /* Move IT to the next line start.
4527
4528 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4529 we skipped over part of the text (as opposed to moving the iterator
4530 continuously over the text). Otherwise, don't change the value
4531 of *SKIPPED_P.
4532
4533 Newlines may come from buffer text, overlay strings, or strings
4534 displayed via the `display' property. That's the reason we can't
4535 simply use find_next_newline_no_quit.
4536
4537 Note that this function may not skip over invisible text that is so
4538 because of text properties and immediately follows a newline. If
4539 it would, function reseat_at_next_visible_line_start, when called
4540 from set_iterator_to_next, would effectively make invisible
4541 characters following a newline part of the wrong glyph row, which
4542 leads to wrong cursor motion. */
4543
4544 static int
4545 forward_to_next_line_start (it, skipped_p)
4546 struct it *it;
4547 int *skipped_p;
4548 {
4549 int old_selective, newline_found_p, n;
4550 const int MAX_NEWLINE_DISTANCE = 500;
4551
4552 /* If already on a newline, just consume it to avoid unintended
4553 skipping over invisible text below. */
4554 if (it->what == IT_CHARACTER
4555 && it->c == '\n'
4556 && CHARPOS (it->position) == IT_CHARPOS (*it))
4557 {
4558 set_iterator_to_next (it, 0);
4559 it->c = 0;
4560 return 1;
4561 }
4562
4563 /* Don't handle selective display in the following. It's (a)
4564 unnecessary because it's done by the caller, and (b) leads to an
4565 infinite recursion because next_element_from_ellipsis indirectly
4566 calls this function. */
4567 old_selective = it->selective;
4568 it->selective = 0;
4569
4570 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4571 from buffer text. */
4572 for (n = newline_found_p = 0;
4573 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4574 n += STRINGP (it->string) ? 0 : 1)
4575 {
4576 if (!get_next_display_element (it))
4577 return 0;
4578 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4579 set_iterator_to_next (it, 0);
4580 }
4581
4582 /* If we didn't find a newline near enough, see if we can use a
4583 short-cut. */
4584 if (!newline_found_p)
4585 {
4586 int start = IT_CHARPOS (*it);
4587 int limit = find_next_newline_no_quit (start, 1);
4588 Lisp_Object pos;
4589
4590 xassert (!STRINGP (it->string));
4591
4592 /* If there isn't any `display' property in sight, and no
4593 overlays, we can just use the position of the newline in
4594 buffer text. */
4595 if (it->stop_charpos >= limit
4596 || ((pos = Fnext_single_property_change (make_number (start),
4597 Qdisplay,
4598 Qnil, make_number (limit)),
4599 NILP (pos))
4600 && next_overlay_change (start) == ZV))
4601 {
4602 IT_CHARPOS (*it) = limit;
4603 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4604 *skipped_p = newline_found_p = 1;
4605 }
4606 else
4607 {
4608 while (get_next_display_element (it)
4609 && !newline_found_p)
4610 {
4611 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4612 set_iterator_to_next (it, 0);
4613 }
4614 }
4615 }
4616
4617 it->selective = old_selective;
4618 return newline_found_p;
4619 }
4620
4621
4622 /* Set IT's current position to the previous visible line start. Skip
4623 invisible text that is so either due to text properties or due to
4624 selective display. Caution: this does not change IT->current_x and
4625 IT->hpos. */
4626
4627 static void
4628 back_to_previous_visible_line_start (it)
4629 struct it *it;
4630 {
4631 int visible_p = 0;
4632
4633 /* Go back one newline if not on BEGV already. */
4634 if (IT_CHARPOS (*it) > BEGV)
4635 back_to_previous_line_start (it);
4636
4637 /* Move over lines that are invisible because of selective display
4638 or text properties. */
4639 while (IT_CHARPOS (*it) > BEGV
4640 && !visible_p)
4641 {
4642 visible_p = 1;
4643
4644 /* If selective > 0, then lines indented more than that values
4645 are invisible. */
4646 if (it->selective > 0
4647 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4648 (double) it->selective)) /* iftc */
4649 visible_p = 0;
4650 else
4651 {
4652 Lisp_Object prop;
4653
4654 /* Check the newline before point for invisibility. */
4655 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4656 Qinvisible, it->window);
4657 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4658 visible_p = 0;
4659 }
4660
4661 if (visible_p)
4662 {
4663 struct it it2 = *it;
4664
4665 if (handle_display_prop (&it2) == HANDLED_RETURN)
4666 visible_p = 0;
4667 }
4668
4669 /* Back one more newline if the current one is invisible. */
4670 if (!visible_p)
4671 back_to_previous_line_start (it);
4672 }
4673
4674 xassert (IT_CHARPOS (*it) >= BEGV);
4675 xassert (IT_CHARPOS (*it) == BEGV
4676 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4677 CHECK_IT (it);
4678 }
4679
4680
4681 /* Reseat iterator IT at the previous visible line start. Skip
4682 invisible text that is so either due to text properties or due to
4683 selective display. At the end, update IT's overlay information,
4684 face information etc. */
4685
4686 static void
4687 reseat_at_previous_visible_line_start (it)
4688 struct it *it;
4689 {
4690 back_to_previous_visible_line_start (it);
4691 reseat (it, it->current.pos, 1);
4692 CHECK_IT (it);
4693 }
4694
4695
4696 /* Reseat iterator IT on the next visible line start in the current
4697 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4698 preceding the line start. Skip over invisible text that is so
4699 because of selective display. Compute faces, overlays etc at the
4700 new position. Note that this function does not skip over text that
4701 is invisible because of text properties. */
4702
4703 static void
4704 reseat_at_next_visible_line_start (it, on_newline_p)
4705 struct it *it;
4706 int on_newline_p;
4707 {
4708 int newline_found_p, skipped_p = 0;
4709
4710 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4711
4712 /* Skip over lines that are invisible because they are indented
4713 more than the value of IT->selective. */
4714 if (it->selective > 0)
4715 while (IT_CHARPOS (*it) < ZV
4716 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4717 (double) it->selective)) /* iftc */
4718 {
4719 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4720 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4721 }
4722
4723 /* Position on the newline if that's what's requested. */
4724 if (on_newline_p && newline_found_p)
4725 {
4726 if (STRINGP (it->string))
4727 {
4728 if (IT_STRING_CHARPOS (*it) > 0)
4729 {
4730 --IT_STRING_CHARPOS (*it);
4731 --IT_STRING_BYTEPOS (*it);
4732 }
4733 }
4734 else if (IT_CHARPOS (*it) > BEGV)
4735 {
4736 --IT_CHARPOS (*it);
4737 --IT_BYTEPOS (*it);
4738 reseat (it, it->current.pos, 0);
4739 }
4740 }
4741 else if (skipped_p)
4742 reseat (it, it->current.pos, 0);
4743
4744 CHECK_IT (it);
4745 }
4746
4747
4748 \f
4749 /***********************************************************************
4750 Changing an iterator's position
4751 ***********************************************************************/
4752
4753 /* Change IT's current position to POS in current_buffer. If FORCE_P
4754 is non-zero, always check for text properties at the new position.
4755 Otherwise, text properties are only looked up if POS >=
4756 IT->check_charpos of a property. */
4757
4758 static void
4759 reseat (it, pos, force_p)
4760 struct it *it;
4761 struct text_pos pos;
4762 int force_p;
4763 {
4764 int original_pos = IT_CHARPOS (*it);
4765
4766 reseat_1 (it, pos, 0);
4767
4768 /* Determine where to check text properties. Avoid doing it
4769 where possible because text property lookup is very expensive. */
4770 if (force_p
4771 || CHARPOS (pos) > it->stop_charpos
4772 || CHARPOS (pos) < original_pos)
4773 handle_stop (it);
4774
4775 CHECK_IT (it);
4776 }
4777
4778
4779 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4780 IT->stop_pos to POS, also. */
4781
4782 static void
4783 reseat_1 (it, pos, set_stop_p)
4784 struct it *it;
4785 struct text_pos pos;
4786 int set_stop_p;
4787 {
4788 /* Don't call this function when scanning a C string. */
4789 xassert (it->s == NULL);
4790
4791 /* POS must be a reasonable value. */
4792 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4793
4794 it->current.pos = it->position = pos;
4795 XSETBUFFER (it->object, current_buffer);
4796 it->end_charpos = ZV;
4797 it->dpvec = NULL;
4798 it->current.dpvec_index = -1;
4799 it->current.overlay_string_index = -1;
4800 IT_STRING_CHARPOS (*it) = -1;
4801 IT_STRING_BYTEPOS (*it) = -1;
4802 it->string = Qnil;
4803 it->method = next_element_from_buffer;
4804 /* RMS: I added this to fix a bug in move_it_vertically_backward
4805 where it->area continued to relate to the starting point
4806 for the backward motion. Bug report from
4807 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4808 However, I am not sure whether reseat still does the right thing
4809 in general after this change. */
4810 it->area = TEXT_AREA;
4811 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4812 it->sp = 0;
4813 it->face_before_selective_p = 0;
4814
4815 if (set_stop_p)
4816 it->stop_charpos = CHARPOS (pos);
4817 }
4818
4819
4820 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4821 If S is non-null, it is a C string to iterate over. Otherwise,
4822 STRING gives a Lisp string to iterate over.
4823
4824 If PRECISION > 0, don't return more then PRECISION number of
4825 characters from the string.
4826
4827 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4828 characters have been returned. FIELD_WIDTH < 0 means an infinite
4829 field width.
4830
4831 MULTIBYTE = 0 means disable processing of multibyte characters,
4832 MULTIBYTE > 0 means enable it,
4833 MULTIBYTE < 0 means use IT->multibyte_p.
4834
4835 IT must be initialized via a prior call to init_iterator before
4836 calling this function. */
4837
4838 static void
4839 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4840 struct it *it;
4841 unsigned char *s;
4842 Lisp_Object string;
4843 int charpos;
4844 int precision, field_width, multibyte;
4845 {
4846 /* No region in strings. */
4847 it->region_beg_charpos = it->region_end_charpos = -1;
4848
4849 /* No text property checks performed by default, but see below. */
4850 it->stop_charpos = -1;
4851
4852 /* Set iterator position and end position. */
4853 bzero (&it->current, sizeof it->current);
4854 it->current.overlay_string_index = -1;
4855 it->current.dpvec_index = -1;
4856 xassert (charpos >= 0);
4857
4858 /* If STRING is specified, use its multibyteness, otherwise use the
4859 setting of MULTIBYTE, if specified. */
4860 if (multibyte >= 0)
4861 it->multibyte_p = multibyte > 0;
4862
4863 if (s == NULL)
4864 {
4865 xassert (STRINGP (string));
4866 it->string = string;
4867 it->s = NULL;
4868 it->end_charpos = it->string_nchars = SCHARS (string);
4869 it->method = next_element_from_string;
4870 it->current.string_pos = string_pos (charpos, string);
4871 }
4872 else
4873 {
4874 it->s = s;
4875 it->string = Qnil;
4876
4877 /* Note that we use IT->current.pos, not it->current.string_pos,
4878 for displaying C strings. */
4879 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4880 if (it->multibyte_p)
4881 {
4882 it->current.pos = c_string_pos (charpos, s, 1);
4883 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4884 }
4885 else
4886 {
4887 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4888 it->end_charpos = it->string_nchars = strlen (s);
4889 }
4890
4891 it->method = next_element_from_c_string;
4892 }
4893
4894 /* PRECISION > 0 means don't return more than PRECISION characters
4895 from the string. */
4896 if (precision > 0 && it->end_charpos - charpos > precision)
4897 it->end_charpos = it->string_nchars = charpos + precision;
4898
4899 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4900 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4901 FIELD_WIDTH < 0 means infinite field width. This is useful for
4902 padding with `-' at the end of a mode line. */
4903 if (field_width < 0)
4904 field_width = INFINITY;
4905 if (field_width > it->end_charpos - charpos)
4906 it->end_charpos = charpos + field_width;
4907
4908 /* Use the standard display table for displaying strings. */
4909 if (DISP_TABLE_P (Vstandard_display_table))
4910 it->dp = XCHAR_TABLE (Vstandard_display_table);
4911
4912 it->stop_charpos = charpos;
4913 CHECK_IT (it);
4914 }
4915
4916
4917 \f
4918 /***********************************************************************
4919 Iteration
4920 ***********************************************************************/
4921
4922 /* Load IT's display element fields with information about the next
4923 display element from the current position of IT. Value is zero if
4924 end of buffer (or C string) is reached. */
4925
4926 int
4927 get_next_display_element (it)
4928 struct it *it;
4929 {
4930 /* Non-zero means that we found a display element. Zero means that
4931 we hit the end of what we iterate over. Performance note: the
4932 function pointer `method' used here turns out to be faster than
4933 using a sequence of if-statements. */
4934 int success_p = (*it->method) (it);
4935
4936 if (it->what == IT_CHARACTER)
4937 {
4938 /* Map via display table or translate control characters.
4939 IT->c, IT->len etc. have been set to the next character by
4940 the function call above. If we have a display table, and it
4941 contains an entry for IT->c, translate it. Don't do this if
4942 IT->c itself comes from a display table, otherwise we could
4943 end up in an infinite recursion. (An alternative could be to
4944 count the recursion depth of this function and signal an
4945 error when a certain maximum depth is reached.) Is it worth
4946 it? */
4947 if (success_p && it->dpvec == NULL)
4948 {
4949 Lisp_Object dv;
4950
4951 if (it->dp
4952 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4953 VECTORP (dv)))
4954 {
4955 struct Lisp_Vector *v = XVECTOR (dv);
4956
4957 /* Return the first character from the display table
4958 entry, if not empty. If empty, don't display the
4959 current character. */
4960 if (v->size)
4961 {
4962 it->dpvec_char_len = it->len;
4963 it->dpvec = v->contents;
4964 it->dpend = v->contents + v->size;
4965 it->current.dpvec_index = 0;
4966 it->method = next_element_from_display_vector;
4967 success_p = get_next_display_element (it);
4968 }
4969 else
4970 {
4971 set_iterator_to_next (it, 0);
4972 success_p = get_next_display_element (it);
4973 }
4974 }
4975
4976 /* Translate control characters into `\003' or `^C' form.
4977 Control characters coming from a display table entry are
4978 currently not translated because we use IT->dpvec to hold
4979 the translation. This could easily be changed but I
4980 don't believe that it is worth doing.
4981
4982 If it->multibyte_p is nonzero, non-printable non-ASCII
4983 characters are also translated to octal form.
4984
4985 If it->multibyte_p is zero, eight-bit characters that
4986 don't have corresponding multibyte char code are also
4987 translated to octal form. */
4988 else if ((it->c < ' '
4989 ? (it->area != TEXT_AREA
4990 /* In mode line, treat \n, \t like other crl chars. */
4991 || (it->glyph_row && it->glyph_row->mode_line_p)
4992 || (it->c != '\n' && it->c != '\t'))
4993 : it->multibyte_p ? !CHAR_PRINTABLE_P (it->c)
4994 : (it->c >= 127
4995 && (! unibyte_display_via_language_environment
4996 || (UNIBYTE_CHAR_HAS_MULTIBYTE_P (it->c))))))
4997 {
4998 /* IT->c is a control character which must be displayed
4999 either as '\003' or as `^C' where the '\\' and '^'
5000 can be defined in the display table. Fill
5001 IT->ctl_chars with glyphs for what we have to
5002 display. Then, set IT->dpvec to these glyphs. */
5003 GLYPH g;
5004
5005 if (it->c < 128 && it->ctl_arrow_p)
5006 {
5007 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5008 if (it->dp
5009 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5010 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5011 g = XINT (DISP_CTRL_GLYPH (it->dp));
5012 else
5013 g = FAST_MAKE_GLYPH ('^', 0);
5014 XSETINT (it->ctl_chars[0], g);
5015
5016 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
5017 XSETINT (it->ctl_chars[1], g);
5018
5019 /* Set up IT->dpvec and return first character from it. */
5020 it->dpvec_char_len = it->len;
5021 it->dpvec = it->ctl_chars;
5022 it->dpend = it->dpvec + 2;
5023 it->current.dpvec_index = 0;
5024 it->method = next_element_from_display_vector;
5025 get_next_display_element (it);
5026 }
5027 else
5028 {
5029 unsigned char str[MAX_MULTIBYTE_LENGTH];
5030 int len;
5031 int i;
5032 GLYPH escape_glyph;
5033
5034 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5035 if (it->dp
5036 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5037 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5038 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5039 else
5040 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
5041
5042 if (CHAR_BYTE8_P (it->c))
5043 {
5044 str[0] = CHAR_TO_BYTE8 (it->c);
5045 len = 1;
5046 }
5047 else if (it->c < 256)
5048 {
5049 str[0] = it->c;
5050 len = 1;
5051 }
5052 else
5053 {
5054 /* It's an invalid character, which
5055 shouldn't happen actually, but due to
5056 bugs it may happen. Let's print the char
5057 as is, there's not much meaningful we can
5058 do with it. */
5059 str[0] = it->c;
5060 str[1] = it->c >> 8;
5061 str[2] = it->c >> 16;
5062 str[3] = it->c >> 24;
5063 len = 4;
5064 }
5065
5066 for (i = 0; i < len; i++)
5067 {
5068 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5069 /* Insert three more glyphs into IT->ctl_chars for
5070 the octal display of the character. */
5071 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
5072 XSETINT (it->ctl_chars[i * 4 + 1], g);
5073 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
5074 XSETINT (it->ctl_chars[i * 4 + 2], g);
5075 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
5076 XSETINT (it->ctl_chars[i * 4 + 3], g);
5077 }
5078
5079 /* Set up IT->dpvec and return the first character
5080 from it. */
5081 it->dpvec_char_len = it->len;
5082 it->dpvec = it->ctl_chars;
5083 it->dpend = it->dpvec + len * 4;
5084 it->current.dpvec_index = 0;
5085 it->method = next_element_from_display_vector;
5086 get_next_display_element (it);
5087 }
5088 }
5089 }
5090
5091 /* Adjust face id for a multibyte character. There are no
5092 multibyte character in unibyte text. */
5093 if (it->multibyte_p
5094 && success_p
5095 && FRAME_WINDOW_P (it->f))
5096 {
5097 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5098 int pos = (it->s ? -1
5099 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5100 : IT_CHARPOS (*it));
5101
5102 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
5103 }
5104 }
5105
5106 /* Is this character the last one of a run of characters with
5107 box? If yes, set IT->end_of_box_run_p to 1. */
5108 if (it->face_box_p
5109 && it->s == NULL)
5110 {
5111 int face_id;
5112 struct face *face;
5113
5114 it->end_of_box_run_p
5115 = ((face_id = face_after_it_pos (it),
5116 face_id != it->face_id)
5117 && (face = FACE_FROM_ID (it->f, face_id),
5118 face->box == FACE_NO_BOX));
5119 }
5120
5121 /* Value is 0 if end of buffer or string reached. */
5122 return success_p;
5123 }
5124
5125
5126 /* Move IT to the next display element.
5127
5128 RESEAT_P non-zero means if called on a newline in buffer text,
5129 skip to the next visible line start.
5130
5131 Functions get_next_display_element and set_iterator_to_next are
5132 separate because I find this arrangement easier to handle than a
5133 get_next_display_element function that also increments IT's
5134 position. The way it is we can first look at an iterator's current
5135 display element, decide whether it fits on a line, and if it does,
5136 increment the iterator position. The other way around we probably
5137 would either need a flag indicating whether the iterator has to be
5138 incremented the next time, or we would have to implement a
5139 decrement position function which would not be easy to write. */
5140
5141 void
5142 set_iterator_to_next (it, reseat_p)
5143 struct it *it;
5144 int reseat_p;
5145 {
5146 /* Reset flags indicating start and end of a sequence of characters
5147 with box. Reset them at the start of this function because
5148 moving the iterator to a new position might set them. */
5149 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5150
5151 if (it->method == next_element_from_buffer)
5152 {
5153 /* The current display element of IT is a character from
5154 current_buffer. Advance in the buffer, and maybe skip over
5155 invisible lines that are so because of selective display. */
5156 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5157 reseat_at_next_visible_line_start (it, 0);
5158 else
5159 {
5160 xassert (it->len != 0);
5161 IT_BYTEPOS (*it) += it->len;
5162 IT_CHARPOS (*it) += 1;
5163 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5164 }
5165 }
5166 else if (it->method == next_element_from_composition)
5167 {
5168 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5169 if (STRINGP (it->string))
5170 {
5171 IT_STRING_BYTEPOS (*it) += it->len;
5172 IT_STRING_CHARPOS (*it) += it->cmp_len;
5173 it->method = next_element_from_string;
5174 goto consider_string_end;
5175 }
5176 else
5177 {
5178 IT_BYTEPOS (*it) += it->len;
5179 IT_CHARPOS (*it) += it->cmp_len;
5180 it->method = next_element_from_buffer;
5181 }
5182 }
5183 else if (it->method == next_element_from_c_string)
5184 {
5185 /* Current display element of IT is from a C string. */
5186 IT_BYTEPOS (*it) += it->len;
5187 IT_CHARPOS (*it) += 1;
5188 }
5189 else if (it->method == next_element_from_display_vector)
5190 {
5191 /* Current display element of IT is from a display table entry.
5192 Advance in the display table definition. Reset it to null if
5193 end reached, and continue with characters from buffers/
5194 strings. */
5195 ++it->current.dpvec_index;
5196
5197 /* Restore face of the iterator to what they were before the
5198 display vector entry (these entries may contain faces). */
5199 it->face_id = it->saved_face_id;
5200
5201 if (it->dpvec + it->current.dpvec_index == it->dpend)
5202 {
5203 if (it->s)
5204 it->method = next_element_from_c_string;
5205 else if (STRINGP (it->string))
5206 it->method = next_element_from_string;
5207 else
5208 it->method = next_element_from_buffer;
5209
5210 it->dpvec = NULL;
5211 it->current.dpvec_index = -1;
5212
5213 /* Skip over characters which were displayed via IT->dpvec. */
5214 if (it->dpvec_char_len < 0)
5215 reseat_at_next_visible_line_start (it, 1);
5216 else if (it->dpvec_char_len > 0)
5217 {
5218 it->len = it->dpvec_char_len;
5219 set_iterator_to_next (it, reseat_p);
5220 }
5221 }
5222 }
5223 else if (it->method == next_element_from_string)
5224 {
5225 /* Current display element is a character from a Lisp string. */
5226 xassert (it->s == NULL && STRINGP (it->string));
5227 IT_STRING_BYTEPOS (*it) += it->len;
5228 IT_STRING_CHARPOS (*it) += 1;
5229
5230 consider_string_end:
5231
5232 if (it->current.overlay_string_index >= 0)
5233 {
5234 /* IT->string is an overlay string. Advance to the
5235 next, if there is one. */
5236 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5237 next_overlay_string (it);
5238 }
5239 else
5240 {
5241 /* IT->string is not an overlay string. If we reached
5242 its end, and there is something on IT->stack, proceed
5243 with what is on the stack. This can be either another
5244 string, this time an overlay string, or a buffer. */
5245 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5246 && it->sp > 0)
5247 {
5248 pop_it (it);
5249 if (!STRINGP (it->string))
5250 it->method = next_element_from_buffer;
5251 else
5252 goto consider_string_end;
5253 }
5254 }
5255 }
5256 else if (it->method == next_element_from_image
5257 || it->method == next_element_from_stretch)
5258 {
5259 /* The position etc with which we have to proceed are on
5260 the stack. The position may be at the end of a string,
5261 if the `display' property takes up the whole string. */
5262 pop_it (it);
5263 it->image_id = 0;
5264 if (STRINGP (it->string))
5265 {
5266 it->method = next_element_from_string;
5267 goto consider_string_end;
5268 }
5269 else
5270 it->method = next_element_from_buffer;
5271 }
5272 else
5273 /* There are no other methods defined, so this should be a bug. */
5274 abort ();
5275
5276 xassert (it->method != next_element_from_string
5277 || (STRINGP (it->string)
5278 && IT_STRING_CHARPOS (*it) >= 0));
5279 }
5280
5281
5282 /* Load IT's display element fields with information about the next
5283 display element which comes from a display table entry or from the
5284 result of translating a control character to one of the forms `^C'
5285 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5286
5287 static int
5288 next_element_from_display_vector (it)
5289 struct it *it;
5290 {
5291 /* Precondition. */
5292 xassert (it->dpvec && it->current.dpvec_index >= 0);
5293
5294 /* Remember the current face id in case glyphs specify faces.
5295 IT's face is restored in set_iterator_to_next. */
5296 it->saved_face_id = it->face_id;
5297
5298 if (INTEGERP (*it->dpvec)
5299 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5300 {
5301 int lface_id;
5302 GLYPH g;
5303
5304 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5305 it->c = FAST_GLYPH_CHAR (g);
5306 it->len = CHAR_BYTES (it->c);
5307
5308 /* The entry may contain a face id to use. Such a face id is
5309 the id of a Lisp face, not a realized face. A face id of
5310 zero means no face is specified. */
5311 lface_id = FAST_GLYPH_FACE (g);
5312 if (lface_id)
5313 {
5314 /* The function returns -1 if lface_id is invalid. */
5315 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5316 if (face_id >= 0)
5317 it->face_id = face_id;
5318 }
5319 }
5320 else
5321 /* Display table entry is invalid. Return a space. */
5322 it->c = ' ', it->len = 1;
5323
5324 /* Don't change position and object of the iterator here. They are
5325 still the values of the character that had this display table
5326 entry or was translated, and that's what we want. */
5327 it->what = IT_CHARACTER;
5328 return 1;
5329 }
5330
5331
5332 /* Load IT with the next display element from Lisp string IT->string.
5333 IT->current.string_pos is the current position within the string.
5334 If IT->current.overlay_string_index >= 0, the Lisp string is an
5335 overlay string. */
5336
5337 static int
5338 next_element_from_string (it)
5339 struct it *it;
5340 {
5341 struct text_pos position;
5342
5343 xassert (STRINGP (it->string));
5344 xassert (IT_STRING_CHARPOS (*it) >= 0);
5345 position = it->current.string_pos;
5346
5347 /* Time to check for invisible text? */
5348 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5349 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5350 {
5351 handle_stop (it);
5352
5353 /* Since a handler may have changed IT->method, we must
5354 recurse here. */
5355 return get_next_display_element (it);
5356 }
5357
5358 if (it->current.overlay_string_index >= 0)
5359 {
5360 /* Get the next character from an overlay string. In overlay
5361 strings, There is no field width or padding with spaces to
5362 do. */
5363 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5364 {
5365 it->what = IT_EOB;
5366 return 0;
5367 }
5368 else if (STRING_MULTIBYTE (it->string))
5369 {
5370 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5371 const unsigned char *s = (SDATA (it->string)
5372 + IT_STRING_BYTEPOS (*it));
5373 it->c = string_char_and_length (s, remaining, &it->len);
5374 }
5375 else
5376 {
5377 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5378 it->len = 1;
5379 }
5380 }
5381 else
5382 {
5383 /* Get the next character from a Lisp string that is not an
5384 overlay string. Such strings come from the mode line, for
5385 example. We may have to pad with spaces, or truncate the
5386 string. See also next_element_from_c_string. */
5387 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5388 {
5389 it->what = IT_EOB;
5390 return 0;
5391 }
5392 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5393 {
5394 /* Pad with spaces. */
5395 it->c = ' ', it->len = 1;
5396 CHARPOS (position) = BYTEPOS (position) = -1;
5397 }
5398 else if (STRING_MULTIBYTE (it->string))
5399 {
5400 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5401 const unsigned char *s = (SDATA (it->string)
5402 + IT_STRING_BYTEPOS (*it));
5403 it->c = string_char_and_length (s, maxlen, &it->len);
5404 }
5405 else
5406 {
5407 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5408 it->len = 1;
5409 }
5410 }
5411
5412 /* Record what we have and where it came from. Note that we store a
5413 buffer position in IT->position although it could arguably be a
5414 string position. */
5415 it->what = IT_CHARACTER;
5416 it->object = it->string;
5417 it->position = position;
5418 return 1;
5419 }
5420
5421
5422 /* Load IT with next display element from C string IT->s.
5423 IT->string_nchars is the maximum number of characters to return
5424 from the string. IT->end_charpos may be greater than
5425 IT->string_nchars when this function is called, in which case we
5426 may have to return padding spaces. Value is zero if end of string
5427 reached, including padding spaces. */
5428
5429 static int
5430 next_element_from_c_string (it)
5431 struct it *it;
5432 {
5433 int success_p = 1;
5434
5435 xassert (it->s);
5436 it->what = IT_CHARACTER;
5437 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5438 it->object = Qnil;
5439
5440 /* IT's position can be greater IT->string_nchars in case a field
5441 width or precision has been specified when the iterator was
5442 initialized. */
5443 if (IT_CHARPOS (*it) >= it->end_charpos)
5444 {
5445 /* End of the game. */
5446 it->what = IT_EOB;
5447 success_p = 0;
5448 }
5449 else if (IT_CHARPOS (*it) >= it->string_nchars)
5450 {
5451 /* Pad with spaces. */
5452 it->c = ' ', it->len = 1;
5453 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5454 }
5455 else if (it->multibyte_p)
5456 {
5457 /* Implementation note: The calls to strlen apparently aren't a
5458 performance problem because there is no noticeable performance
5459 difference between Emacs running in unibyte or multibyte mode. */
5460 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5461 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5462 maxlen, &it->len);
5463 }
5464 else
5465 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5466
5467 return success_p;
5468 }
5469
5470
5471 /* Set up IT to return characters from an ellipsis, if appropriate.
5472 The definition of the ellipsis glyphs may come from a display table
5473 entry. This function Fills IT with the first glyph from the
5474 ellipsis if an ellipsis is to be displayed. */
5475
5476 static int
5477 next_element_from_ellipsis (it)
5478 struct it *it;
5479 {
5480 if (it->selective_display_ellipsis_p)
5481 {
5482 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5483 {
5484 /* Use the display table definition for `...'. Invalid glyphs
5485 will be handled by the method returning elements from dpvec. */
5486 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5487 it->dpvec_char_len = it->len;
5488 it->dpvec = v->contents;
5489 it->dpend = v->contents + v->size;
5490 it->current.dpvec_index = 0;
5491 it->method = next_element_from_display_vector;
5492 }
5493 else
5494 {
5495 /* Use default `...' which is stored in default_invis_vector. */
5496 it->dpvec_char_len = it->len;
5497 it->dpvec = default_invis_vector;
5498 it->dpend = default_invis_vector + 3;
5499 it->current.dpvec_index = 0;
5500 it->method = next_element_from_display_vector;
5501 }
5502 }
5503 else
5504 {
5505 /* The face at the current position may be different from the
5506 face we find after the invisible text. Remember what it
5507 was in IT->saved_face_id, and signal that it's there by
5508 setting face_before_selective_p. */
5509 it->saved_face_id = it->face_id;
5510 it->method = next_element_from_buffer;
5511 reseat_at_next_visible_line_start (it, 1);
5512 it->face_before_selective_p = 1;
5513 }
5514
5515 return get_next_display_element (it);
5516 }
5517
5518
5519 /* Deliver an image display element. The iterator IT is already
5520 filled with image information (done in handle_display_prop). Value
5521 is always 1. */
5522
5523
5524 static int
5525 next_element_from_image (it)
5526 struct it *it;
5527 {
5528 it->what = IT_IMAGE;
5529 return 1;
5530 }
5531
5532
5533 /* Fill iterator IT with next display element from a stretch glyph
5534 property. IT->object is the value of the text property. Value is
5535 always 1. */
5536
5537 static int
5538 next_element_from_stretch (it)
5539 struct it *it;
5540 {
5541 it->what = IT_STRETCH;
5542 return 1;
5543 }
5544
5545
5546 /* Load IT with the next display element from current_buffer. Value
5547 is zero if end of buffer reached. IT->stop_charpos is the next
5548 position at which to stop and check for text properties or buffer
5549 end. */
5550
5551 static int
5552 next_element_from_buffer (it)
5553 struct it *it;
5554 {
5555 int success_p = 1;
5556
5557 /* Check this assumption, otherwise, we would never enter the
5558 if-statement, below. */
5559 xassert (IT_CHARPOS (*it) >= BEGV
5560 && IT_CHARPOS (*it) <= it->stop_charpos);
5561
5562 if (IT_CHARPOS (*it) >= it->stop_charpos)
5563 {
5564 if (IT_CHARPOS (*it) >= it->end_charpos)
5565 {
5566 int overlay_strings_follow_p;
5567
5568 /* End of the game, except when overlay strings follow that
5569 haven't been returned yet. */
5570 if (it->overlay_strings_at_end_processed_p)
5571 overlay_strings_follow_p = 0;
5572 else
5573 {
5574 it->overlay_strings_at_end_processed_p = 1;
5575 overlay_strings_follow_p = get_overlay_strings (it, 0);
5576 }
5577
5578 if (overlay_strings_follow_p)
5579 success_p = get_next_display_element (it);
5580 else
5581 {
5582 it->what = IT_EOB;
5583 it->position = it->current.pos;
5584 success_p = 0;
5585 }
5586 }
5587 else
5588 {
5589 handle_stop (it);
5590 return get_next_display_element (it);
5591 }
5592 }
5593 else
5594 {
5595 /* No face changes, overlays etc. in sight, so just return a
5596 character from current_buffer. */
5597 unsigned char *p;
5598
5599 /* Maybe run the redisplay end trigger hook. Performance note:
5600 This doesn't seem to cost measurable time. */
5601 if (it->redisplay_end_trigger_charpos
5602 && it->glyph_row
5603 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5604 run_redisplay_end_trigger_hook (it);
5605
5606 /* Get the next character, maybe multibyte. */
5607 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5608 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5609 {
5610 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5611 - IT_BYTEPOS (*it));
5612 it->c = string_char_and_length (p, maxlen, &it->len);
5613 }
5614 else
5615 it->c = *p, it->len = 1;
5616
5617 /* Record what we have and where it came from. */
5618 it->what = IT_CHARACTER;;
5619 it->object = it->w->buffer;
5620 it->position = it->current.pos;
5621
5622 /* Normally we return the character found above, except when we
5623 really want to return an ellipsis for selective display. */
5624 if (it->selective)
5625 {
5626 if (it->c == '\n')
5627 {
5628 /* A value of selective > 0 means hide lines indented more
5629 than that number of columns. */
5630 if (it->selective > 0
5631 && IT_CHARPOS (*it) + 1 < ZV
5632 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5633 IT_BYTEPOS (*it) + 1,
5634 (double) it->selective)) /* iftc */
5635 {
5636 success_p = next_element_from_ellipsis (it);
5637 it->dpvec_char_len = -1;
5638 }
5639 }
5640 else if (it->c == '\r' && it->selective == -1)
5641 {
5642 /* A value of selective == -1 means that everything from the
5643 CR to the end of the line is invisible, with maybe an
5644 ellipsis displayed for it. */
5645 success_p = next_element_from_ellipsis (it);
5646 it->dpvec_char_len = -1;
5647 }
5648 }
5649 }
5650
5651 /* Value is zero if end of buffer reached. */
5652 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5653 return success_p;
5654 }
5655
5656
5657 /* Run the redisplay end trigger hook for IT. */
5658
5659 static void
5660 run_redisplay_end_trigger_hook (it)
5661 struct it *it;
5662 {
5663 Lisp_Object args[3];
5664
5665 /* IT->glyph_row should be non-null, i.e. we should be actually
5666 displaying something, or otherwise we should not run the hook. */
5667 xassert (it->glyph_row);
5668
5669 /* Set up hook arguments. */
5670 args[0] = Qredisplay_end_trigger_functions;
5671 args[1] = it->window;
5672 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5673 it->redisplay_end_trigger_charpos = 0;
5674
5675 /* Since we are *trying* to run these functions, don't try to run
5676 them again, even if they get an error. */
5677 it->w->redisplay_end_trigger = Qnil;
5678 Frun_hook_with_args (3, args);
5679
5680 /* Notice if it changed the face of the character we are on. */
5681 handle_face_prop (it);
5682 }
5683
5684
5685 /* Deliver a composition display element. The iterator IT is already
5686 filled with composition information (done in
5687 handle_composition_prop). Value is always 1. */
5688
5689 static int
5690 next_element_from_composition (it)
5691 struct it *it;
5692 {
5693 it->what = IT_COMPOSITION;
5694 it->position = (STRINGP (it->string)
5695 ? it->current.string_pos
5696 : it->current.pos);
5697 return 1;
5698 }
5699
5700
5701 \f
5702 /***********************************************************************
5703 Moving an iterator without producing glyphs
5704 ***********************************************************************/
5705
5706 /* Move iterator IT to a specified buffer or X position within one
5707 line on the display without producing glyphs.
5708
5709 OP should be a bit mask including some or all of these bits:
5710 MOVE_TO_X: Stop on reaching x-position TO_X.
5711 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5712 Regardless of OP's value, stop in reaching the end of the display line.
5713
5714 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5715 This means, in particular, that TO_X includes window's horizontal
5716 scroll amount.
5717
5718 The return value has several possible values that
5719 say what condition caused the scan to stop:
5720
5721 MOVE_POS_MATCH_OR_ZV
5722 - when TO_POS or ZV was reached.
5723
5724 MOVE_X_REACHED
5725 -when TO_X was reached before TO_POS or ZV were reached.
5726
5727 MOVE_LINE_CONTINUED
5728 - when we reached the end of the display area and the line must
5729 be continued.
5730
5731 MOVE_LINE_TRUNCATED
5732 - when we reached the end of the display area and the line is
5733 truncated.
5734
5735 MOVE_NEWLINE_OR_CR
5736 - when we stopped at a line end, i.e. a newline or a CR and selective
5737 display is on. */
5738
5739 static enum move_it_result
5740 move_it_in_display_line_to (it, to_charpos, to_x, op)
5741 struct it *it;
5742 int to_charpos, to_x, op;
5743 {
5744 enum move_it_result result = MOVE_UNDEFINED;
5745 struct glyph_row *saved_glyph_row;
5746
5747 /* Don't produce glyphs in produce_glyphs. */
5748 saved_glyph_row = it->glyph_row;
5749 it->glyph_row = NULL;
5750
5751 #define BUFFER_POS_REACHED_P() \
5752 ((op & MOVE_TO_POS) != 0 \
5753 && BUFFERP (it->object) \
5754 && IT_CHARPOS (*it) >= to_charpos)
5755
5756 while (1)
5757 {
5758 int x, i, ascent = 0, descent = 0;
5759
5760 /* Stop when ZV reached.
5761 We used to stop here when TO_CHARPOS reached as well, but that is
5762 too soon if this glyph does not fit on this line. So we handle it
5763 explicitly below. */
5764 if (!get_next_display_element (it)
5765 || (it->truncate_lines_p
5766 && BUFFER_POS_REACHED_P ()))
5767 {
5768 result = MOVE_POS_MATCH_OR_ZV;
5769 break;
5770 }
5771
5772 /* The call to produce_glyphs will get the metrics of the
5773 display element IT is loaded with. We record in x the
5774 x-position before this display element in case it does not
5775 fit on the line. */
5776 x = it->current_x;
5777
5778 /* Remember the line height so far in case the next element doesn't
5779 fit on the line. */
5780 if (!it->truncate_lines_p)
5781 {
5782 ascent = it->max_ascent;
5783 descent = it->max_descent;
5784 }
5785
5786 PRODUCE_GLYPHS (it);
5787
5788 if (it->area != TEXT_AREA)
5789 {
5790 set_iterator_to_next (it, 1);
5791 continue;
5792 }
5793
5794 /* The number of glyphs we get back in IT->nglyphs will normally
5795 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5796 character on a terminal frame, or (iii) a line end. For the
5797 second case, IT->nglyphs - 1 padding glyphs will be present
5798 (on X frames, there is only one glyph produced for a
5799 composite character.
5800
5801 The behavior implemented below means, for continuation lines,
5802 that as many spaces of a TAB as fit on the current line are
5803 displayed there. For terminal frames, as many glyphs of a
5804 multi-glyph character are displayed in the current line, too.
5805 This is what the old redisplay code did, and we keep it that
5806 way. Under X, the whole shape of a complex character must
5807 fit on the line or it will be completely displayed in the
5808 next line.
5809
5810 Note that both for tabs and padding glyphs, all glyphs have
5811 the same width. */
5812 if (it->nglyphs)
5813 {
5814 /* More than one glyph or glyph doesn't fit on line. All
5815 glyphs have the same width. */
5816 int single_glyph_width = it->pixel_width / it->nglyphs;
5817 int new_x;
5818
5819 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5820 {
5821 new_x = x + single_glyph_width;
5822
5823 /* We want to leave anything reaching TO_X to the caller. */
5824 if ((op & MOVE_TO_X) && new_x > to_x)
5825 {
5826 if (BUFFER_POS_REACHED_P ())
5827 goto buffer_pos_reached;
5828 it->current_x = x;
5829 result = MOVE_X_REACHED;
5830 break;
5831 }
5832 else if (/* Lines are continued. */
5833 !it->truncate_lines_p
5834 && (/* And glyph doesn't fit on the line. */
5835 new_x > it->last_visible_x
5836 /* Or it fits exactly and we're on a window
5837 system frame. */
5838 || (new_x == it->last_visible_x
5839 && FRAME_WINDOW_P (it->f))))
5840 {
5841 if (/* IT->hpos == 0 means the very first glyph
5842 doesn't fit on the line, e.g. a wide image. */
5843 it->hpos == 0
5844 || (new_x == it->last_visible_x
5845 && FRAME_WINDOW_P (it->f)))
5846 {
5847 ++it->hpos;
5848 it->current_x = new_x;
5849 if (i == it->nglyphs - 1)
5850 {
5851 set_iterator_to_next (it, 1);
5852 #ifdef HAVE_WINDOW_SYSTEM
5853 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5854 {
5855 if (!get_next_display_element (it))
5856 {
5857 result = MOVE_POS_MATCH_OR_ZV;
5858 break;
5859 }
5860 if (BUFFER_POS_REACHED_P ())
5861 {
5862 if (ITERATOR_AT_END_OF_LINE_P (it))
5863 result = MOVE_POS_MATCH_OR_ZV;
5864 else
5865 result = MOVE_LINE_CONTINUED;
5866 break;
5867 }
5868 if (ITERATOR_AT_END_OF_LINE_P (it))
5869 {
5870 result = MOVE_NEWLINE_OR_CR;
5871 break;
5872 }
5873 }
5874 #endif /* HAVE_WINDOW_SYSTEM */
5875 }
5876 }
5877 else
5878 {
5879 it->current_x = x;
5880 it->max_ascent = ascent;
5881 it->max_descent = descent;
5882 }
5883
5884 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5885 IT_CHARPOS (*it)));
5886 result = MOVE_LINE_CONTINUED;
5887 break;
5888 }
5889 else if (BUFFER_POS_REACHED_P ())
5890 goto buffer_pos_reached;
5891 else if (new_x > it->first_visible_x)
5892 {
5893 /* Glyph is visible. Increment number of glyphs that
5894 would be displayed. */
5895 ++it->hpos;
5896 }
5897 else
5898 {
5899 /* Glyph is completely off the left margin of the display
5900 area. Nothing to do. */
5901 }
5902 }
5903
5904 if (result != MOVE_UNDEFINED)
5905 break;
5906 }
5907 else if (BUFFER_POS_REACHED_P ())
5908 {
5909 buffer_pos_reached:
5910 it->current_x = x;
5911 it->max_ascent = ascent;
5912 it->max_descent = descent;
5913 result = MOVE_POS_MATCH_OR_ZV;
5914 break;
5915 }
5916 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5917 {
5918 /* Stop when TO_X specified and reached. This check is
5919 necessary here because of lines consisting of a line end,
5920 only. The line end will not produce any glyphs and we
5921 would never get MOVE_X_REACHED. */
5922 xassert (it->nglyphs == 0);
5923 result = MOVE_X_REACHED;
5924 break;
5925 }
5926
5927 /* Is this a line end? If yes, we're done. */
5928 if (ITERATOR_AT_END_OF_LINE_P (it))
5929 {
5930 result = MOVE_NEWLINE_OR_CR;
5931 break;
5932 }
5933
5934 /* The current display element has been consumed. Advance
5935 to the next. */
5936 set_iterator_to_next (it, 1);
5937
5938 /* Stop if lines are truncated and IT's current x-position is
5939 past the right edge of the window now. */
5940 if (it->truncate_lines_p
5941 && it->current_x >= it->last_visible_x)
5942 {
5943 #ifdef HAVE_WINDOW_SYSTEM
5944 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5945 {
5946 if (!get_next_display_element (it)
5947 || BUFFER_POS_REACHED_P ())
5948 {
5949 result = MOVE_POS_MATCH_OR_ZV;
5950 break;
5951 }
5952 if (ITERATOR_AT_END_OF_LINE_P (it))
5953 {
5954 result = MOVE_NEWLINE_OR_CR;
5955 break;
5956 }
5957 }
5958 #endif /* HAVE_WINDOW_SYSTEM */
5959 result = MOVE_LINE_TRUNCATED;
5960 break;
5961 }
5962 }
5963
5964 #undef BUFFER_POS_REACHED_P
5965
5966 /* Restore the iterator settings altered at the beginning of this
5967 function. */
5968 it->glyph_row = saved_glyph_row;
5969 return result;
5970 }
5971
5972
5973 /* Move IT forward until it satisfies one or more of the criteria in
5974 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5975
5976 OP is a bit-mask that specifies where to stop, and in particular,
5977 which of those four position arguments makes a difference. See the
5978 description of enum move_operation_enum.
5979
5980 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5981 screen line, this function will set IT to the next position >
5982 TO_CHARPOS. */
5983
5984 void
5985 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5986 struct it *it;
5987 int to_charpos, to_x, to_y, to_vpos;
5988 int op;
5989 {
5990 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5991 int line_height;
5992 int reached = 0;
5993
5994 for (;;)
5995 {
5996 if (op & MOVE_TO_VPOS)
5997 {
5998 /* If no TO_CHARPOS and no TO_X specified, stop at the
5999 start of the line TO_VPOS. */
6000 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6001 {
6002 if (it->vpos == to_vpos)
6003 {
6004 reached = 1;
6005 break;
6006 }
6007 else
6008 skip = move_it_in_display_line_to (it, -1, -1, 0);
6009 }
6010 else
6011 {
6012 /* TO_VPOS >= 0 means stop at TO_X in the line at
6013 TO_VPOS, or at TO_POS, whichever comes first. */
6014 if (it->vpos == to_vpos)
6015 {
6016 reached = 2;
6017 break;
6018 }
6019
6020 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6021
6022 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6023 {
6024 reached = 3;
6025 break;
6026 }
6027 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6028 {
6029 /* We have reached TO_X but not in the line we want. */
6030 skip = move_it_in_display_line_to (it, to_charpos,
6031 -1, MOVE_TO_POS);
6032 if (skip == MOVE_POS_MATCH_OR_ZV)
6033 {
6034 reached = 4;
6035 break;
6036 }
6037 }
6038 }
6039 }
6040 else if (op & MOVE_TO_Y)
6041 {
6042 struct it it_backup;
6043
6044 /* TO_Y specified means stop at TO_X in the line containing
6045 TO_Y---or at TO_CHARPOS if this is reached first. The
6046 problem is that we can't really tell whether the line
6047 contains TO_Y before we have completely scanned it, and
6048 this may skip past TO_X. What we do is to first scan to
6049 TO_X.
6050
6051 If TO_X is not specified, use a TO_X of zero. The reason
6052 is to make the outcome of this function more predictable.
6053 If we didn't use TO_X == 0, we would stop at the end of
6054 the line which is probably not what a caller would expect
6055 to happen. */
6056 skip = move_it_in_display_line_to (it, to_charpos,
6057 ((op & MOVE_TO_X)
6058 ? to_x : 0),
6059 (MOVE_TO_X
6060 | (op & MOVE_TO_POS)));
6061
6062 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6063 if (skip == MOVE_POS_MATCH_OR_ZV)
6064 {
6065 reached = 5;
6066 break;
6067 }
6068
6069 /* If TO_X was reached, we would like to know whether TO_Y
6070 is in the line. This can only be said if we know the
6071 total line height which requires us to scan the rest of
6072 the line. */
6073 if (skip == MOVE_X_REACHED)
6074 {
6075 /* Wait! We can conclude that TO_Y is in the line if
6076 the already scanned glyphs make the line tall enough
6077 because further scanning doesn't make it shorter. */
6078 line_height = it->max_ascent + it->max_descent;
6079 if (to_y >= it->current_y
6080 && to_y < it->current_y + line_height)
6081 {
6082 reached = 6;
6083 break;
6084 }
6085 it_backup = *it;
6086 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6087 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6088 op & MOVE_TO_POS);
6089 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6090 }
6091
6092 /* Now, decide whether TO_Y is in this line. */
6093 line_height = it->max_ascent + it->max_descent;
6094 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6095
6096 if (to_y >= it->current_y
6097 && to_y < it->current_y + line_height)
6098 {
6099 if (skip == MOVE_X_REACHED)
6100 /* If TO_Y is in this line and TO_X was reached above,
6101 we scanned too far. We have to restore IT's settings
6102 to the ones before skipping. */
6103 *it = it_backup;
6104 reached = 6;
6105 }
6106 else if (skip == MOVE_X_REACHED)
6107 {
6108 skip = skip2;
6109 if (skip == MOVE_POS_MATCH_OR_ZV)
6110 reached = 7;
6111 }
6112
6113 if (reached)
6114 break;
6115 }
6116 else
6117 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6118
6119 switch (skip)
6120 {
6121 case MOVE_POS_MATCH_OR_ZV:
6122 reached = 8;
6123 goto out;
6124
6125 case MOVE_NEWLINE_OR_CR:
6126 set_iterator_to_next (it, 1);
6127 it->continuation_lines_width = 0;
6128 break;
6129
6130 case MOVE_LINE_TRUNCATED:
6131 it->continuation_lines_width = 0;
6132 reseat_at_next_visible_line_start (it, 0);
6133 if ((op & MOVE_TO_POS) != 0
6134 && IT_CHARPOS (*it) > to_charpos)
6135 {
6136 reached = 9;
6137 goto out;
6138 }
6139 break;
6140
6141 case MOVE_LINE_CONTINUED:
6142 it->continuation_lines_width += it->current_x;
6143 break;
6144
6145 default:
6146 abort ();
6147 }
6148
6149 /* Reset/increment for the next run. */
6150 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6151 it->current_x = it->hpos = 0;
6152 it->current_y += it->max_ascent + it->max_descent;
6153 ++it->vpos;
6154 last_height = it->max_ascent + it->max_descent;
6155 last_max_ascent = it->max_ascent;
6156 it->max_ascent = it->max_descent = 0;
6157 }
6158
6159 out:
6160
6161 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6162 }
6163
6164
6165 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6166
6167 If DY > 0, move IT backward at least that many pixels. DY = 0
6168 means move IT backward to the preceding line start or BEGV. This
6169 function may move over more than DY pixels if IT->current_y - DY
6170 ends up in the middle of a line; in this case IT->current_y will be
6171 set to the top of the line moved to. */
6172
6173 void
6174 move_it_vertically_backward (it, dy)
6175 struct it *it;
6176 int dy;
6177 {
6178 int nlines, h;
6179 struct it it2, it3;
6180 int start_pos = IT_CHARPOS (*it);
6181
6182 xassert (dy >= 0);
6183
6184 /* Estimate how many newlines we must move back. */
6185 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6186
6187 /* Set the iterator's position that many lines back. */
6188 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6189 back_to_previous_visible_line_start (it);
6190
6191 /* Reseat the iterator here. When moving backward, we don't want
6192 reseat to skip forward over invisible text, set up the iterator
6193 to deliver from overlay strings at the new position etc. So,
6194 use reseat_1 here. */
6195 reseat_1 (it, it->current.pos, 1);
6196
6197 /* We are now surely at a line start. */
6198 it->current_x = it->hpos = 0;
6199 it->continuation_lines_width = 0;
6200
6201 /* Move forward and see what y-distance we moved. First move to the
6202 start of the next line so that we get its height. We need this
6203 height to be able to tell whether we reached the specified
6204 y-distance. */
6205 it2 = *it;
6206 it2.max_ascent = it2.max_descent = 0;
6207 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6208 MOVE_TO_POS | MOVE_TO_VPOS);
6209 xassert (IT_CHARPOS (*it) >= BEGV);
6210 it3 = it2;
6211
6212 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6213 xassert (IT_CHARPOS (*it) >= BEGV);
6214 /* H is the actual vertical distance from the position in *IT
6215 and the starting position. */
6216 h = it2.current_y - it->current_y;
6217 /* NLINES is the distance in number of lines. */
6218 nlines = it2.vpos - it->vpos;
6219
6220 /* Correct IT's y and vpos position
6221 so that they are relative to the starting point. */
6222 it->vpos -= nlines;
6223 it->current_y -= h;
6224
6225 if (dy == 0)
6226 {
6227 /* DY == 0 means move to the start of the screen line. The
6228 value of nlines is > 0 if continuation lines were involved. */
6229 if (nlines > 0)
6230 move_it_by_lines (it, nlines, 1);
6231 xassert (IT_CHARPOS (*it) <= start_pos);
6232 }
6233 else
6234 {
6235 /* The y-position we try to reach, relative to *IT.
6236 Note that H has been subtracted in front of the if-statement. */
6237 int target_y = it->current_y + h - dy;
6238 int y0 = it3.current_y;
6239 int y1 = line_bottom_y (&it3);
6240 int line_height = y1 - y0;
6241
6242 /* If we did not reach target_y, try to move further backward if
6243 we can. If we moved too far backward, try to move forward. */
6244 if (target_y < it->current_y
6245 /* This is heuristic. In a window that's 3 lines high, with
6246 a line height of 13 pixels each, recentering with point
6247 on the bottom line will try to move -39/2 = 19 pixels
6248 backward. Try to avoid moving into the first line. */
6249 && it->current_y - target_y > line_height / 3 * 2
6250 && IT_CHARPOS (*it) > BEGV)
6251 {
6252 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6253 target_y - it->current_y));
6254 move_it_vertically (it, target_y - it->current_y);
6255 xassert (IT_CHARPOS (*it) >= BEGV);
6256 }
6257 else if (target_y >= it->current_y + line_height
6258 && IT_CHARPOS (*it) < ZV)
6259 {
6260 /* Should move forward by at least one line, maybe more.
6261
6262 Note: Calling move_it_by_lines can be expensive on
6263 terminal frames, where compute_motion is used (via
6264 vmotion) to do the job, when there are very long lines
6265 and truncate-lines is nil. That's the reason for
6266 treating terminal frames specially here. */
6267
6268 if (!FRAME_WINDOW_P (it->f))
6269 move_it_vertically (it, target_y - (it->current_y + line_height));
6270 else
6271 {
6272 do
6273 {
6274 move_it_by_lines (it, 1, 1);
6275 }
6276 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6277 }
6278
6279 xassert (IT_CHARPOS (*it) >= BEGV);
6280 }
6281 }
6282 }
6283
6284
6285 /* Move IT by a specified amount of pixel lines DY. DY negative means
6286 move backwards. DY = 0 means move to start of screen line. At the
6287 end, IT will be on the start of a screen line. */
6288
6289 void
6290 move_it_vertically (it, dy)
6291 struct it *it;
6292 int dy;
6293 {
6294 if (dy <= 0)
6295 move_it_vertically_backward (it, -dy);
6296 else if (dy > 0)
6297 {
6298 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6299 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6300 MOVE_TO_POS | MOVE_TO_Y);
6301 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6302
6303 /* If buffer ends in ZV without a newline, move to the start of
6304 the line to satisfy the post-condition. */
6305 if (IT_CHARPOS (*it) == ZV
6306 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6307 move_it_by_lines (it, 0, 0);
6308 }
6309 }
6310
6311
6312 /* Move iterator IT past the end of the text line it is in. */
6313
6314 void
6315 move_it_past_eol (it)
6316 struct it *it;
6317 {
6318 enum move_it_result rc;
6319
6320 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6321 if (rc == MOVE_NEWLINE_OR_CR)
6322 set_iterator_to_next (it, 0);
6323 }
6324
6325
6326 #if 0 /* Currently not used. */
6327
6328 /* Return non-zero if some text between buffer positions START_CHARPOS
6329 and END_CHARPOS is invisible. IT->window is the window for text
6330 property lookup. */
6331
6332 static int
6333 invisible_text_between_p (it, start_charpos, end_charpos)
6334 struct it *it;
6335 int start_charpos, end_charpos;
6336 {
6337 Lisp_Object prop, limit;
6338 int invisible_found_p;
6339
6340 xassert (it != NULL && start_charpos <= end_charpos);
6341
6342 /* Is text at START invisible? */
6343 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6344 it->window);
6345 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6346 invisible_found_p = 1;
6347 else
6348 {
6349 limit = Fnext_single_char_property_change (make_number (start_charpos),
6350 Qinvisible, Qnil,
6351 make_number (end_charpos));
6352 invisible_found_p = XFASTINT (limit) < end_charpos;
6353 }
6354
6355 return invisible_found_p;
6356 }
6357
6358 #endif /* 0 */
6359
6360
6361 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6362 negative means move up. DVPOS == 0 means move to the start of the
6363 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6364 NEED_Y_P is zero, IT->current_y will be left unchanged.
6365
6366 Further optimization ideas: If we would know that IT->f doesn't use
6367 a face with proportional font, we could be faster for
6368 truncate-lines nil. */
6369
6370 void
6371 move_it_by_lines (it, dvpos, need_y_p)
6372 struct it *it;
6373 int dvpos, need_y_p;
6374 {
6375 struct position pos;
6376
6377 if (!FRAME_WINDOW_P (it->f))
6378 {
6379 struct text_pos textpos;
6380
6381 /* We can use vmotion on frames without proportional fonts. */
6382 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6383 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6384 reseat (it, textpos, 1);
6385 it->vpos += pos.vpos;
6386 it->current_y += pos.vpos;
6387 }
6388 else if (dvpos == 0)
6389 {
6390 /* DVPOS == 0 means move to the start of the screen line. */
6391 move_it_vertically_backward (it, 0);
6392 xassert (it->current_x == 0 && it->hpos == 0);
6393 }
6394 else if (dvpos > 0)
6395 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6396 else
6397 {
6398 struct it it2;
6399 int start_charpos, i;
6400
6401 /* Start at the beginning of the screen line containing IT's
6402 position. */
6403 move_it_vertically_backward (it, 0);
6404
6405 /* Go back -DVPOS visible lines and reseat the iterator there. */
6406 start_charpos = IT_CHARPOS (*it);
6407 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6408 back_to_previous_visible_line_start (it);
6409 reseat (it, it->current.pos, 1);
6410 it->current_x = it->hpos = 0;
6411
6412 /* Above call may have moved too far if continuation lines
6413 are involved. Scan forward and see if it did. */
6414 it2 = *it;
6415 it2.vpos = it2.current_y = 0;
6416 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6417 it->vpos -= it2.vpos;
6418 it->current_y -= it2.current_y;
6419 it->current_x = it->hpos = 0;
6420
6421 /* If we moved too far, move IT some lines forward. */
6422 if (it2.vpos > -dvpos)
6423 {
6424 int delta = it2.vpos + dvpos;
6425 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6426 }
6427 }
6428 }
6429
6430 /* Return 1 if IT points into the middle of a display vector. */
6431
6432 int
6433 in_display_vector_p (it)
6434 struct it *it;
6435 {
6436 return (it->method == next_element_from_display_vector
6437 && it->current.dpvec_index > 0
6438 && it->dpvec + it->current.dpvec_index != it->dpend);
6439 }
6440
6441 \f
6442 /***********************************************************************
6443 Messages
6444 ***********************************************************************/
6445
6446
6447 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6448 to *Messages*. */
6449
6450 void
6451 add_to_log (format, arg1, arg2)
6452 char *format;
6453 Lisp_Object arg1, arg2;
6454 {
6455 Lisp_Object args[3];
6456 Lisp_Object msg, fmt;
6457 char *buffer;
6458 int len;
6459 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6460 USE_SAFE_ALLOCA;
6461
6462 /* Do nothing if called asynchronously. Inserting text into
6463 a buffer may call after-change-functions and alike and
6464 that would means running Lisp asynchronously. */
6465 if (handling_signal)
6466 return;
6467
6468 fmt = msg = Qnil;
6469 GCPRO4 (fmt, msg, arg1, arg2);
6470
6471 args[0] = fmt = build_string (format);
6472 args[1] = arg1;
6473 args[2] = arg2;
6474 msg = Fformat (3, args);
6475
6476 len = SBYTES (msg) + 1;
6477 SAFE_ALLOCA (buffer, char *, len);
6478 bcopy (SDATA (msg), buffer, len);
6479
6480 message_dolog (buffer, len - 1, 1, 0);
6481 SAFE_FREE ();
6482
6483 UNGCPRO;
6484 }
6485
6486
6487 /* Output a newline in the *Messages* buffer if "needs" one. */
6488
6489 void
6490 message_log_maybe_newline ()
6491 {
6492 if (message_log_need_newline)
6493 message_dolog ("", 0, 1, 0);
6494 }
6495
6496
6497 /* Add a string M of length NBYTES to the message log, optionally
6498 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6499 nonzero, means interpret the contents of M as multibyte. This
6500 function calls low-level routines in order to bypass text property
6501 hooks, etc. which might not be safe to run. */
6502
6503 void
6504 message_dolog (m, nbytes, nlflag, multibyte)
6505 const char *m;
6506 int nbytes, nlflag, multibyte;
6507 {
6508 if (!NILP (Vmemory_full))
6509 return;
6510
6511 if (!NILP (Vmessage_log_max))
6512 {
6513 struct buffer *oldbuf;
6514 Lisp_Object oldpoint, oldbegv, oldzv;
6515 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6516 int point_at_end = 0;
6517 int zv_at_end = 0;
6518 Lisp_Object old_deactivate_mark, tem;
6519 struct gcpro gcpro1;
6520
6521 old_deactivate_mark = Vdeactivate_mark;
6522 oldbuf = current_buffer;
6523 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6524 current_buffer->undo_list = Qt;
6525
6526 oldpoint = message_dolog_marker1;
6527 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6528 oldbegv = message_dolog_marker2;
6529 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6530 oldzv = message_dolog_marker3;
6531 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6532 GCPRO1 (old_deactivate_mark);
6533
6534 if (PT == Z)
6535 point_at_end = 1;
6536 if (ZV == Z)
6537 zv_at_end = 1;
6538
6539 BEGV = BEG;
6540 BEGV_BYTE = BEG_BYTE;
6541 ZV = Z;
6542 ZV_BYTE = Z_BYTE;
6543 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6544
6545 /* Insert the string--maybe converting multibyte to single byte
6546 or vice versa, so that all the text fits the buffer. */
6547 if (multibyte
6548 && NILP (current_buffer->enable_multibyte_characters))
6549 {
6550 int i, c, char_bytes;
6551 unsigned char work[1];
6552
6553 /* Convert a multibyte string to single-byte
6554 for the *Message* buffer. */
6555 for (i = 0; i < nbytes; i += char_bytes)
6556 {
6557 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6558 work[0] = (ASCII_CHAR_P (c)
6559 ? c
6560 : multibyte_char_to_unibyte (c, Qnil));
6561 insert_1_both (work, 1, 1, 1, 0, 0);
6562 }
6563 }
6564 else if (! multibyte
6565 && ! NILP (current_buffer->enable_multibyte_characters))
6566 {
6567 int i, c, char_bytes;
6568 unsigned char *msg = (unsigned char *) m;
6569 unsigned char str[MAX_MULTIBYTE_LENGTH];
6570 /* Convert a single-byte string to multibyte
6571 for the *Message* buffer. */
6572 for (i = 0; i < nbytes; i++)
6573 {
6574 c = msg[i];
6575 c = unibyte_char_to_multibyte (c);
6576 char_bytes = CHAR_STRING (c, str);
6577 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6578 }
6579 }
6580 else if (nbytes)
6581 insert_1 (m, nbytes, 1, 0, 0);
6582
6583 if (nlflag)
6584 {
6585 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6586 insert_1 ("\n", 1, 1, 0, 0);
6587
6588 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6589 this_bol = PT;
6590 this_bol_byte = PT_BYTE;
6591
6592 /* See if this line duplicates the previous one.
6593 If so, combine duplicates. */
6594 if (this_bol > BEG)
6595 {
6596 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6597 prev_bol = PT;
6598 prev_bol_byte = PT_BYTE;
6599
6600 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6601 this_bol, this_bol_byte);
6602 if (dup)
6603 {
6604 del_range_both (prev_bol, prev_bol_byte,
6605 this_bol, this_bol_byte, 0);
6606 if (dup > 1)
6607 {
6608 char dupstr[40];
6609 int duplen;
6610
6611 /* If you change this format, don't forget to also
6612 change message_log_check_duplicate. */
6613 sprintf (dupstr, " [%d times]", dup);
6614 duplen = strlen (dupstr);
6615 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6616 insert_1 (dupstr, duplen, 1, 0, 1);
6617 }
6618 }
6619 }
6620
6621 /* If we have more than the desired maximum number of lines
6622 in the *Messages* buffer now, delete the oldest ones.
6623 This is safe because we don't have undo in this buffer. */
6624
6625 if (NATNUMP (Vmessage_log_max))
6626 {
6627 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6628 -XFASTINT (Vmessage_log_max) - 1, 0);
6629 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6630 }
6631 }
6632 BEGV = XMARKER (oldbegv)->charpos;
6633 BEGV_BYTE = marker_byte_position (oldbegv);
6634
6635 if (zv_at_end)
6636 {
6637 ZV = Z;
6638 ZV_BYTE = Z_BYTE;
6639 }
6640 else
6641 {
6642 ZV = XMARKER (oldzv)->charpos;
6643 ZV_BYTE = marker_byte_position (oldzv);
6644 }
6645
6646 if (point_at_end)
6647 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6648 else
6649 /* We can't do Fgoto_char (oldpoint) because it will run some
6650 Lisp code. */
6651 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6652 XMARKER (oldpoint)->bytepos);
6653
6654 UNGCPRO;
6655 unchain_marker (XMARKER (oldpoint));
6656 unchain_marker (XMARKER (oldbegv));
6657 unchain_marker (XMARKER (oldzv));
6658
6659 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6660 set_buffer_internal (oldbuf);
6661 if (NILP (tem))
6662 windows_or_buffers_changed = old_windows_or_buffers_changed;
6663 message_log_need_newline = !nlflag;
6664 Vdeactivate_mark = old_deactivate_mark;
6665 }
6666 }
6667
6668
6669 /* We are at the end of the buffer after just having inserted a newline.
6670 (Note: We depend on the fact we won't be crossing the gap.)
6671 Check to see if the most recent message looks a lot like the previous one.
6672 Return 0 if different, 1 if the new one should just replace it, or a
6673 value N > 1 if we should also append " [N times]". */
6674
6675 static int
6676 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6677 int prev_bol, this_bol;
6678 int prev_bol_byte, this_bol_byte;
6679 {
6680 int i;
6681 int len = Z_BYTE - 1 - this_bol_byte;
6682 int seen_dots = 0;
6683 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6684 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6685
6686 for (i = 0; i < len; i++)
6687 {
6688 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6689 seen_dots = 1;
6690 if (p1[i] != p2[i])
6691 return seen_dots;
6692 }
6693 p1 += len;
6694 if (*p1 == '\n')
6695 return 2;
6696 if (*p1++ == ' ' && *p1++ == '[')
6697 {
6698 int n = 0;
6699 while (*p1 >= '0' && *p1 <= '9')
6700 n = n * 10 + *p1++ - '0';
6701 if (strncmp (p1, " times]\n", 8) == 0)
6702 return n+1;
6703 }
6704 return 0;
6705 }
6706
6707
6708 /* Display an echo area message M with a specified length of NBYTES
6709 bytes. The string may include null characters. If M is 0, clear
6710 out any existing message, and let the mini-buffer text show
6711 through.
6712
6713 The buffer M must continue to exist until after the echo area gets
6714 cleared or some other message gets displayed there. This means do
6715 not pass text that is stored in a Lisp string; do not pass text in
6716 a buffer that was alloca'd. */
6717
6718 void
6719 message2 (m, nbytes, multibyte)
6720 const char *m;
6721 int nbytes;
6722 int multibyte;
6723 {
6724 /* First flush out any partial line written with print. */
6725 message_log_maybe_newline ();
6726 if (m)
6727 message_dolog (m, nbytes, 1, multibyte);
6728 message2_nolog (m, nbytes, multibyte);
6729 }
6730
6731
6732 /* The non-logging counterpart of message2. */
6733
6734 void
6735 message2_nolog (m, nbytes, multibyte)
6736 const char *m;
6737 int nbytes, multibyte;
6738 {
6739 struct frame *sf = SELECTED_FRAME ();
6740 message_enable_multibyte = multibyte;
6741
6742 if (noninteractive)
6743 {
6744 if (noninteractive_need_newline)
6745 putc ('\n', stderr);
6746 noninteractive_need_newline = 0;
6747 if (m)
6748 fwrite (m, nbytes, 1, stderr);
6749 if (cursor_in_echo_area == 0)
6750 fprintf (stderr, "\n");
6751 fflush (stderr);
6752 }
6753 /* A null message buffer means that the frame hasn't really been
6754 initialized yet. Error messages get reported properly by
6755 cmd_error, so this must be just an informative message; toss it. */
6756 else if (INTERACTIVE
6757 && sf->glyphs_initialized_p
6758 && FRAME_MESSAGE_BUF (sf))
6759 {
6760 Lisp_Object mini_window;
6761 struct frame *f;
6762
6763 /* Get the frame containing the mini-buffer
6764 that the selected frame is using. */
6765 mini_window = FRAME_MINIBUF_WINDOW (sf);
6766 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6767
6768 FRAME_SAMPLE_VISIBILITY (f);
6769 if (FRAME_VISIBLE_P (sf)
6770 && ! FRAME_VISIBLE_P (f))
6771 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6772
6773 if (m)
6774 {
6775 set_message (m, Qnil, nbytes, multibyte);
6776 if (minibuffer_auto_raise)
6777 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6778 }
6779 else
6780 clear_message (1, 1);
6781
6782 do_pending_window_change (0);
6783 echo_area_display (1);
6784 do_pending_window_change (0);
6785 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6786 (*frame_up_to_date_hook) (f);
6787 }
6788 }
6789
6790
6791 /* Display an echo area message M with a specified length of NBYTES
6792 bytes. The string may include null characters. If M is not a
6793 string, clear out any existing message, and let the mini-buffer
6794 text show through. */
6795
6796 void
6797 message3 (m, nbytes, multibyte)
6798 Lisp_Object m;
6799 int nbytes;
6800 int multibyte;
6801 {
6802 struct gcpro gcpro1;
6803
6804 GCPRO1 (m);
6805
6806 /* First flush out any partial line written with print. */
6807 message_log_maybe_newline ();
6808 if (STRINGP (m))
6809 message_dolog (SDATA (m), nbytes, 1, multibyte);
6810 message3_nolog (m, nbytes, multibyte);
6811
6812 UNGCPRO;
6813 }
6814
6815
6816 /* The non-logging version of message3. */
6817
6818 void
6819 message3_nolog (m, nbytes, multibyte)
6820 Lisp_Object m;
6821 int nbytes, multibyte;
6822 {
6823 struct frame *sf = SELECTED_FRAME ();
6824 message_enable_multibyte = multibyte;
6825
6826 if (noninteractive)
6827 {
6828 if (noninteractive_need_newline)
6829 putc ('\n', stderr);
6830 noninteractive_need_newline = 0;
6831 if (STRINGP (m))
6832 fwrite (SDATA (m), nbytes, 1, stderr);
6833 if (cursor_in_echo_area == 0)
6834 fprintf (stderr, "\n");
6835 fflush (stderr);
6836 }
6837 /* A null message buffer means that the frame hasn't really been
6838 initialized yet. Error messages get reported properly by
6839 cmd_error, so this must be just an informative message; toss it. */
6840 else if (INTERACTIVE
6841 && sf->glyphs_initialized_p
6842 && FRAME_MESSAGE_BUF (sf))
6843 {
6844 Lisp_Object mini_window;
6845 Lisp_Object frame;
6846 struct frame *f;
6847
6848 /* Get the frame containing the mini-buffer
6849 that the selected frame is using. */
6850 mini_window = FRAME_MINIBUF_WINDOW (sf);
6851 frame = XWINDOW (mini_window)->frame;
6852 f = XFRAME (frame);
6853
6854 FRAME_SAMPLE_VISIBILITY (f);
6855 if (FRAME_VISIBLE_P (sf)
6856 && !FRAME_VISIBLE_P (f))
6857 Fmake_frame_visible (frame);
6858
6859 if (STRINGP (m) && SCHARS (m) > 0)
6860 {
6861 set_message (NULL, m, nbytes, multibyte);
6862 if (minibuffer_auto_raise)
6863 Fraise_frame (frame);
6864 }
6865 else
6866 clear_message (1, 1);
6867
6868 do_pending_window_change (0);
6869 echo_area_display (1);
6870 do_pending_window_change (0);
6871 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6872 (*frame_up_to_date_hook) (f);
6873 }
6874 }
6875
6876
6877 /* Display a null-terminated echo area message M. If M is 0, clear
6878 out any existing message, and let the mini-buffer text show through.
6879
6880 The buffer M must continue to exist until after the echo area gets
6881 cleared or some other message gets displayed there. Do not pass
6882 text that is stored in a Lisp string. Do not pass text in a buffer
6883 that was alloca'd. */
6884
6885 void
6886 message1 (m)
6887 char *m;
6888 {
6889 message2 (m, (m ? strlen (m) : 0), 0);
6890 }
6891
6892
6893 /* The non-logging counterpart of message1. */
6894
6895 void
6896 message1_nolog (m)
6897 char *m;
6898 {
6899 message2_nolog (m, (m ? strlen (m) : 0), 0);
6900 }
6901
6902 /* Display a message M which contains a single %s
6903 which gets replaced with STRING. */
6904
6905 void
6906 message_with_string (m, string, log)
6907 char *m;
6908 Lisp_Object string;
6909 int log;
6910 {
6911 CHECK_STRING (string);
6912
6913 if (noninteractive)
6914 {
6915 if (m)
6916 {
6917 if (noninteractive_need_newline)
6918 putc ('\n', stderr);
6919 noninteractive_need_newline = 0;
6920 fprintf (stderr, m, SDATA (string));
6921 if (cursor_in_echo_area == 0)
6922 fprintf (stderr, "\n");
6923 fflush (stderr);
6924 }
6925 }
6926 else if (INTERACTIVE)
6927 {
6928 /* The frame whose minibuffer we're going to display the message on.
6929 It may be larger than the selected frame, so we need
6930 to use its buffer, not the selected frame's buffer. */
6931 Lisp_Object mini_window;
6932 struct frame *f, *sf = SELECTED_FRAME ();
6933
6934 /* Get the frame containing the minibuffer
6935 that the selected frame is using. */
6936 mini_window = FRAME_MINIBUF_WINDOW (sf);
6937 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6938
6939 /* A null message buffer means that the frame hasn't really been
6940 initialized yet. Error messages get reported properly by
6941 cmd_error, so this must be just an informative message; toss it. */
6942 if (FRAME_MESSAGE_BUF (f))
6943 {
6944 Lisp_Object args[2], message;
6945 struct gcpro gcpro1, gcpro2;
6946
6947 args[0] = build_string (m);
6948 args[1] = message = string;
6949 GCPRO2 (args[0], message);
6950 gcpro1.nvars = 2;
6951
6952 message = Fformat (2, args);
6953
6954 if (log)
6955 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6956 else
6957 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6958
6959 UNGCPRO;
6960
6961 /* Print should start at the beginning of the message
6962 buffer next time. */
6963 message_buf_print = 0;
6964 }
6965 }
6966 }
6967
6968
6969 /* Dump an informative message to the minibuf. If M is 0, clear out
6970 any existing message, and let the mini-buffer text show through. */
6971
6972 /* VARARGS 1 */
6973 void
6974 message (m, a1, a2, a3)
6975 char *m;
6976 EMACS_INT a1, a2, a3;
6977 {
6978 if (noninteractive)
6979 {
6980 if (m)
6981 {
6982 if (noninteractive_need_newline)
6983 putc ('\n', stderr);
6984 noninteractive_need_newline = 0;
6985 fprintf (stderr, m, a1, a2, a3);
6986 if (cursor_in_echo_area == 0)
6987 fprintf (stderr, "\n");
6988 fflush (stderr);
6989 }
6990 }
6991 else if (INTERACTIVE)
6992 {
6993 /* The frame whose mini-buffer we're going to display the message
6994 on. It may be larger than the selected frame, so we need to
6995 use its buffer, not the selected frame's buffer. */
6996 Lisp_Object mini_window;
6997 struct frame *f, *sf = SELECTED_FRAME ();
6998
6999 /* Get the frame containing the mini-buffer
7000 that the selected frame is using. */
7001 mini_window = FRAME_MINIBUF_WINDOW (sf);
7002 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7003
7004 /* A null message buffer means that the frame hasn't really been
7005 initialized yet. Error messages get reported properly by
7006 cmd_error, so this must be just an informative message; toss
7007 it. */
7008 if (FRAME_MESSAGE_BUF (f))
7009 {
7010 if (m)
7011 {
7012 int len;
7013 #ifdef NO_ARG_ARRAY
7014 char *a[3];
7015 a[0] = (char *) a1;
7016 a[1] = (char *) a2;
7017 a[2] = (char *) a3;
7018
7019 len = doprnt (FRAME_MESSAGE_BUF (f),
7020 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7021 #else
7022 len = doprnt (FRAME_MESSAGE_BUF (f),
7023 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7024 (char **) &a1);
7025 #endif /* NO_ARG_ARRAY */
7026
7027 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7028 }
7029 else
7030 message1 (0);
7031
7032 /* Print should start at the beginning of the message
7033 buffer next time. */
7034 message_buf_print = 0;
7035 }
7036 }
7037 }
7038
7039
7040 /* The non-logging version of message. */
7041
7042 void
7043 message_nolog (m, a1, a2, a3)
7044 char *m;
7045 EMACS_INT a1, a2, a3;
7046 {
7047 Lisp_Object old_log_max;
7048 old_log_max = Vmessage_log_max;
7049 Vmessage_log_max = Qnil;
7050 message (m, a1, a2, a3);
7051 Vmessage_log_max = old_log_max;
7052 }
7053
7054
7055 /* Display the current message in the current mini-buffer. This is
7056 only called from error handlers in process.c, and is not time
7057 critical. */
7058
7059 void
7060 update_echo_area ()
7061 {
7062 if (!NILP (echo_area_buffer[0]))
7063 {
7064 Lisp_Object string;
7065 string = Fcurrent_message ();
7066 message3 (string, SBYTES (string),
7067 !NILP (current_buffer->enable_multibyte_characters));
7068 }
7069 }
7070
7071
7072 /* Make sure echo area buffers in `echo_buffers' are live.
7073 If they aren't, make new ones. */
7074
7075 static void
7076 ensure_echo_area_buffers ()
7077 {
7078 int i;
7079
7080 for (i = 0; i < 2; ++i)
7081 if (!BUFFERP (echo_buffer[i])
7082 || NILP (XBUFFER (echo_buffer[i])->name))
7083 {
7084 char name[30];
7085 Lisp_Object old_buffer;
7086 int j;
7087
7088 old_buffer = echo_buffer[i];
7089 sprintf (name, " *Echo Area %d*", i);
7090 echo_buffer[i] = Fget_buffer_create (build_string (name));
7091 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7092
7093 for (j = 0; j < 2; ++j)
7094 if (EQ (old_buffer, echo_area_buffer[j]))
7095 echo_area_buffer[j] = echo_buffer[i];
7096 }
7097 }
7098
7099
7100 /* Call FN with args A1..A4 with either the current or last displayed
7101 echo_area_buffer as current buffer.
7102
7103 WHICH zero means use the current message buffer
7104 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7105 from echo_buffer[] and clear it.
7106
7107 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7108 suitable buffer from echo_buffer[] and clear it.
7109
7110 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7111 that the current message becomes the last displayed one, make
7112 choose a suitable buffer for echo_area_buffer[0], and clear it.
7113
7114 Value is what FN returns. */
7115
7116 static int
7117 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7118 struct window *w;
7119 int which;
7120 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7121 EMACS_INT a1;
7122 Lisp_Object a2;
7123 EMACS_INT a3, a4;
7124 {
7125 Lisp_Object buffer;
7126 int this_one, the_other, clear_buffer_p, rc;
7127 int count = SPECPDL_INDEX ();
7128
7129 /* If buffers aren't live, make new ones. */
7130 ensure_echo_area_buffers ();
7131
7132 clear_buffer_p = 0;
7133
7134 if (which == 0)
7135 this_one = 0, the_other = 1;
7136 else if (which > 0)
7137 this_one = 1, the_other = 0;
7138 else
7139 {
7140 this_one = 0, the_other = 1;
7141 clear_buffer_p = 1;
7142
7143 /* We need a fresh one in case the current echo buffer equals
7144 the one containing the last displayed echo area message. */
7145 if (!NILP (echo_area_buffer[this_one])
7146 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7147 echo_area_buffer[this_one] = Qnil;
7148 }
7149
7150 /* Choose a suitable buffer from echo_buffer[] is we don't
7151 have one. */
7152 if (NILP (echo_area_buffer[this_one]))
7153 {
7154 echo_area_buffer[this_one]
7155 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7156 ? echo_buffer[the_other]
7157 : echo_buffer[this_one]);
7158 clear_buffer_p = 1;
7159 }
7160
7161 buffer = echo_area_buffer[this_one];
7162
7163 /* Don't get confused by reusing the buffer used for echoing
7164 for a different purpose. */
7165 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7166 cancel_echoing ();
7167
7168 record_unwind_protect (unwind_with_echo_area_buffer,
7169 with_echo_area_buffer_unwind_data (w));
7170
7171 /* Make the echo area buffer current. Note that for display
7172 purposes, it is not necessary that the displayed window's buffer
7173 == current_buffer, except for text property lookup. So, let's
7174 only set that buffer temporarily here without doing a full
7175 Fset_window_buffer. We must also change w->pointm, though,
7176 because otherwise an assertions in unshow_buffer fails, and Emacs
7177 aborts. */
7178 set_buffer_internal_1 (XBUFFER (buffer));
7179 if (w)
7180 {
7181 w->buffer = buffer;
7182 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7183 }
7184
7185 current_buffer->undo_list = Qt;
7186 current_buffer->read_only = Qnil;
7187 specbind (Qinhibit_read_only, Qt);
7188 specbind (Qinhibit_modification_hooks, Qt);
7189
7190 if (clear_buffer_p && Z > BEG)
7191 del_range (BEG, Z);
7192
7193 xassert (BEGV >= BEG);
7194 xassert (ZV <= Z && ZV >= BEGV);
7195
7196 rc = fn (a1, a2, a3, a4);
7197
7198 xassert (BEGV >= BEG);
7199 xassert (ZV <= Z && ZV >= BEGV);
7200
7201 unbind_to (count, Qnil);
7202 return rc;
7203 }
7204
7205
7206 /* Save state that should be preserved around the call to the function
7207 FN called in with_echo_area_buffer. */
7208
7209 static Lisp_Object
7210 with_echo_area_buffer_unwind_data (w)
7211 struct window *w;
7212 {
7213 int i = 0;
7214 Lisp_Object vector;
7215
7216 /* Reduce consing by keeping one vector in
7217 Vwith_echo_area_save_vector. */
7218 vector = Vwith_echo_area_save_vector;
7219 Vwith_echo_area_save_vector = Qnil;
7220
7221 if (NILP (vector))
7222 vector = Fmake_vector (make_number (7), Qnil);
7223
7224 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7225 AREF (vector, i) = Vdeactivate_mark, ++i;
7226 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7227
7228 if (w)
7229 {
7230 XSETWINDOW (AREF (vector, i), w); ++i;
7231 AREF (vector, i) = w->buffer; ++i;
7232 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7233 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7234 }
7235 else
7236 {
7237 int end = i + 4;
7238 for (; i < end; ++i)
7239 AREF (vector, i) = Qnil;
7240 }
7241
7242 xassert (i == ASIZE (vector));
7243 return vector;
7244 }
7245
7246
7247 /* Restore global state from VECTOR which was created by
7248 with_echo_area_buffer_unwind_data. */
7249
7250 static Lisp_Object
7251 unwind_with_echo_area_buffer (vector)
7252 Lisp_Object vector;
7253 {
7254 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7255 Vdeactivate_mark = AREF (vector, 1);
7256 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7257
7258 if (WINDOWP (AREF (vector, 3)))
7259 {
7260 struct window *w;
7261 Lisp_Object buffer, charpos, bytepos;
7262
7263 w = XWINDOW (AREF (vector, 3));
7264 buffer = AREF (vector, 4);
7265 charpos = AREF (vector, 5);
7266 bytepos = AREF (vector, 6);
7267
7268 w->buffer = buffer;
7269 set_marker_both (w->pointm, buffer,
7270 XFASTINT (charpos), XFASTINT (bytepos));
7271 }
7272
7273 Vwith_echo_area_save_vector = vector;
7274 return Qnil;
7275 }
7276
7277
7278 /* Set up the echo area for use by print functions. MULTIBYTE_P
7279 non-zero means we will print multibyte. */
7280
7281 void
7282 setup_echo_area_for_printing (multibyte_p)
7283 int multibyte_p;
7284 {
7285 /* If we can't find an echo area any more, exit. */
7286 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7287 Fkill_emacs (Qnil);
7288
7289 ensure_echo_area_buffers ();
7290
7291 if (!message_buf_print)
7292 {
7293 /* A message has been output since the last time we printed.
7294 Choose a fresh echo area buffer. */
7295 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7296 echo_area_buffer[0] = echo_buffer[1];
7297 else
7298 echo_area_buffer[0] = echo_buffer[0];
7299
7300 /* Switch to that buffer and clear it. */
7301 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7302 current_buffer->truncate_lines = Qnil;
7303
7304 if (Z > BEG)
7305 {
7306 int count = SPECPDL_INDEX ();
7307 specbind (Qinhibit_read_only, Qt);
7308 /* Note that undo recording is always disabled. */
7309 del_range (BEG, Z);
7310 unbind_to (count, Qnil);
7311 }
7312 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7313
7314 /* Set up the buffer for the multibyteness we need. */
7315 if (multibyte_p
7316 != !NILP (current_buffer->enable_multibyte_characters))
7317 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7318
7319 /* Raise the frame containing the echo area. */
7320 if (minibuffer_auto_raise)
7321 {
7322 struct frame *sf = SELECTED_FRAME ();
7323 Lisp_Object mini_window;
7324 mini_window = FRAME_MINIBUF_WINDOW (sf);
7325 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7326 }
7327
7328 message_log_maybe_newline ();
7329 message_buf_print = 1;
7330 }
7331 else
7332 {
7333 if (NILP (echo_area_buffer[0]))
7334 {
7335 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7336 echo_area_buffer[0] = echo_buffer[1];
7337 else
7338 echo_area_buffer[0] = echo_buffer[0];
7339 }
7340
7341 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7342 {
7343 /* Someone switched buffers between print requests. */
7344 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7345 current_buffer->truncate_lines = Qnil;
7346 }
7347 }
7348 }
7349
7350
7351 /* Display an echo area message in window W. Value is non-zero if W's
7352 height is changed. If display_last_displayed_message_p is
7353 non-zero, display the message that was last displayed, otherwise
7354 display the current message. */
7355
7356 static int
7357 display_echo_area (w)
7358 struct window *w;
7359 {
7360 int i, no_message_p, window_height_changed_p, count;
7361
7362 /* Temporarily disable garbage collections while displaying the echo
7363 area. This is done because a GC can print a message itself.
7364 That message would modify the echo area buffer's contents while a
7365 redisplay of the buffer is going on, and seriously confuse
7366 redisplay. */
7367 count = inhibit_garbage_collection ();
7368
7369 /* If there is no message, we must call display_echo_area_1
7370 nevertheless because it resizes the window. But we will have to
7371 reset the echo_area_buffer in question to nil at the end because
7372 with_echo_area_buffer will sets it to an empty buffer. */
7373 i = display_last_displayed_message_p ? 1 : 0;
7374 no_message_p = NILP (echo_area_buffer[i]);
7375
7376 window_height_changed_p
7377 = with_echo_area_buffer (w, display_last_displayed_message_p,
7378 display_echo_area_1,
7379 (EMACS_INT) w, Qnil, 0, 0);
7380
7381 if (no_message_p)
7382 echo_area_buffer[i] = Qnil;
7383
7384 unbind_to (count, Qnil);
7385 return window_height_changed_p;
7386 }
7387
7388
7389 /* Helper for display_echo_area. Display the current buffer which
7390 contains the current echo area message in window W, a mini-window,
7391 a pointer to which is passed in A1. A2..A4 are currently not used.
7392 Change the height of W so that all of the message is displayed.
7393 Value is non-zero if height of W was changed. */
7394
7395 static int
7396 display_echo_area_1 (a1, a2, a3, a4)
7397 EMACS_INT a1;
7398 Lisp_Object a2;
7399 EMACS_INT a3, a4;
7400 {
7401 struct window *w = (struct window *) a1;
7402 Lisp_Object window;
7403 struct text_pos start;
7404 int window_height_changed_p = 0;
7405
7406 /* Do this before displaying, so that we have a large enough glyph
7407 matrix for the display. */
7408 window_height_changed_p = resize_mini_window (w, 0);
7409
7410 /* Display. */
7411 clear_glyph_matrix (w->desired_matrix);
7412 XSETWINDOW (window, w);
7413 SET_TEXT_POS (start, BEG, BEG_BYTE);
7414 try_window (window, start);
7415
7416 return window_height_changed_p;
7417 }
7418
7419
7420 /* Resize the echo area window to exactly the size needed for the
7421 currently displayed message, if there is one. If a mini-buffer
7422 is active, don't shrink it. */
7423
7424 void
7425 resize_echo_area_exactly ()
7426 {
7427 if (BUFFERP (echo_area_buffer[0])
7428 && WINDOWP (echo_area_window))
7429 {
7430 struct window *w = XWINDOW (echo_area_window);
7431 int resized_p;
7432 Lisp_Object resize_exactly;
7433
7434 if (minibuf_level == 0)
7435 resize_exactly = Qt;
7436 else
7437 resize_exactly = Qnil;
7438
7439 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7440 (EMACS_INT) w, resize_exactly, 0, 0);
7441 if (resized_p)
7442 {
7443 ++windows_or_buffers_changed;
7444 ++update_mode_lines;
7445 redisplay_internal (0);
7446 }
7447 }
7448 }
7449
7450
7451 /* Callback function for with_echo_area_buffer, when used from
7452 resize_echo_area_exactly. A1 contains a pointer to the window to
7453 resize, EXACTLY non-nil means resize the mini-window exactly to the
7454 size of the text displayed. A3 and A4 are not used. Value is what
7455 resize_mini_window returns. */
7456
7457 static int
7458 resize_mini_window_1 (a1, exactly, a3, a4)
7459 EMACS_INT a1;
7460 Lisp_Object exactly;
7461 EMACS_INT a3, a4;
7462 {
7463 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7464 }
7465
7466
7467 /* Resize mini-window W to fit the size of its contents. EXACT:P
7468 means size the window exactly to the size needed. Otherwise, it's
7469 only enlarged until W's buffer is empty. Value is non-zero if
7470 the window height has been changed. */
7471
7472 int
7473 resize_mini_window (w, exact_p)
7474 struct window *w;
7475 int exact_p;
7476 {
7477 struct frame *f = XFRAME (w->frame);
7478 int window_height_changed_p = 0;
7479
7480 xassert (MINI_WINDOW_P (w));
7481
7482 /* Don't resize windows while redisplaying a window; it would
7483 confuse redisplay functions when the size of the window they are
7484 displaying changes from under them. Such a resizing can happen,
7485 for instance, when which-func prints a long message while
7486 we are running fontification-functions. We're running these
7487 functions with safe_call which binds inhibit-redisplay to t. */
7488 if (!NILP (Vinhibit_redisplay))
7489 return 0;
7490
7491 /* Nil means don't try to resize. */
7492 if (NILP (Vresize_mini_windows)
7493 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7494 return 0;
7495
7496 if (!FRAME_MINIBUF_ONLY_P (f))
7497 {
7498 struct it it;
7499 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7500 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7501 int height, max_height;
7502 int unit = FRAME_LINE_HEIGHT (f);
7503 struct text_pos start;
7504 struct buffer *old_current_buffer = NULL;
7505
7506 if (current_buffer != XBUFFER (w->buffer))
7507 {
7508 old_current_buffer = current_buffer;
7509 set_buffer_internal (XBUFFER (w->buffer));
7510 }
7511
7512 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7513
7514 /* Compute the max. number of lines specified by the user. */
7515 if (FLOATP (Vmax_mini_window_height))
7516 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7517 else if (INTEGERP (Vmax_mini_window_height))
7518 max_height = XINT (Vmax_mini_window_height);
7519 else
7520 max_height = total_height / 4;
7521
7522 /* Correct that max. height if it's bogus. */
7523 max_height = max (1, max_height);
7524 max_height = min (total_height, max_height);
7525
7526 /* Find out the height of the text in the window. */
7527 if (it.truncate_lines_p)
7528 height = 1;
7529 else
7530 {
7531 last_height = 0;
7532 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7533 if (it.max_ascent == 0 && it.max_descent == 0)
7534 height = it.current_y + last_height;
7535 else
7536 height = it.current_y + it.max_ascent + it.max_descent;
7537 height -= it.extra_line_spacing;
7538 height = (height + unit - 1) / unit;
7539 }
7540
7541 /* Compute a suitable window start. */
7542 if (height > max_height)
7543 {
7544 height = max_height;
7545 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7546 move_it_vertically_backward (&it, (height - 1) * unit);
7547 start = it.current.pos;
7548 }
7549 else
7550 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7551 SET_MARKER_FROM_TEXT_POS (w->start, start);
7552
7553 if (EQ (Vresize_mini_windows, Qgrow_only))
7554 {
7555 /* Let it grow only, until we display an empty message, in which
7556 case the window shrinks again. */
7557 if (height > WINDOW_TOTAL_LINES (w))
7558 {
7559 int old_height = WINDOW_TOTAL_LINES (w);
7560 freeze_window_starts (f, 1);
7561 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7562 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7563 }
7564 else if (height < WINDOW_TOTAL_LINES (w)
7565 && (exact_p || BEGV == ZV))
7566 {
7567 int old_height = WINDOW_TOTAL_LINES (w);
7568 freeze_window_starts (f, 0);
7569 shrink_mini_window (w);
7570 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7571 }
7572 }
7573 else
7574 {
7575 /* Always resize to exact size needed. */
7576 if (height > WINDOW_TOTAL_LINES (w))
7577 {
7578 int old_height = WINDOW_TOTAL_LINES (w);
7579 freeze_window_starts (f, 1);
7580 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7581 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7582 }
7583 else if (height < WINDOW_TOTAL_LINES (w))
7584 {
7585 int old_height = WINDOW_TOTAL_LINES (w);
7586 freeze_window_starts (f, 0);
7587 shrink_mini_window (w);
7588
7589 if (height)
7590 {
7591 freeze_window_starts (f, 1);
7592 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7593 }
7594
7595 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7596 }
7597 }
7598
7599 if (old_current_buffer)
7600 set_buffer_internal (old_current_buffer);
7601 }
7602
7603 return window_height_changed_p;
7604 }
7605
7606
7607 /* Value is the current message, a string, or nil if there is no
7608 current message. */
7609
7610 Lisp_Object
7611 current_message ()
7612 {
7613 Lisp_Object msg;
7614
7615 if (NILP (echo_area_buffer[0]))
7616 msg = Qnil;
7617 else
7618 {
7619 with_echo_area_buffer (0, 0, current_message_1,
7620 (EMACS_INT) &msg, Qnil, 0, 0);
7621 if (NILP (msg))
7622 echo_area_buffer[0] = Qnil;
7623 }
7624
7625 return msg;
7626 }
7627
7628
7629 static int
7630 current_message_1 (a1, a2, a3, a4)
7631 EMACS_INT a1;
7632 Lisp_Object a2;
7633 EMACS_INT a3, a4;
7634 {
7635 Lisp_Object *msg = (Lisp_Object *) a1;
7636
7637 if (Z > BEG)
7638 *msg = make_buffer_string (BEG, Z, 1);
7639 else
7640 *msg = Qnil;
7641 return 0;
7642 }
7643
7644
7645 /* Push the current message on Vmessage_stack for later restauration
7646 by restore_message. Value is non-zero if the current message isn't
7647 empty. This is a relatively infrequent operation, so it's not
7648 worth optimizing. */
7649
7650 int
7651 push_message ()
7652 {
7653 Lisp_Object msg;
7654 msg = current_message ();
7655 Vmessage_stack = Fcons (msg, Vmessage_stack);
7656 return STRINGP (msg);
7657 }
7658
7659
7660 /* Restore message display from the top of Vmessage_stack. */
7661
7662 void
7663 restore_message ()
7664 {
7665 Lisp_Object msg;
7666
7667 xassert (CONSP (Vmessage_stack));
7668 msg = XCAR (Vmessage_stack);
7669 if (STRINGP (msg))
7670 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7671 else
7672 message3_nolog (msg, 0, 0);
7673 }
7674
7675
7676 /* Handler for record_unwind_protect calling pop_message. */
7677
7678 Lisp_Object
7679 pop_message_unwind (dummy)
7680 Lisp_Object dummy;
7681 {
7682 pop_message ();
7683 return Qnil;
7684 }
7685
7686 /* Pop the top-most entry off Vmessage_stack. */
7687
7688 void
7689 pop_message ()
7690 {
7691 xassert (CONSP (Vmessage_stack));
7692 Vmessage_stack = XCDR (Vmessage_stack);
7693 }
7694
7695
7696 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7697 exits. If the stack is not empty, we have a missing pop_message
7698 somewhere. */
7699
7700 void
7701 check_message_stack ()
7702 {
7703 if (!NILP (Vmessage_stack))
7704 abort ();
7705 }
7706
7707
7708 /* Truncate to NCHARS what will be displayed in the echo area the next
7709 time we display it---but don't redisplay it now. */
7710
7711 void
7712 truncate_echo_area (nchars)
7713 int nchars;
7714 {
7715 if (nchars == 0)
7716 echo_area_buffer[0] = Qnil;
7717 /* A null message buffer means that the frame hasn't really been
7718 initialized yet. Error messages get reported properly by
7719 cmd_error, so this must be just an informative message; toss it. */
7720 else if (!noninteractive
7721 && INTERACTIVE
7722 && !NILP (echo_area_buffer[0]))
7723 {
7724 struct frame *sf = SELECTED_FRAME ();
7725 if (FRAME_MESSAGE_BUF (sf))
7726 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7727 }
7728 }
7729
7730
7731 /* Helper function for truncate_echo_area. Truncate the current
7732 message to at most NCHARS characters. */
7733
7734 static int
7735 truncate_message_1 (nchars, a2, a3, a4)
7736 EMACS_INT nchars;
7737 Lisp_Object a2;
7738 EMACS_INT a3, a4;
7739 {
7740 if (BEG + nchars < Z)
7741 del_range (BEG + nchars, Z);
7742 if (Z == BEG)
7743 echo_area_buffer[0] = Qnil;
7744 return 0;
7745 }
7746
7747
7748 /* Set the current message to a substring of S or STRING.
7749
7750 If STRING is a Lisp string, set the message to the first NBYTES
7751 bytes from STRING. NBYTES zero means use the whole string. If
7752 STRING is multibyte, the message will be displayed multibyte.
7753
7754 If S is not null, set the message to the first LEN bytes of S. LEN
7755 zero means use the whole string. MULTIBYTE_P non-zero means S is
7756 multibyte. Display the message multibyte in that case. */
7757
7758 void
7759 set_message (s, string, nbytes, multibyte_p)
7760 const char *s;
7761 Lisp_Object string;
7762 int nbytes, multibyte_p;
7763 {
7764 message_enable_multibyte
7765 = ((s && multibyte_p)
7766 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7767
7768 with_echo_area_buffer (0, -1, set_message_1,
7769 (EMACS_INT) s, string, nbytes, multibyte_p);
7770 message_buf_print = 0;
7771 help_echo_showing_p = 0;
7772 }
7773
7774
7775 /* Helper function for set_message. Arguments have the same meaning
7776 as there, with A1 corresponding to S and A2 corresponding to STRING
7777 This function is called with the echo area buffer being
7778 current. */
7779
7780 static int
7781 set_message_1 (a1, a2, nbytes, multibyte_p)
7782 EMACS_INT a1;
7783 Lisp_Object a2;
7784 EMACS_INT nbytes, multibyte_p;
7785 {
7786 const char *s = (const char *) a1;
7787 Lisp_Object string = a2;
7788
7789 xassert (BEG == Z);
7790
7791 /* Change multibyteness of the echo buffer appropriately. */
7792 if (message_enable_multibyte
7793 != !NILP (current_buffer->enable_multibyte_characters))
7794 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7795
7796 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7797
7798 /* Insert new message at BEG. */
7799 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7800
7801 if (STRINGP (string))
7802 {
7803 int nchars;
7804
7805 if (nbytes == 0)
7806 nbytes = SBYTES (string);
7807 nchars = string_byte_to_char (string, nbytes);
7808
7809 /* This function takes care of single/multibyte conversion. We
7810 just have to ensure that the echo area buffer has the right
7811 setting of enable_multibyte_characters. */
7812 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7813 }
7814 else if (s)
7815 {
7816 if (nbytes == 0)
7817 nbytes = strlen (s);
7818
7819 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7820 {
7821 /* Convert from multi-byte to single-byte. */
7822 int i, c, n;
7823 unsigned char work[1];
7824
7825 /* Convert a multibyte string to single-byte. */
7826 for (i = 0; i < nbytes; i += n)
7827 {
7828 c = string_char_and_length (s + i, nbytes - i, &n);
7829 work[0] = (ASCII_CHAR_P (c)
7830 ? c
7831 : multibyte_char_to_unibyte (c, Qnil));
7832 insert_1_both (work, 1, 1, 1, 0, 0);
7833 }
7834 }
7835 else if (!multibyte_p
7836 && !NILP (current_buffer->enable_multibyte_characters))
7837 {
7838 /* Convert from single-byte to multi-byte. */
7839 int i, c, n;
7840 const unsigned char *msg = (const unsigned char *) s;
7841 unsigned char str[MAX_MULTIBYTE_LENGTH];
7842
7843 /* Convert a single-byte string to multibyte. */
7844 for (i = 0; i < nbytes; i++)
7845 {
7846 c = msg[i];
7847 c = unibyte_char_to_multibyte (c);
7848 n = CHAR_STRING (c, str);
7849 insert_1_both (str, 1, n, 1, 0, 0);
7850 }
7851 }
7852 else
7853 insert_1 (s, nbytes, 1, 0, 0);
7854 }
7855
7856 return 0;
7857 }
7858
7859
7860 /* Clear messages. CURRENT_P non-zero means clear the current
7861 message. LAST_DISPLAYED_P non-zero means clear the message
7862 last displayed. */
7863
7864 void
7865 clear_message (current_p, last_displayed_p)
7866 int current_p, last_displayed_p;
7867 {
7868 if (current_p)
7869 {
7870 echo_area_buffer[0] = Qnil;
7871 message_cleared_p = 1;
7872 }
7873
7874 if (last_displayed_p)
7875 echo_area_buffer[1] = Qnil;
7876
7877 message_buf_print = 0;
7878 }
7879
7880 /* Clear garbaged frames.
7881
7882 This function is used where the old redisplay called
7883 redraw_garbaged_frames which in turn called redraw_frame which in
7884 turn called clear_frame. The call to clear_frame was a source of
7885 flickering. I believe a clear_frame is not necessary. It should
7886 suffice in the new redisplay to invalidate all current matrices,
7887 and ensure a complete redisplay of all windows. */
7888
7889 static void
7890 clear_garbaged_frames ()
7891 {
7892 if (frame_garbaged)
7893 {
7894 Lisp_Object tail, frame;
7895 int changed_count = 0;
7896
7897 FOR_EACH_FRAME (tail, frame)
7898 {
7899 struct frame *f = XFRAME (frame);
7900
7901 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7902 {
7903 if (f->resized_p)
7904 {
7905 Fredraw_frame (frame);
7906 f->force_flush_display_p = 1;
7907 }
7908 clear_current_matrices (f);
7909 changed_count++;
7910 f->garbaged = 0;
7911 f->resized_p = 0;
7912 }
7913 }
7914
7915 frame_garbaged = 0;
7916 if (changed_count)
7917 ++windows_or_buffers_changed;
7918 }
7919 }
7920
7921
7922 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7923 is non-zero update selected_frame. Value is non-zero if the
7924 mini-windows height has been changed. */
7925
7926 static int
7927 echo_area_display (update_frame_p)
7928 int update_frame_p;
7929 {
7930 Lisp_Object mini_window;
7931 struct window *w;
7932 struct frame *f;
7933 int window_height_changed_p = 0;
7934 struct frame *sf = SELECTED_FRAME ();
7935
7936 mini_window = FRAME_MINIBUF_WINDOW (sf);
7937 w = XWINDOW (mini_window);
7938 f = XFRAME (WINDOW_FRAME (w));
7939
7940 /* Don't display if frame is invisible or not yet initialized. */
7941 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7942 return 0;
7943
7944 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7945 #ifndef MAC_OS8
7946 #ifdef HAVE_WINDOW_SYSTEM
7947 /* When Emacs starts, selected_frame may be a visible terminal
7948 frame, even if we run under a window system. If we let this
7949 through, a message would be displayed on the terminal. */
7950 if (EQ (selected_frame, Vterminal_frame)
7951 && !NILP (Vwindow_system))
7952 return 0;
7953 #endif /* HAVE_WINDOW_SYSTEM */
7954 #endif
7955
7956 /* Redraw garbaged frames. */
7957 if (frame_garbaged)
7958 clear_garbaged_frames ();
7959
7960 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7961 {
7962 echo_area_window = mini_window;
7963 window_height_changed_p = display_echo_area (w);
7964 w->must_be_updated_p = 1;
7965
7966 /* Update the display, unless called from redisplay_internal.
7967 Also don't update the screen during redisplay itself. The
7968 update will happen at the end of redisplay, and an update
7969 here could cause confusion. */
7970 if (update_frame_p && !redisplaying_p)
7971 {
7972 int n = 0;
7973
7974 /* If the display update has been interrupted by pending
7975 input, update mode lines in the frame. Due to the
7976 pending input, it might have been that redisplay hasn't
7977 been called, so that mode lines above the echo area are
7978 garbaged. This looks odd, so we prevent it here. */
7979 if (!display_completed)
7980 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7981
7982 if (window_height_changed_p
7983 /* Don't do this if Emacs is shutting down. Redisplay
7984 needs to run hooks. */
7985 && !NILP (Vrun_hooks))
7986 {
7987 /* Must update other windows. Likewise as in other
7988 cases, don't let this update be interrupted by
7989 pending input. */
7990 int count = SPECPDL_INDEX ();
7991 specbind (Qredisplay_dont_pause, Qt);
7992 windows_or_buffers_changed = 1;
7993 redisplay_internal (0);
7994 unbind_to (count, Qnil);
7995 }
7996 else if (FRAME_WINDOW_P (f) && n == 0)
7997 {
7998 /* Window configuration is the same as before.
7999 Can do with a display update of the echo area,
8000 unless we displayed some mode lines. */
8001 update_single_window (w, 1);
8002 rif->flush_display (f);
8003 }
8004 else
8005 update_frame (f, 1, 1);
8006
8007 /* If cursor is in the echo area, make sure that the next
8008 redisplay displays the minibuffer, so that the cursor will
8009 be replaced with what the minibuffer wants. */
8010 if (cursor_in_echo_area)
8011 ++windows_or_buffers_changed;
8012 }
8013 }
8014 else if (!EQ (mini_window, selected_window))
8015 windows_or_buffers_changed++;
8016
8017 /* Last displayed message is now the current message. */
8018 echo_area_buffer[1] = echo_area_buffer[0];
8019
8020 /* Prevent redisplay optimization in redisplay_internal by resetting
8021 this_line_start_pos. This is done because the mini-buffer now
8022 displays the message instead of its buffer text. */
8023 if (EQ (mini_window, selected_window))
8024 CHARPOS (this_line_start_pos) = 0;
8025
8026 return window_height_changed_p;
8027 }
8028
8029
8030 \f
8031 /***********************************************************************
8032 Frame Titles
8033 ***********************************************************************/
8034
8035
8036 /* The frame title buffering code is also used by Fformat_mode_line.
8037 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
8038
8039 /* A buffer for constructing frame titles in it; allocated from the
8040 heap in init_xdisp and resized as needed in store_frame_title_char. */
8041
8042 static char *frame_title_buf;
8043
8044 /* The buffer's end, and a current output position in it. */
8045
8046 static char *frame_title_buf_end;
8047 static char *frame_title_ptr;
8048
8049
8050 /* Store a single character C for the frame title in frame_title_buf.
8051 Re-allocate frame_title_buf if necessary. */
8052
8053 static void
8054 #ifdef PROTOTYPES
8055 store_frame_title_char (char c)
8056 #else
8057 store_frame_title_char (c)
8058 char c;
8059 #endif
8060 {
8061 /* If output position has reached the end of the allocated buffer,
8062 double the buffer's size. */
8063 if (frame_title_ptr == frame_title_buf_end)
8064 {
8065 int len = frame_title_ptr - frame_title_buf;
8066 int new_size = 2 * len * sizeof *frame_title_buf;
8067 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
8068 frame_title_buf_end = frame_title_buf + new_size;
8069 frame_title_ptr = frame_title_buf + len;
8070 }
8071
8072 *frame_title_ptr++ = c;
8073 }
8074
8075
8076 /* Store part of a frame title in frame_title_buf, beginning at
8077 frame_title_ptr. STR is the string to store. Do not copy
8078 characters that yield more columns than PRECISION; PRECISION <= 0
8079 means copy the whole string. Pad with spaces until FIELD_WIDTH
8080 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8081 pad. Called from display_mode_element when it is used to build a
8082 frame title. */
8083
8084 static int
8085 store_frame_title (str, field_width, precision)
8086 const unsigned char *str;
8087 int field_width, precision;
8088 {
8089 int n = 0;
8090 int dummy, nbytes;
8091
8092 /* Copy at most PRECISION chars from STR. */
8093 nbytes = strlen (str);
8094 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8095 while (nbytes--)
8096 store_frame_title_char (*str++);
8097
8098 /* Fill up with spaces until FIELD_WIDTH reached. */
8099 while (field_width > 0
8100 && n < field_width)
8101 {
8102 store_frame_title_char (' ');
8103 ++n;
8104 }
8105
8106 return n;
8107 }
8108
8109 #ifdef HAVE_WINDOW_SYSTEM
8110
8111 /* Set the title of FRAME, if it has changed. The title format is
8112 Vicon_title_format if FRAME is iconified, otherwise it is
8113 frame_title_format. */
8114
8115 static void
8116 x_consider_frame_title (frame)
8117 Lisp_Object frame;
8118 {
8119 struct frame *f = XFRAME (frame);
8120
8121 if (FRAME_WINDOW_P (f)
8122 || FRAME_MINIBUF_ONLY_P (f)
8123 || f->explicit_name)
8124 {
8125 /* Do we have more than one visible frame on this X display? */
8126 Lisp_Object tail;
8127 Lisp_Object fmt;
8128 struct buffer *obuf;
8129 int len;
8130 struct it it;
8131
8132 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8133 {
8134 Lisp_Object other_frame = XCAR (tail);
8135 struct frame *tf = XFRAME (other_frame);
8136
8137 if (tf != f
8138 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8139 && !FRAME_MINIBUF_ONLY_P (tf)
8140 && !EQ (other_frame, tip_frame)
8141 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8142 break;
8143 }
8144
8145 /* Set global variable indicating that multiple frames exist. */
8146 multiple_frames = CONSP (tail);
8147
8148 /* Switch to the buffer of selected window of the frame. Set up
8149 frame_title_ptr so that display_mode_element will output into it;
8150 then display the title. */
8151 obuf = current_buffer;
8152 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8153 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8154 frame_title_ptr = frame_title_buf;
8155 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8156 NULL, DEFAULT_FACE_ID);
8157 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8158 len = frame_title_ptr - frame_title_buf;
8159 frame_title_ptr = NULL;
8160 set_buffer_internal_1 (obuf);
8161
8162 /* Set the title only if it's changed. This avoids consing in
8163 the common case where it hasn't. (If it turns out that we've
8164 already wasted too much time by walking through the list with
8165 display_mode_element, then we might need to optimize at a
8166 higher level than this.) */
8167 if (! STRINGP (f->name)
8168 || SBYTES (f->name) != len
8169 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8170 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8171 }
8172 }
8173
8174 #endif /* not HAVE_WINDOW_SYSTEM */
8175
8176
8177
8178 \f
8179 /***********************************************************************
8180 Menu Bars
8181 ***********************************************************************/
8182
8183
8184 /* Prepare for redisplay by updating menu-bar item lists when
8185 appropriate. This can call eval. */
8186
8187 void
8188 prepare_menu_bars ()
8189 {
8190 int all_windows;
8191 struct gcpro gcpro1, gcpro2;
8192 struct frame *f;
8193 Lisp_Object tooltip_frame;
8194
8195 #ifdef HAVE_WINDOW_SYSTEM
8196 tooltip_frame = tip_frame;
8197 #else
8198 tooltip_frame = Qnil;
8199 #endif
8200
8201 /* Update all frame titles based on their buffer names, etc. We do
8202 this before the menu bars so that the buffer-menu will show the
8203 up-to-date frame titles. */
8204 #ifdef HAVE_WINDOW_SYSTEM
8205 if (windows_or_buffers_changed || update_mode_lines)
8206 {
8207 Lisp_Object tail, frame;
8208
8209 FOR_EACH_FRAME (tail, frame)
8210 {
8211 f = XFRAME (frame);
8212 if (!EQ (frame, tooltip_frame)
8213 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8214 x_consider_frame_title (frame);
8215 }
8216 }
8217 #endif /* HAVE_WINDOW_SYSTEM */
8218
8219 /* Update the menu bar item lists, if appropriate. This has to be
8220 done before any actual redisplay or generation of display lines. */
8221 all_windows = (update_mode_lines
8222 || buffer_shared > 1
8223 || windows_or_buffers_changed);
8224 if (all_windows)
8225 {
8226 Lisp_Object tail, frame;
8227 int count = SPECPDL_INDEX ();
8228
8229 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8230
8231 FOR_EACH_FRAME (tail, frame)
8232 {
8233 f = XFRAME (frame);
8234
8235 /* Ignore tooltip frame. */
8236 if (EQ (frame, tooltip_frame))
8237 continue;
8238
8239 /* If a window on this frame changed size, report that to
8240 the user and clear the size-change flag. */
8241 if (FRAME_WINDOW_SIZES_CHANGED (f))
8242 {
8243 Lisp_Object functions;
8244
8245 /* Clear flag first in case we get an error below. */
8246 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8247 functions = Vwindow_size_change_functions;
8248 GCPRO2 (tail, functions);
8249
8250 while (CONSP (functions))
8251 {
8252 call1 (XCAR (functions), frame);
8253 functions = XCDR (functions);
8254 }
8255 UNGCPRO;
8256 }
8257
8258 GCPRO1 (tail);
8259 update_menu_bar (f, 0);
8260 #ifdef HAVE_WINDOW_SYSTEM
8261 update_tool_bar (f, 0);
8262 #endif
8263 UNGCPRO;
8264 }
8265
8266 unbind_to (count, Qnil);
8267 }
8268 else
8269 {
8270 struct frame *sf = SELECTED_FRAME ();
8271 update_menu_bar (sf, 1);
8272 #ifdef HAVE_WINDOW_SYSTEM
8273 update_tool_bar (sf, 1);
8274 #endif
8275 }
8276
8277 /* Motif needs this. See comment in xmenu.c. Turn it off when
8278 pending_menu_activation is not defined. */
8279 #ifdef USE_X_TOOLKIT
8280 pending_menu_activation = 0;
8281 #endif
8282 }
8283
8284
8285 /* Update the menu bar item list for frame F. This has to be done
8286 before we start to fill in any display lines, because it can call
8287 eval.
8288
8289 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8290
8291 static void
8292 update_menu_bar (f, save_match_data)
8293 struct frame *f;
8294 int save_match_data;
8295 {
8296 Lisp_Object window;
8297 register struct window *w;
8298
8299 /* If called recursively during a menu update, do nothing. This can
8300 happen when, for instance, an activate-menubar-hook causes a
8301 redisplay. */
8302 if (inhibit_menubar_update)
8303 return;
8304
8305 window = FRAME_SELECTED_WINDOW (f);
8306 w = XWINDOW (window);
8307
8308 #if 0 /* The if statement below this if statement used to include the
8309 condition !NILP (w->update_mode_line), rather than using
8310 update_mode_lines directly, and this if statement may have
8311 been added to make that condition work. Now the if
8312 statement below matches its comment, this isn't needed. */
8313 if (update_mode_lines)
8314 w->update_mode_line = Qt;
8315 #endif
8316
8317 if (FRAME_WINDOW_P (f)
8318 ?
8319 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8320 || defined (USE_GTK)
8321 FRAME_EXTERNAL_MENU_BAR (f)
8322 #else
8323 FRAME_MENU_BAR_LINES (f) > 0
8324 #endif
8325 : FRAME_MENU_BAR_LINES (f) > 0)
8326 {
8327 /* If the user has switched buffers or windows, we need to
8328 recompute to reflect the new bindings. But we'll
8329 recompute when update_mode_lines is set too; that means
8330 that people can use force-mode-line-update to request
8331 that the menu bar be recomputed. The adverse effect on
8332 the rest of the redisplay algorithm is about the same as
8333 windows_or_buffers_changed anyway. */
8334 if (windows_or_buffers_changed
8335 /* This used to test w->update_mode_line, but we believe
8336 there is no need to recompute the menu in that case. */
8337 || update_mode_lines
8338 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8339 < BUF_MODIFF (XBUFFER (w->buffer)))
8340 != !NILP (w->last_had_star))
8341 || ((!NILP (Vtransient_mark_mode)
8342 && !NILP (XBUFFER (w->buffer)->mark_active))
8343 != !NILP (w->region_showing)))
8344 {
8345 struct buffer *prev = current_buffer;
8346 int count = SPECPDL_INDEX ();
8347
8348 specbind (Qinhibit_menubar_update, Qt);
8349
8350 set_buffer_internal_1 (XBUFFER (w->buffer));
8351 if (save_match_data)
8352 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8353 if (NILP (Voverriding_local_map_menu_flag))
8354 {
8355 specbind (Qoverriding_terminal_local_map, Qnil);
8356 specbind (Qoverriding_local_map, Qnil);
8357 }
8358
8359 /* Run the Lucid hook. */
8360 safe_run_hooks (Qactivate_menubar_hook);
8361
8362 /* If it has changed current-menubar from previous value,
8363 really recompute the menu-bar from the value. */
8364 if (! NILP (Vlucid_menu_bar_dirty_flag))
8365 call0 (Qrecompute_lucid_menubar);
8366
8367 safe_run_hooks (Qmenu_bar_update_hook);
8368 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8369
8370 /* Redisplay the menu bar in case we changed it. */
8371 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8372 || defined (USE_GTK)
8373 if (FRAME_WINDOW_P (f)
8374 #if defined (MAC_OS)
8375 /* All frames on Mac OS share the same menubar. So only the
8376 selected frame should be allowed to set it. */
8377 && f == SELECTED_FRAME ()
8378 #endif
8379 )
8380 set_frame_menubar (f, 0, 0);
8381 else
8382 /* On a terminal screen, the menu bar is an ordinary screen
8383 line, and this makes it get updated. */
8384 w->update_mode_line = Qt;
8385 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8386 /* In the non-toolkit version, the menu bar is an ordinary screen
8387 line, and this makes it get updated. */
8388 w->update_mode_line = Qt;
8389 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8390
8391 unbind_to (count, Qnil);
8392 set_buffer_internal_1 (prev);
8393 }
8394 }
8395 }
8396
8397
8398 \f
8399 /***********************************************************************
8400 Output Cursor
8401 ***********************************************************************/
8402
8403 #ifdef HAVE_WINDOW_SYSTEM
8404
8405 /* EXPORT:
8406 Nominal cursor position -- where to draw output.
8407 HPOS and VPOS are window relative glyph matrix coordinates.
8408 X and Y are window relative pixel coordinates. */
8409
8410 struct cursor_pos output_cursor;
8411
8412
8413 /* EXPORT:
8414 Set the global variable output_cursor to CURSOR. All cursor
8415 positions are relative to updated_window. */
8416
8417 void
8418 set_output_cursor (cursor)
8419 struct cursor_pos *cursor;
8420 {
8421 output_cursor.hpos = cursor->hpos;
8422 output_cursor.vpos = cursor->vpos;
8423 output_cursor.x = cursor->x;
8424 output_cursor.y = cursor->y;
8425 }
8426
8427
8428 /* EXPORT for RIF:
8429 Set a nominal cursor position.
8430
8431 HPOS and VPOS are column/row positions in a window glyph matrix. X
8432 and Y are window text area relative pixel positions.
8433
8434 If this is done during an update, updated_window will contain the
8435 window that is being updated and the position is the future output
8436 cursor position for that window. If updated_window is null, use
8437 selected_window and display the cursor at the given position. */
8438
8439 void
8440 x_cursor_to (vpos, hpos, y, x)
8441 int vpos, hpos, y, x;
8442 {
8443 struct window *w;
8444
8445 /* If updated_window is not set, work on selected_window. */
8446 if (updated_window)
8447 w = updated_window;
8448 else
8449 w = XWINDOW (selected_window);
8450
8451 /* Set the output cursor. */
8452 output_cursor.hpos = hpos;
8453 output_cursor.vpos = vpos;
8454 output_cursor.x = x;
8455 output_cursor.y = y;
8456
8457 /* If not called as part of an update, really display the cursor.
8458 This will also set the cursor position of W. */
8459 if (updated_window == NULL)
8460 {
8461 BLOCK_INPUT;
8462 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8463 if (rif->flush_display_optional)
8464 rif->flush_display_optional (SELECTED_FRAME ());
8465 UNBLOCK_INPUT;
8466 }
8467 }
8468
8469 #endif /* HAVE_WINDOW_SYSTEM */
8470
8471 \f
8472 /***********************************************************************
8473 Tool-bars
8474 ***********************************************************************/
8475
8476 #ifdef HAVE_WINDOW_SYSTEM
8477
8478 /* Where the mouse was last time we reported a mouse event. */
8479
8480 FRAME_PTR last_mouse_frame;
8481
8482 /* Tool-bar item index of the item on which a mouse button was pressed
8483 or -1. */
8484
8485 int last_tool_bar_item;
8486
8487
8488 /* Update the tool-bar item list for frame F. This has to be done
8489 before we start to fill in any display lines. Called from
8490 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8491 and restore it here. */
8492
8493 static void
8494 update_tool_bar (f, save_match_data)
8495 struct frame *f;
8496 int save_match_data;
8497 {
8498 #ifdef USE_GTK
8499 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8500 #else
8501 int do_update = WINDOWP (f->tool_bar_window)
8502 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8503 #endif
8504
8505 if (do_update)
8506 {
8507 Lisp_Object window;
8508 struct window *w;
8509
8510 window = FRAME_SELECTED_WINDOW (f);
8511 w = XWINDOW (window);
8512
8513 /* If the user has switched buffers or windows, we need to
8514 recompute to reflect the new bindings. But we'll
8515 recompute when update_mode_lines is set too; that means
8516 that people can use force-mode-line-update to request
8517 that the menu bar be recomputed. The adverse effect on
8518 the rest of the redisplay algorithm is about the same as
8519 windows_or_buffers_changed anyway. */
8520 if (windows_or_buffers_changed
8521 || !NILP (w->update_mode_line)
8522 || update_mode_lines
8523 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8524 < BUF_MODIFF (XBUFFER (w->buffer)))
8525 != !NILP (w->last_had_star))
8526 || ((!NILP (Vtransient_mark_mode)
8527 && !NILP (XBUFFER (w->buffer)->mark_active))
8528 != !NILP (w->region_showing)))
8529 {
8530 struct buffer *prev = current_buffer;
8531 int count = SPECPDL_INDEX ();
8532 Lisp_Object new_tool_bar;
8533 int new_n_tool_bar;
8534 struct gcpro gcpro1;
8535
8536 /* Set current_buffer to the buffer of the selected
8537 window of the frame, so that we get the right local
8538 keymaps. */
8539 set_buffer_internal_1 (XBUFFER (w->buffer));
8540
8541 /* Save match data, if we must. */
8542 if (save_match_data)
8543 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8544
8545 /* Make sure that we don't accidentally use bogus keymaps. */
8546 if (NILP (Voverriding_local_map_menu_flag))
8547 {
8548 specbind (Qoverriding_terminal_local_map, Qnil);
8549 specbind (Qoverriding_local_map, Qnil);
8550 }
8551
8552 GCPRO1 (new_tool_bar);
8553
8554 /* Build desired tool-bar items from keymaps. */
8555 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8556 &new_n_tool_bar);
8557
8558 /* Redisplay the tool-bar if we changed it. */
8559 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8560 {
8561 /* Redisplay that happens asynchronously due to an expose event
8562 may access f->tool_bar_items. Make sure we update both
8563 variables within BLOCK_INPUT so no such event interrupts. */
8564 BLOCK_INPUT;
8565 f->tool_bar_items = new_tool_bar;
8566 f->n_tool_bar_items = new_n_tool_bar;
8567 w->update_mode_line = Qt;
8568 UNBLOCK_INPUT;
8569 }
8570
8571 UNGCPRO;
8572
8573 unbind_to (count, Qnil);
8574 set_buffer_internal_1 (prev);
8575 }
8576 }
8577 }
8578
8579
8580 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8581 F's desired tool-bar contents. F->tool_bar_items must have
8582 been set up previously by calling prepare_menu_bars. */
8583
8584 static void
8585 build_desired_tool_bar_string (f)
8586 struct frame *f;
8587 {
8588 int i, size, size_needed;
8589 struct gcpro gcpro1, gcpro2, gcpro3;
8590 Lisp_Object image, plist, props;
8591
8592 image = plist = props = Qnil;
8593 GCPRO3 (image, plist, props);
8594
8595 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8596 Otherwise, make a new string. */
8597
8598 /* The size of the string we might be able to reuse. */
8599 size = (STRINGP (f->desired_tool_bar_string)
8600 ? SCHARS (f->desired_tool_bar_string)
8601 : 0);
8602
8603 /* We need one space in the string for each image. */
8604 size_needed = f->n_tool_bar_items;
8605
8606 /* Reuse f->desired_tool_bar_string, if possible. */
8607 if (size < size_needed || NILP (f->desired_tool_bar_string))
8608 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8609 make_number (' '));
8610 else
8611 {
8612 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8613 Fremove_text_properties (make_number (0), make_number (size),
8614 props, f->desired_tool_bar_string);
8615 }
8616
8617 /* Put a `display' property on the string for the images to display,
8618 put a `menu_item' property on tool-bar items with a value that
8619 is the index of the item in F's tool-bar item vector. */
8620 for (i = 0; i < f->n_tool_bar_items; ++i)
8621 {
8622 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8623
8624 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8625 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8626 int hmargin, vmargin, relief, idx, end;
8627 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8628
8629 /* If image is a vector, choose the image according to the
8630 button state. */
8631 image = PROP (TOOL_BAR_ITEM_IMAGES);
8632 if (VECTORP (image))
8633 {
8634 if (enabled_p)
8635 idx = (selected_p
8636 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8637 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8638 else
8639 idx = (selected_p
8640 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8641 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8642
8643 xassert (ASIZE (image) >= idx);
8644 image = AREF (image, idx);
8645 }
8646 else
8647 idx = -1;
8648
8649 /* Ignore invalid image specifications. */
8650 if (!valid_image_p (image))
8651 continue;
8652
8653 /* Display the tool-bar button pressed, or depressed. */
8654 plist = Fcopy_sequence (XCDR (image));
8655
8656 /* Compute margin and relief to draw. */
8657 relief = (tool_bar_button_relief >= 0
8658 ? tool_bar_button_relief
8659 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8660 hmargin = vmargin = relief;
8661
8662 if (INTEGERP (Vtool_bar_button_margin)
8663 && XINT (Vtool_bar_button_margin) > 0)
8664 {
8665 hmargin += XFASTINT (Vtool_bar_button_margin);
8666 vmargin += XFASTINT (Vtool_bar_button_margin);
8667 }
8668 else if (CONSP (Vtool_bar_button_margin))
8669 {
8670 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8671 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8672 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8673
8674 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8675 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8676 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8677 }
8678
8679 if (auto_raise_tool_bar_buttons_p)
8680 {
8681 /* Add a `:relief' property to the image spec if the item is
8682 selected. */
8683 if (selected_p)
8684 {
8685 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8686 hmargin -= relief;
8687 vmargin -= relief;
8688 }
8689 }
8690 else
8691 {
8692 /* If image is selected, display it pressed, i.e. with a
8693 negative relief. If it's not selected, display it with a
8694 raised relief. */
8695 plist = Fplist_put (plist, QCrelief,
8696 (selected_p
8697 ? make_number (-relief)
8698 : make_number (relief)));
8699 hmargin -= relief;
8700 vmargin -= relief;
8701 }
8702
8703 /* Put a margin around the image. */
8704 if (hmargin || vmargin)
8705 {
8706 if (hmargin == vmargin)
8707 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8708 else
8709 plist = Fplist_put (plist, QCmargin,
8710 Fcons (make_number (hmargin),
8711 make_number (vmargin)));
8712 }
8713
8714 /* If button is not enabled, and we don't have special images
8715 for the disabled state, make the image appear disabled by
8716 applying an appropriate algorithm to it. */
8717 if (!enabled_p && idx < 0)
8718 plist = Fplist_put (plist, QCconversion, Qdisabled);
8719
8720 /* Put a `display' text property on the string for the image to
8721 display. Put a `menu-item' property on the string that gives
8722 the start of this item's properties in the tool-bar items
8723 vector. */
8724 image = Fcons (Qimage, plist);
8725 props = list4 (Qdisplay, image,
8726 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8727
8728 /* Let the last image hide all remaining spaces in the tool bar
8729 string. The string can be longer than needed when we reuse a
8730 previous string. */
8731 if (i + 1 == f->n_tool_bar_items)
8732 end = SCHARS (f->desired_tool_bar_string);
8733 else
8734 end = i + 1;
8735 Fadd_text_properties (make_number (i), make_number (end),
8736 props, f->desired_tool_bar_string);
8737 #undef PROP
8738 }
8739
8740 UNGCPRO;
8741 }
8742
8743
8744 /* Display one line of the tool-bar of frame IT->f. */
8745
8746 static void
8747 display_tool_bar_line (it)
8748 struct it *it;
8749 {
8750 struct glyph_row *row = it->glyph_row;
8751 int max_x = it->last_visible_x;
8752 struct glyph *last;
8753
8754 prepare_desired_row (row);
8755 row->y = it->current_y;
8756
8757 /* Note that this isn't made use of if the face hasn't a box,
8758 so there's no need to check the face here. */
8759 it->start_of_box_run_p = 1;
8760
8761 while (it->current_x < max_x)
8762 {
8763 int x_before, x, n_glyphs_before, i, nglyphs;
8764
8765 /* Get the next display element. */
8766 if (!get_next_display_element (it))
8767 break;
8768
8769 /* Produce glyphs. */
8770 x_before = it->current_x;
8771 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8772 PRODUCE_GLYPHS (it);
8773
8774 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8775 i = 0;
8776 x = x_before;
8777 while (i < nglyphs)
8778 {
8779 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8780
8781 if (x + glyph->pixel_width > max_x)
8782 {
8783 /* Glyph doesn't fit on line. */
8784 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8785 it->current_x = x;
8786 goto out;
8787 }
8788
8789 ++it->hpos;
8790 x += glyph->pixel_width;
8791 ++i;
8792 }
8793
8794 /* Stop at line ends. */
8795 if (ITERATOR_AT_END_OF_LINE_P (it))
8796 break;
8797
8798 set_iterator_to_next (it, 1);
8799 }
8800
8801 out:;
8802
8803 row->displays_text_p = row->used[TEXT_AREA] != 0;
8804 extend_face_to_end_of_line (it);
8805 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8806 last->right_box_line_p = 1;
8807 if (last == row->glyphs[TEXT_AREA])
8808 last->left_box_line_p = 1;
8809 compute_line_metrics (it);
8810
8811 /* If line is empty, make it occupy the rest of the tool-bar. */
8812 if (!row->displays_text_p)
8813 {
8814 row->height = row->phys_height = it->last_visible_y - row->y;
8815 row->ascent = row->phys_ascent = 0;
8816 }
8817
8818 row->full_width_p = 1;
8819 row->continued_p = 0;
8820 row->truncated_on_left_p = 0;
8821 row->truncated_on_right_p = 0;
8822
8823 it->current_x = it->hpos = 0;
8824 it->current_y += row->height;
8825 ++it->vpos;
8826 ++it->glyph_row;
8827 }
8828
8829
8830 /* Value is the number of screen lines needed to make all tool-bar
8831 items of frame F visible. */
8832
8833 static int
8834 tool_bar_lines_needed (f)
8835 struct frame *f;
8836 {
8837 struct window *w = XWINDOW (f->tool_bar_window);
8838 struct it it;
8839
8840 /* Initialize an iterator for iteration over
8841 F->desired_tool_bar_string in the tool-bar window of frame F. */
8842 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8843 it.first_visible_x = 0;
8844 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8845 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8846
8847 while (!ITERATOR_AT_END_P (&it))
8848 {
8849 it.glyph_row = w->desired_matrix->rows;
8850 clear_glyph_row (it.glyph_row);
8851 display_tool_bar_line (&it);
8852 }
8853
8854 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8855 }
8856
8857
8858 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8859 0, 1, 0,
8860 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8861 (frame)
8862 Lisp_Object frame;
8863 {
8864 struct frame *f;
8865 struct window *w;
8866 int nlines = 0;
8867
8868 if (NILP (frame))
8869 frame = selected_frame;
8870 else
8871 CHECK_FRAME (frame);
8872 f = XFRAME (frame);
8873
8874 if (WINDOWP (f->tool_bar_window)
8875 || (w = XWINDOW (f->tool_bar_window),
8876 WINDOW_TOTAL_LINES (w) > 0))
8877 {
8878 update_tool_bar (f, 1);
8879 if (f->n_tool_bar_items)
8880 {
8881 build_desired_tool_bar_string (f);
8882 nlines = tool_bar_lines_needed (f);
8883 }
8884 }
8885
8886 return make_number (nlines);
8887 }
8888
8889
8890 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8891 height should be changed. */
8892
8893 static int
8894 redisplay_tool_bar (f)
8895 struct frame *f;
8896 {
8897 struct window *w;
8898 struct it it;
8899 struct glyph_row *row;
8900 int change_height_p = 0;
8901
8902 #ifdef USE_GTK
8903 if (FRAME_EXTERNAL_TOOL_BAR (f))
8904 update_frame_tool_bar (f);
8905 return 0;
8906 #endif
8907
8908 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8909 do anything. This means you must start with tool-bar-lines
8910 non-zero to get the auto-sizing effect. Or in other words, you
8911 can turn off tool-bars by specifying tool-bar-lines zero. */
8912 if (!WINDOWP (f->tool_bar_window)
8913 || (w = XWINDOW (f->tool_bar_window),
8914 WINDOW_TOTAL_LINES (w) == 0))
8915 return 0;
8916
8917 /* Set up an iterator for the tool-bar window. */
8918 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8919 it.first_visible_x = 0;
8920 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8921 row = it.glyph_row;
8922
8923 /* Build a string that represents the contents of the tool-bar. */
8924 build_desired_tool_bar_string (f);
8925 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8926
8927 /* Display as many lines as needed to display all tool-bar items. */
8928 while (it.current_y < it.last_visible_y)
8929 display_tool_bar_line (&it);
8930
8931 /* It doesn't make much sense to try scrolling in the tool-bar
8932 window, so don't do it. */
8933 w->desired_matrix->no_scrolling_p = 1;
8934 w->must_be_updated_p = 1;
8935
8936 if (auto_resize_tool_bars_p)
8937 {
8938 int nlines;
8939
8940 /* If we couldn't display everything, change the tool-bar's
8941 height. */
8942 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8943 change_height_p = 1;
8944
8945 /* If there are blank lines at the end, except for a partially
8946 visible blank line at the end that is smaller than
8947 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8948 row = it.glyph_row - 1;
8949 if (!row->displays_text_p
8950 && row->height >= FRAME_LINE_HEIGHT (f))
8951 change_height_p = 1;
8952
8953 /* If row displays tool-bar items, but is partially visible,
8954 change the tool-bar's height. */
8955 if (row->displays_text_p
8956 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8957 change_height_p = 1;
8958
8959 /* Resize windows as needed by changing the `tool-bar-lines'
8960 frame parameter. */
8961 if (change_height_p
8962 && (nlines = tool_bar_lines_needed (f),
8963 nlines != WINDOW_TOTAL_LINES (w)))
8964 {
8965 extern Lisp_Object Qtool_bar_lines;
8966 Lisp_Object frame;
8967 int old_height = WINDOW_TOTAL_LINES (w);
8968
8969 XSETFRAME (frame, f);
8970 clear_glyph_matrix (w->desired_matrix);
8971 Fmodify_frame_parameters (frame,
8972 Fcons (Fcons (Qtool_bar_lines,
8973 make_number (nlines)),
8974 Qnil));
8975 if (WINDOW_TOTAL_LINES (w) != old_height)
8976 fonts_changed_p = 1;
8977 }
8978 }
8979
8980 return change_height_p;
8981 }
8982
8983
8984 /* Get information about the tool-bar item which is displayed in GLYPH
8985 on frame F. Return in *PROP_IDX the index where tool-bar item
8986 properties start in F->tool_bar_items. Value is zero if
8987 GLYPH doesn't display a tool-bar item. */
8988
8989 static int
8990 tool_bar_item_info (f, glyph, prop_idx)
8991 struct frame *f;
8992 struct glyph *glyph;
8993 int *prop_idx;
8994 {
8995 Lisp_Object prop;
8996 int success_p;
8997 int charpos;
8998
8999 /* This function can be called asynchronously, which means we must
9000 exclude any possibility that Fget_text_property signals an
9001 error. */
9002 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9003 charpos = max (0, charpos);
9004
9005 /* Get the text property `menu-item' at pos. The value of that
9006 property is the start index of this item's properties in
9007 F->tool_bar_items. */
9008 prop = Fget_text_property (make_number (charpos),
9009 Qmenu_item, f->current_tool_bar_string);
9010 if (INTEGERP (prop))
9011 {
9012 *prop_idx = XINT (prop);
9013 success_p = 1;
9014 }
9015 else
9016 success_p = 0;
9017
9018 return success_p;
9019 }
9020
9021 \f
9022 /* Get information about the tool-bar item at position X/Y on frame F.
9023 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9024 the current matrix of the tool-bar window of F, or NULL if not
9025 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9026 item in F->tool_bar_items. Value is
9027
9028 -1 if X/Y is not on a tool-bar item
9029 0 if X/Y is on the same item that was highlighted before.
9030 1 otherwise. */
9031
9032 static int
9033 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9034 struct frame *f;
9035 int x, y;
9036 struct glyph **glyph;
9037 int *hpos, *vpos, *prop_idx;
9038 {
9039 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9040 struct window *w = XWINDOW (f->tool_bar_window);
9041 int area;
9042
9043 /* Find the glyph under X/Y. */
9044 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9045 if (*glyph == NULL)
9046 return -1;
9047
9048 /* Get the start of this tool-bar item's properties in
9049 f->tool_bar_items. */
9050 if (!tool_bar_item_info (f, *glyph, prop_idx))
9051 return -1;
9052
9053 /* Is mouse on the highlighted item? */
9054 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9055 && *vpos >= dpyinfo->mouse_face_beg_row
9056 && *vpos <= dpyinfo->mouse_face_end_row
9057 && (*vpos > dpyinfo->mouse_face_beg_row
9058 || *hpos >= dpyinfo->mouse_face_beg_col)
9059 && (*vpos < dpyinfo->mouse_face_end_row
9060 || *hpos < dpyinfo->mouse_face_end_col
9061 || dpyinfo->mouse_face_past_end))
9062 return 0;
9063
9064 return 1;
9065 }
9066
9067
9068 /* EXPORT:
9069 Handle mouse button event on the tool-bar of frame F, at
9070 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9071 0 for button release. MODIFIERS is event modifiers for button
9072 release. */
9073
9074 void
9075 handle_tool_bar_click (f, x, y, down_p, modifiers)
9076 struct frame *f;
9077 int x, y, down_p;
9078 unsigned int modifiers;
9079 {
9080 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9081 struct window *w = XWINDOW (f->tool_bar_window);
9082 int hpos, vpos, prop_idx;
9083 struct glyph *glyph;
9084 Lisp_Object enabled_p;
9085
9086 /* If not on the highlighted tool-bar item, return. */
9087 frame_to_window_pixel_xy (w, &x, &y);
9088 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9089 return;
9090
9091 /* If item is disabled, do nothing. */
9092 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9093 if (NILP (enabled_p))
9094 return;
9095
9096 if (down_p)
9097 {
9098 /* Show item in pressed state. */
9099 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9100 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9101 last_tool_bar_item = prop_idx;
9102 }
9103 else
9104 {
9105 Lisp_Object key, frame;
9106 struct input_event event;
9107 EVENT_INIT (event);
9108
9109 /* Show item in released state. */
9110 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9111 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9112
9113 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9114
9115 XSETFRAME (frame, f);
9116 event.kind = TOOL_BAR_EVENT;
9117 event.frame_or_window = frame;
9118 event.arg = frame;
9119 kbd_buffer_store_event (&event);
9120
9121 event.kind = TOOL_BAR_EVENT;
9122 event.frame_or_window = frame;
9123 event.arg = key;
9124 event.modifiers = modifiers;
9125 kbd_buffer_store_event (&event);
9126 last_tool_bar_item = -1;
9127 }
9128 }
9129
9130
9131 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9132 tool-bar window-relative coordinates X/Y. Called from
9133 note_mouse_highlight. */
9134
9135 static void
9136 note_tool_bar_highlight (f, x, y)
9137 struct frame *f;
9138 int x, y;
9139 {
9140 Lisp_Object window = f->tool_bar_window;
9141 struct window *w = XWINDOW (window);
9142 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9143 int hpos, vpos;
9144 struct glyph *glyph;
9145 struct glyph_row *row;
9146 int i;
9147 Lisp_Object enabled_p;
9148 int prop_idx;
9149 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9150 int mouse_down_p, rc;
9151
9152 /* Function note_mouse_highlight is called with negative x(y
9153 values when mouse moves outside of the frame. */
9154 if (x <= 0 || y <= 0)
9155 {
9156 clear_mouse_face (dpyinfo);
9157 return;
9158 }
9159
9160 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9161 if (rc < 0)
9162 {
9163 /* Not on tool-bar item. */
9164 clear_mouse_face (dpyinfo);
9165 return;
9166 }
9167 else if (rc == 0)
9168 /* On same tool-bar item as before. */
9169 goto set_help_echo;
9170
9171 clear_mouse_face (dpyinfo);
9172
9173 /* Mouse is down, but on different tool-bar item? */
9174 mouse_down_p = (dpyinfo->grabbed
9175 && f == last_mouse_frame
9176 && FRAME_LIVE_P (f));
9177 if (mouse_down_p
9178 && last_tool_bar_item != prop_idx)
9179 return;
9180
9181 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9182 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9183
9184 /* If tool-bar item is not enabled, don't highlight it. */
9185 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9186 if (!NILP (enabled_p))
9187 {
9188 /* Compute the x-position of the glyph. In front and past the
9189 image is a space. We include this in the highlighted area. */
9190 row = MATRIX_ROW (w->current_matrix, vpos);
9191 for (i = x = 0; i < hpos; ++i)
9192 x += row->glyphs[TEXT_AREA][i].pixel_width;
9193
9194 /* Record this as the current active region. */
9195 dpyinfo->mouse_face_beg_col = hpos;
9196 dpyinfo->mouse_face_beg_row = vpos;
9197 dpyinfo->mouse_face_beg_x = x;
9198 dpyinfo->mouse_face_beg_y = row->y;
9199 dpyinfo->mouse_face_past_end = 0;
9200
9201 dpyinfo->mouse_face_end_col = hpos + 1;
9202 dpyinfo->mouse_face_end_row = vpos;
9203 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9204 dpyinfo->mouse_face_end_y = row->y;
9205 dpyinfo->mouse_face_window = window;
9206 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9207
9208 /* Display it as active. */
9209 show_mouse_face (dpyinfo, draw);
9210 dpyinfo->mouse_face_image_state = draw;
9211 }
9212
9213 set_help_echo:
9214
9215 /* Set help_echo_string to a help string to display for this tool-bar item.
9216 XTread_socket does the rest. */
9217 help_echo_object = help_echo_window = Qnil;
9218 help_echo_pos = -1;
9219 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9220 if (NILP (help_echo_string))
9221 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9222 }
9223
9224 #endif /* HAVE_WINDOW_SYSTEM */
9225
9226
9227 \f
9228 /************************************************************************
9229 Horizontal scrolling
9230 ************************************************************************/
9231
9232 static int hscroll_window_tree P_ ((Lisp_Object));
9233 static int hscroll_windows P_ ((Lisp_Object));
9234
9235 /* For all leaf windows in the window tree rooted at WINDOW, set their
9236 hscroll value so that PT is (i) visible in the window, and (ii) so
9237 that it is not within a certain margin at the window's left and
9238 right border. Value is non-zero if any window's hscroll has been
9239 changed. */
9240
9241 static int
9242 hscroll_window_tree (window)
9243 Lisp_Object window;
9244 {
9245 int hscrolled_p = 0;
9246 int hscroll_relative_p = FLOATP (Vhscroll_step);
9247 int hscroll_step_abs = 0;
9248 double hscroll_step_rel = 0;
9249
9250 if (hscroll_relative_p)
9251 {
9252 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9253 if (hscroll_step_rel < 0)
9254 {
9255 hscroll_relative_p = 0;
9256 hscroll_step_abs = 0;
9257 }
9258 }
9259 else if (INTEGERP (Vhscroll_step))
9260 {
9261 hscroll_step_abs = XINT (Vhscroll_step);
9262 if (hscroll_step_abs < 0)
9263 hscroll_step_abs = 0;
9264 }
9265 else
9266 hscroll_step_abs = 0;
9267
9268 while (WINDOWP (window))
9269 {
9270 struct window *w = XWINDOW (window);
9271
9272 if (WINDOWP (w->hchild))
9273 hscrolled_p |= hscroll_window_tree (w->hchild);
9274 else if (WINDOWP (w->vchild))
9275 hscrolled_p |= hscroll_window_tree (w->vchild);
9276 else if (w->cursor.vpos >= 0)
9277 {
9278 int h_margin;
9279 int text_area_width;
9280 struct glyph_row *current_cursor_row
9281 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9282 struct glyph_row *desired_cursor_row
9283 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9284 struct glyph_row *cursor_row
9285 = (desired_cursor_row->enabled_p
9286 ? desired_cursor_row
9287 : current_cursor_row);
9288
9289 text_area_width = window_box_width (w, TEXT_AREA);
9290
9291 /* Scroll when cursor is inside this scroll margin. */
9292 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9293
9294 if ((XFASTINT (w->hscroll)
9295 && w->cursor.x <= h_margin)
9296 || (cursor_row->enabled_p
9297 && cursor_row->truncated_on_right_p
9298 && (w->cursor.x >= text_area_width - h_margin)))
9299 {
9300 struct it it;
9301 int hscroll;
9302 struct buffer *saved_current_buffer;
9303 int pt;
9304 int wanted_x;
9305
9306 /* Find point in a display of infinite width. */
9307 saved_current_buffer = current_buffer;
9308 current_buffer = XBUFFER (w->buffer);
9309
9310 if (w == XWINDOW (selected_window))
9311 pt = BUF_PT (current_buffer);
9312 else
9313 {
9314 pt = marker_position (w->pointm);
9315 pt = max (BEGV, pt);
9316 pt = min (ZV, pt);
9317 }
9318
9319 /* Move iterator to pt starting at cursor_row->start in
9320 a line with infinite width. */
9321 init_to_row_start (&it, w, cursor_row);
9322 it.last_visible_x = INFINITY;
9323 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9324 current_buffer = saved_current_buffer;
9325
9326 /* Position cursor in window. */
9327 if (!hscroll_relative_p && hscroll_step_abs == 0)
9328 hscroll = max (0, (it.current_x
9329 - (ITERATOR_AT_END_OF_LINE_P (&it)
9330 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9331 : (text_area_width / 2))))
9332 / FRAME_COLUMN_WIDTH (it.f);
9333 else if (w->cursor.x >= text_area_width - h_margin)
9334 {
9335 if (hscroll_relative_p)
9336 wanted_x = text_area_width * (1 - hscroll_step_rel)
9337 - h_margin;
9338 else
9339 wanted_x = text_area_width
9340 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9341 - h_margin;
9342 hscroll
9343 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9344 }
9345 else
9346 {
9347 if (hscroll_relative_p)
9348 wanted_x = text_area_width * hscroll_step_rel
9349 + h_margin;
9350 else
9351 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9352 + h_margin;
9353 hscroll
9354 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9355 }
9356 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9357
9358 /* Don't call Fset_window_hscroll if value hasn't
9359 changed because it will prevent redisplay
9360 optimizations. */
9361 if (XFASTINT (w->hscroll) != hscroll)
9362 {
9363 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9364 w->hscroll = make_number (hscroll);
9365 hscrolled_p = 1;
9366 }
9367 }
9368 }
9369
9370 window = w->next;
9371 }
9372
9373 /* Value is non-zero if hscroll of any leaf window has been changed. */
9374 return hscrolled_p;
9375 }
9376
9377
9378 /* Set hscroll so that cursor is visible and not inside horizontal
9379 scroll margins for all windows in the tree rooted at WINDOW. See
9380 also hscroll_window_tree above. Value is non-zero if any window's
9381 hscroll has been changed. If it has, desired matrices on the frame
9382 of WINDOW are cleared. */
9383
9384 static int
9385 hscroll_windows (window)
9386 Lisp_Object window;
9387 {
9388 int hscrolled_p;
9389
9390 if (automatic_hscrolling_p)
9391 {
9392 hscrolled_p = hscroll_window_tree (window);
9393 if (hscrolled_p)
9394 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9395 }
9396 else
9397 hscrolled_p = 0;
9398 return hscrolled_p;
9399 }
9400
9401
9402 \f
9403 /************************************************************************
9404 Redisplay
9405 ************************************************************************/
9406
9407 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9408 to a non-zero value. This is sometimes handy to have in a debugger
9409 session. */
9410
9411 #if GLYPH_DEBUG
9412
9413 /* First and last unchanged row for try_window_id. */
9414
9415 int debug_first_unchanged_at_end_vpos;
9416 int debug_last_unchanged_at_beg_vpos;
9417
9418 /* Delta vpos and y. */
9419
9420 int debug_dvpos, debug_dy;
9421
9422 /* Delta in characters and bytes for try_window_id. */
9423
9424 int debug_delta, debug_delta_bytes;
9425
9426 /* Values of window_end_pos and window_end_vpos at the end of
9427 try_window_id. */
9428
9429 EMACS_INT debug_end_pos, debug_end_vpos;
9430
9431 /* Append a string to W->desired_matrix->method. FMT is a printf
9432 format string. A1...A9 are a supplement for a variable-length
9433 argument list. If trace_redisplay_p is non-zero also printf the
9434 resulting string to stderr. */
9435
9436 static void
9437 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9438 struct window *w;
9439 char *fmt;
9440 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9441 {
9442 char buffer[512];
9443 char *method = w->desired_matrix->method;
9444 int len = strlen (method);
9445 int size = sizeof w->desired_matrix->method;
9446 int remaining = size - len - 1;
9447
9448 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9449 if (len && remaining)
9450 {
9451 method[len] = '|';
9452 --remaining, ++len;
9453 }
9454
9455 strncpy (method + len, buffer, remaining);
9456
9457 if (trace_redisplay_p)
9458 fprintf (stderr, "%p (%s): %s\n",
9459 w,
9460 ((BUFFERP (w->buffer)
9461 && STRINGP (XBUFFER (w->buffer)->name))
9462 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9463 : "no buffer"),
9464 buffer);
9465 }
9466
9467 #endif /* GLYPH_DEBUG */
9468
9469
9470 /* Value is non-zero if all changes in window W, which displays
9471 current_buffer, are in the text between START and END. START is a
9472 buffer position, END is given as a distance from Z. Used in
9473 redisplay_internal for display optimization. */
9474
9475 static INLINE int
9476 text_outside_line_unchanged_p (w, start, end)
9477 struct window *w;
9478 int start, end;
9479 {
9480 int unchanged_p = 1;
9481
9482 /* If text or overlays have changed, see where. */
9483 if (XFASTINT (w->last_modified) < MODIFF
9484 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9485 {
9486 /* Gap in the line? */
9487 if (GPT < start || Z - GPT < end)
9488 unchanged_p = 0;
9489
9490 /* Changes start in front of the line, or end after it? */
9491 if (unchanged_p
9492 && (BEG_UNCHANGED < start - 1
9493 || END_UNCHANGED < end))
9494 unchanged_p = 0;
9495
9496 /* If selective display, can't optimize if changes start at the
9497 beginning of the line. */
9498 if (unchanged_p
9499 && INTEGERP (current_buffer->selective_display)
9500 && XINT (current_buffer->selective_display) > 0
9501 && (BEG_UNCHANGED < start || GPT <= start))
9502 unchanged_p = 0;
9503
9504 /* If there are overlays at the start or end of the line, these
9505 may have overlay strings with newlines in them. A change at
9506 START, for instance, may actually concern the display of such
9507 overlay strings as well, and they are displayed on different
9508 lines. So, quickly rule out this case. (For the future, it
9509 might be desirable to implement something more telling than
9510 just BEG/END_UNCHANGED.) */
9511 if (unchanged_p)
9512 {
9513 if (BEG + BEG_UNCHANGED == start
9514 && overlay_touches_p (start))
9515 unchanged_p = 0;
9516 if (END_UNCHANGED == end
9517 && overlay_touches_p (Z - end))
9518 unchanged_p = 0;
9519 }
9520 }
9521
9522 return unchanged_p;
9523 }
9524
9525
9526 /* Do a frame update, taking possible shortcuts into account. This is
9527 the main external entry point for redisplay.
9528
9529 If the last redisplay displayed an echo area message and that message
9530 is no longer requested, we clear the echo area or bring back the
9531 mini-buffer if that is in use. */
9532
9533 void
9534 redisplay ()
9535 {
9536 redisplay_internal (0);
9537 }
9538
9539
9540 static Lisp_Object
9541 overlay_arrow_string_or_property (var, pbitmap)
9542 Lisp_Object var;
9543 int *pbitmap;
9544 {
9545 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9546 Lisp_Object bitmap;
9547
9548 if (pbitmap)
9549 {
9550 *pbitmap = 0;
9551 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9552 *pbitmap = XINT (bitmap);
9553 }
9554
9555 if (!NILP (pstr))
9556 return pstr;
9557 return Voverlay_arrow_string;
9558 }
9559
9560 /* Return 1 if there are any overlay-arrows in current_buffer. */
9561 static int
9562 overlay_arrow_in_current_buffer_p ()
9563 {
9564 Lisp_Object vlist;
9565
9566 for (vlist = Voverlay_arrow_variable_list;
9567 CONSP (vlist);
9568 vlist = XCDR (vlist))
9569 {
9570 Lisp_Object var = XCAR (vlist);
9571 Lisp_Object val;
9572
9573 if (!SYMBOLP (var))
9574 continue;
9575 val = find_symbol_value (var);
9576 if (MARKERP (val)
9577 && current_buffer == XMARKER (val)->buffer)
9578 return 1;
9579 }
9580 return 0;
9581 }
9582
9583
9584 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9585 has changed. */
9586
9587 static int
9588 overlay_arrows_changed_p ()
9589 {
9590 Lisp_Object vlist;
9591
9592 for (vlist = Voverlay_arrow_variable_list;
9593 CONSP (vlist);
9594 vlist = XCDR (vlist))
9595 {
9596 Lisp_Object var = XCAR (vlist);
9597 Lisp_Object val, pstr;
9598
9599 if (!SYMBOLP (var))
9600 continue;
9601 val = find_symbol_value (var);
9602 if (!MARKERP (val))
9603 continue;
9604 if (! EQ (COERCE_MARKER (val),
9605 Fget (var, Qlast_arrow_position))
9606 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9607 EQ (pstr, Fget (var, Qlast_arrow_string))))
9608 return 1;
9609 }
9610 return 0;
9611 }
9612
9613 /* Mark overlay arrows to be updated on next redisplay. */
9614
9615 static void
9616 update_overlay_arrows (up_to_date)
9617 int up_to_date;
9618 {
9619 Lisp_Object vlist;
9620
9621 for (vlist = Voverlay_arrow_variable_list;
9622 CONSP (vlist);
9623 vlist = XCDR (vlist))
9624 {
9625 Lisp_Object var = XCAR (vlist);
9626
9627 if (!SYMBOLP (var))
9628 continue;
9629
9630 if (up_to_date > 0)
9631 {
9632 Lisp_Object val = find_symbol_value (var);
9633 Fput (var, Qlast_arrow_position,
9634 COERCE_MARKER (val));
9635 Fput (var, Qlast_arrow_string,
9636 overlay_arrow_string_or_property (var, 0));
9637 }
9638 else if (up_to_date < 0
9639 || !NILP (Fget (var, Qlast_arrow_position)))
9640 {
9641 Fput (var, Qlast_arrow_position, Qt);
9642 Fput (var, Qlast_arrow_string, Qt);
9643 }
9644 }
9645 }
9646
9647
9648 /* Return overlay arrow string to display at row.
9649 Return t if display as bitmap in left fringe.
9650 Return nil if no overlay arrow. */
9651
9652 static Lisp_Object
9653 overlay_arrow_at_row (it, row, pbitmap)
9654 struct it *it;
9655 struct glyph_row *row;
9656 int *pbitmap;
9657 {
9658 Lisp_Object vlist;
9659
9660 for (vlist = Voverlay_arrow_variable_list;
9661 CONSP (vlist);
9662 vlist = XCDR (vlist))
9663 {
9664 Lisp_Object var = XCAR (vlist);
9665 Lisp_Object val;
9666
9667 if (!SYMBOLP (var))
9668 continue;
9669
9670 val = find_symbol_value (var);
9671
9672 if (MARKERP (val)
9673 && current_buffer == XMARKER (val)->buffer
9674 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9675 {
9676 val = overlay_arrow_string_or_property (var, pbitmap);
9677 if (FRAME_WINDOW_P (it->f)
9678 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9679 return Qt;
9680 if (STRINGP (val))
9681 return val;
9682 break;
9683 }
9684 }
9685
9686 *pbitmap = 0;
9687 return Qnil;
9688 }
9689
9690 /* Return 1 if point moved out of or into a composition. Otherwise
9691 return 0. PREV_BUF and PREV_PT are the last point buffer and
9692 position. BUF and PT are the current point buffer and position. */
9693
9694 int
9695 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9696 struct buffer *prev_buf, *buf;
9697 int prev_pt, pt;
9698 {
9699 EMACS_INT start, end;
9700 Lisp_Object prop;
9701 Lisp_Object buffer;
9702
9703 XSETBUFFER (buffer, buf);
9704 /* Check a composition at the last point if point moved within the
9705 same buffer. */
9706 if (prev_buf == buf)
9707 {
9708 if (prev_pt == pt)
9709 /* Point didn't move. */
9710 return 0;
9711
9712 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9713 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9714 && COMPOSITION_VALID_P (start, end, prop)
9715 && start < prev_pt && end > prev_pt)
9716 /* The last point was within the composition. Return 1 iff
9717 point moved out of the composition. */
9718 return (pt <= start || pt >= end);
9719 }
9720
9721 /* Check a composition at the current point. */
9722 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9723 && find_composition (pt, -1, &start, &end, &prop, buffer)
9724 && COMPOSITION_VALID_P (start, end, prop)
9725 && start < pt && end > pt);
9726 }
9727
9728
9729 /* Reconsider the setting of B->clip_changed which is displayed
9730 in window W. */
9731
9732 static INLINE void
9733 reconsider_clip_changes (w, b)
9734 struct window *w;
9735 struct buffer *b;
9736 {
9737 if (b->clip_changed
9738 && !NILP (w->window_end_valid)
9739 && w->current_matrix->buffer == b
9740 && w->current_matrix->zv == BUF_ZV (b)
9741 && w->current_matrix->begv == BUF_BEGV (b))
9742 b->clip_changed = 0;
9743
9744 /* If display wasn't paused, and W is not a tool bar window, see if
9745 point has been moved into or out of a composition. In that case,
9746 we set b->clip_changed to 1 to force updating the screen. If
9747 b->clip_changed has already been set to 1, we can skip this
9748 check. */
9749 if (!b->clip_changed
9750 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9751 {
9752 int pt;
9753
9754 if (w == XWINDOW (selected_window))
9755 pt = BUF_PT (current_buffer);
9756 else
9757 pt = marker_position (w->pointm);
9758
9759 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9760 || pt != XINT (w->last_point))
9761 && check_point_in_composition (w->current_matrix->buffer,
9762 XINT (w->last_point),
9763 XBUFFER (w->buffer), pt))
9764 b->clip_changed = 1;
9765 }
9766 }
9767 \f
9768
9769 /* Select FRAME to forward the values of frame-local variables into C
9770 variables so that the redisplay routines can access those values
9771 directly. */
9772
9773 static void
9774 select_frame_for_redisplay (frame)
9775 Lisp_Object frame;
9776 {
9777 Lisp_Object tail, sym, val;
9778 Lisp_Object old = selected_frame;
9779
9780 selected_frame = frame;
9781
9782 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9783 if (CONSP (XCAR (tail))
9784 && (sym = XCAR (XCAR (tail)),
9785 SYMBOLP (sym))
9786 && (sym = indirect_variable (sym),
9787 val = SYMBOL_VALUE (sym),
9788 (BUFFER_LOCAL_VALUEP (val)
9789 || SOME_BUFFER_LOCAL_VALUEP (val)))
9790 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9791 Fsymbol_value (sym);
9792
9793 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9794 if (CONSP (XCAR (tail))
9795 && (sym = XCAR (XCAR (tail)),
9796 SYMBOLP (sym))
9797 && (sym = indirect_variable (sym),
9798 val = SYMBOL_VALUE (sym),
9799 (BUFFER_LOCAL_VALUEP (val)
9800 || SOME_BUFFER_LOCAL_VALUEP (val)))
9801 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9802 Fsymbol_value (sym);
9803 }
9804
9805
9806 #define STOP_POLLING \
9807 do { if (! polling_stopped_here) stop_polling (); \
9808 polling_stopped_here = 1; } while (0)
9809
9810 #define RESUME_POLLING \
9811 do { if (polling_stopped_here) start_polling (); \
9812 polling_stopped_here = 0; } while (0)
9813
9814
9815 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9816 response to any user action; therefore, we should preserve the echo
9817 area. (Actually, our caller does that job.) Perhaps in the future
9818 avoid recentering windows if it is not necessary; currently that
9819 causes some problems. */
9820
9821 static void
9822 redisplay_internal (preserve_echo_area)
9823 int preserve_echo_area;
9824 {
9825 struct window *w = XWINDOW (selected_window);
9826 struct frame *f = XFRAME (w->frame);
9827 int pause;
9828 int must_finish = 0;
9829 struct text_pos tlbufpos, tlendpos;
9830 int number_of_visible_frames;
9831 int count;
9832 struct frame *sf = SELECTED_FRAME ();
9833 int polling_stopped_here = 0;
9834
9835 /* Non-zero means redisplay has to consider all windows on all
9836 frames. Zero means, only selected_window is considered. */
9837 int consider_all_windows_p;
9838
9839 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9840
9841 /* No redisplay if running in batch mode or frame is not yet fully
9842 initialized, or redisplay is explicitly turned off by setting
9843 Vinhibit_redisplay. */
9844 if (noninteractive
9845 || !NILP (Vinhibit_redisplay)
9846 || !f->glyphs_initialized_p)
9847 return;
9848
9849 /* The flag redisplay_performed_directly_p is set by
9850 direct_output_for_insert when it already did the whole screen
9851 update necessary. */
9852 if (redisplay_performed_directly_p)
9853 {
9854 redisplay_performed_directly_p = 0;
9855 if (!hscroll_windows (selected_window))
9856 return;
9857 }
9858
9859 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9860 if (popup_activated ())
9861 return;
9862 #endif
9863
9864 /* I don't think this happens but let's be paranoid. */
9865 if (redisplaying_p)
9866 return;
9867
9868 /* Record a function that resets redisplaying_p to its old value
9869 when we leave this function. */
9870 count = SPECPDL_INDEX ();
9871 record_unwind_protect (unwind_redisplay,
9872 Fcons (make_number (redisplaying_p), selected_frame));
9873 ++redisplaying_p;
9874 specbind (Qinhibit_free_realized_faces, Qnil);
9875
9876 retry:
9877 pause = 0;
9878 reconsider_clip_changes (w, current_buffer);
9879
9880 /* If new fonts have been loaded that make a glyph matrix adjustment
9881 necessary, do it. */
9882 if (fonts_changed_p)
9883 {
9884 adjust_glyphs (NULL);
9885 ++windows_or_buffers_changed;
9886 fonts_changed_p = 0;
9887 }
9888
9889 /* If face_change_count is non-zero, init_iterator will free all
9890 realized faces, which includes the faces referenced from current
9891 matrices. So, we can't reuse current matrices in this case. */
9892 if (face_change_count)
9893 ++windows_or_buffers_changed;
9894
9895 if (! FRAME_WINDOW_P (sf)
9896 && previous_terminal_frame != sf)
9897 {
9898 /* Since frames on an ASCII terminal share the same display
9899 area, displaying a different frame means redisplay the whole
9900 thing. */
9901 windows_or_buffers_changed++;
9902 SET_FRAME_GARBAGED (sf);
9903 XSETFRAME (Vterminal_frame, sf);
9904 }
9905 previous_terminal_frame = sf;
9906
9907 /* Set the visible flags for all frames. Do this before checking
9908 for resized or garbaged frames; they want to know if their frames
9909 are visible. See the comment in frame.h for
9910 FRAME_SAMPLE_VISIBILITY. */
9911 {
9912 Lisp_Object tail, frame;
9913
9914 number_of_visible_frames = 0;
9915
9916 FOR_EACH_FRAME (tail, frame)
9917 {
9918 struct frame *f = XFRAME (frame);
9919
9920 FRAME_SAMPLE_VISIBILITY (f);
9921 if (FRAME_VISIBLE_P (f))
9922 ++number_of_visible_frames;
9923 clear_desired_matrices (f);
9924 }
9925 }
9926
9927 /* Notice any pending interrupt request to change frame size. */
9928 do_pending_window_change (1);
9929
9930 /* Clear frames marked as garbaged. */
9931 if (frame_garbaged)
9932 clear_garbaged_frames ();
9933
9934 /* Build menubar and tool-bar items. */
9935 prepare_menu_bars ();
9936
9937 if (windows_or_buffers_changed)
9938 update_mode_lines++;
9939
9940 /* Detect case that we need to write or remove a star in the mode line. */
9941 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9942 {
9943 w->update_mode_line = Qt;
9944 if (buffer_shared > 1)
9945 update_mode_lines++;
9946 }
9947
9948 /* If %c is in the mode line, update it if needed. */
9949 if (!NILP (w->column_number_displayed)
9950 /* This alternative quickly identifies a common case
9951 where no change is needed. */
9952 && !(PT == XFASTINT (w->last_point)
9953 && XFASTINT (w->last_modified) >= MODIFF
9954 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9955 && (XFASTINT (w->column_number_displayed)
9956 != (int) current_column ())) /* iftc */
9957 w->update_mode_line = Qt;
9958
9959 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9960
9961 /* The variable buffer_shared is set in redisplay_window and
9962 indicates that we redisplay a buffer in different windows. See
9963 there. */
9964 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9965 || cursor_type_changed);
9966
9967 /* If specs for an arrow have changed, do thorough redisplay
9968 to ensure we remove any arrow that should no longer exist. */
9969 if (overlay_arrows_changed_p ())
9970 consider_all_windows_p = windows_or_buffers_changed = 1;
9971
9972 /* Normally the message* functions will have already displayed and
9973 updated the echo area, but the frame may have been trashed, or
9974 the update may have been preempted, so display the echo area
9975 again here. Checking message_cleared_p captures the case that
9976 the echo area should be cleared. */
9977 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9978 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9979 || (message_cleared_p
9980 && minibuf_level == 0
9981 /* If the mini-window is currently selected, this means the
9982 echo-area doesn't show through. */
9983 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9984 {
9985 int window_height_changed_p = echo_area_display (0);
9986 must_finish = 1;
9987
9988 /* If we don't display the current message, don't clear the
9989 message_cleared_p flag, because, if we did, we wouldn't clear
9990 the echo area in the next redisplay which doesn't preserve
9991 the echo area. */
9992 if (!display_last_displayed_message_p)
9993 message_cleared_p = 0;
9994
9995 if (fonts_changed_p)
9996 goto retry;
9997 else if (window_height_changed_p)
9998 {
9999 consider_all_windows_p = 1;
10000 ++update_mode_lines;
10001 ++windows_or_buffers_changed;
10002
10003 /* If window configuration was changed, frames may have been
10004 marked garbaged. Clear them or we will experience
10005 surprises wrt scrolling. */
10006 if (frame_garbaged)
10007 clear_garbaged_frames ();
10008 }
10009 }
10010 else if (EQ (selected_window, minibuf_window)
10011 && (current_buffer->clip_changed
10012 || XFASTINT (w->last_modified) < MODIFF
10013 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10014 && resize_mini_window (w, 0))
10015 {
10016 /* Resized active mini-window to fit the size of what it is
10017 showing if its contents might have changed. */
10018 must_finish = 1;
10019 consider_all_windows_p = 1;
10020 ++windows_or_buffers_changed;
10021 ++update_mode_lines;
10022
10023 /* If window configuration was changed, frames may have been
10024 marked garbaged. Clear them or we will experience
10025 surprises wrt scrolling. */
10026 if (frame_garbaged)
10027 clear_garbaged_frames ();
10028 }
10029
10030
10031 /* If showing the region, and mark has changed, we must redisplay
10032 the whole window. The assignment to this_line_start_pos prevents
10033 the optimization directly below this if-statement. */
10034 if (((!NILP (Vtransient_mark_mode)
10035 && !NILP (XBUFFER (w->buffer)->mark_active))
10036 != !NILP (w->region_showing))
10037 || (!NILP (w->region_showing)
10038 && !EQ (w->region_showing,
10039 Fmarker_position (XBUFFER (w->buffer)->mark))))
10040 CHARPOS (this_line_start_pos) = 0;
10041
10042 /* Optimize the case that only the line containing the cursor in the
10043 selected window has changed. Variables starting with this_ are
10044 set in display_line and record information about the line
10045 containing the cursor. */
10046 tlbufpos = this_line_start_pos;
10047 tlendpos = this_line_end_pos;
10048 if (!consider_all_windows_p
10049 && CHARPOS (tlbufpos) > 0
10050 && NILP (w->update_mode_line)
10051 && !current_buffer->clip_changed
10052 && !current_buffer->prevent_redisplay_optimizations_p
10053 && FRAME_VISIBLE_P (XFRAME (w->frame))
10054 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10055 /* Make sure recorded data applies to current buffer, etc. */
10056 && this_line_buffer == current_buffer
10057 && current_buffer == XBUFFER (w->buffer)
10058 && NILP (w->force_start)
10059 && NILP (w->optional_new_start)
10060 /* Point must be on the line that we have info recorded about. */
10061 && PT >= CHARPOS (tlbufpos)
10062 && PT <= Z - CHARPOS (tlendpos)
10063 /* All text outside that line, including its final newline,
10064 must be unchanged */
10065 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10066 CHARPOS (tlendpos)))
10067 {
10068 if (CHARPOS (tlbufpos) > BEGV
10069 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10070 && (CHARPOS (tlbufpos) == ZV
10071 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10072 /* Former continuation line has disappeared by becoming empty */
10073 goto cancel;
10074 else if (XFASTINT (w->last_modified) < MODIFF
10075 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10076 || MINI_WINDOW_P (w))
10077 {
10078 /* We have to handle the case of continuation around a
10079 wide-column character (See the comment in indent.c around
10080 line 885).
10081
10082 For instance, in the following case:
10083
10084 -------- Insert --------
10085 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10086 J_I_ ==> J_I_ `^^' are cursors.
10087 ^^ ^^
10088 -------- --------
10089
10090 As we have to redraw the line above, we should goto cancel. */
10091
10092 struct it it;
10093 int line_height_before = this_line_pixel_height;
10094
10095 /* Note that start_display will handle the case that the
10096 line starting at tlbufpos is a continuation lines. */
10097 start_display (&it, w, tlbufpos);
10098
10099 /* Implementation note: It this still necessary? */
10100 if (it.current_x != this_line_start_x)
10101 goto cancel;
10102
10103 TRACE ((stderr, "trying display optimization 1\n"));
10104 w->cursor.vpos = -1;
10105 overlay_arrow_seen = 0;
10106 it.vpos = this_line_vpos;
10107 it.current_y = this_line_y;
10108 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10109 display_line (&it);
10110
10111 /* If line contains point, is not continued,
10112 and ends at same distance from eob as before, we win */
10113 if (w->cursor.vpos >= 0
10114 /* Line is not continued, otherwise this_line_start_pos
10115 would have been set to 0 in display_line. */
10116 && CHARPOS (this_line_start_pos)
10117 /* Line ends as before. */
10118 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10119 /* Line has same height as before. Otherwise other lines
10120 would have to be shifted up or down. */
10121 && this_line_pixel_height == line_height_before)
10122 {
10123 /* If this is not the window's last line, we must adjust
10124 the charstarts of the lines below. */
10125 if (it.current_y < it.last_visible_y)
10126 {
10127 struct glyph_row *row
10128 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10129 int delta, delta_bytes;
10130
10131 if (Z - CHARPOS (tlendpos) == ZV)
10132 {
10133 /* This line ends at end of (accessible part of)
10134 buffer. There is no newline to count. */
10135 delta = (Z
10136 - CHARPOS (tlendpos)
10137 - MATRIX_ROW_START_CHARPOS (row));
10138 delta_bytes = (Z_BYTE
10139 - BYTEPOS (tlendpos)
10140 - MATRIX_ROW_START_BYTEPOS (row));
10141 }
10142 else
10143 {
10144 /* This line ends in a newline. Must take
10145 account of the newline and the rest of the
10146 text that follows. */
10147 delta = (Z
10148 - CHARPOS (tlendpos)
10149 - MATRIX_ROW_START_CHARPOS (row));
10150 delta_bytes = (Z_BYTE
10151 - BYTEPOS (tlendpos)
10152 - MATRIX_ROW_START_BYTEPOS (row));
10153 }
10154
10155 increment_matrix_positions (w->current_matrix,
10156 this_line_vpos + 1,
10157 w->current_matrix->nrows,
10158 delta, delta_bytes);
10159 }
10160
10161 /* If this row displays text now but previously didn't,
10162 or vice versa, w->window_end_vpos may have to be
10163 adjusted. */
10164 if ((it.glyph_row - 1)->displays_text_p)
10165 {
10166 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10167 XSETINT (w->window_end_vpos, this_line_vpos);
10168 }
10169 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10170 && this_line_vpos > 0)
10171 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10172 w->window_end_valid = Qnil;
10173
10174 /* Update hint: No need to try to scroll in update_window. */
10175 w->desired_matrix->no_scrolling_p = 1;
10176
10177 #if GLYPH_DEBUG
10178 *w->desired_matrix->method = 0;
10179 debug_method_add (w, "optimization 1");
10180 #endif
10181 #ifdef HAVE_WINDOW_SYSTEM
10182 update_window_fringes (w, 0);
10183 #endif
10184 goto update;
10185 }
10186 else
10187 goto cancel;
10188 }
10189 else if (/* Cursor position hasn't changed. */
10190 PT == XFASTINT (w->last_point)
10191 /* Make sure the cursor was last displayed
10192 in this window. Otherwise we have to reposition it. */
10193 && 0 <= w->cursor.vpos
10194 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10195 {
10196 if (!must_finish)
10197 {
10198 do_pending_window_change (1);
10199
10200 /* We used to always goto end_of_redisplay here, but this
10201 isn't enough if we have a blinking cursor. */
10202 if (w->cursor_off_p == w->last_cursor_off_p)
10203 goto end_of_redisplay;
10204 }
10205 goto update;
10206 }
10207 /* If highlighting the region, or if the cursor is in the echo area,
10208 then we can't just move the cursor. */
10209 else if (! (!NILP (Vtransient_mark_mode)
10210 && !NILP (current_buffer->mark_active))
10211 && (EQ (selected_window, current_buffer->last_selected_window)
10212 || highlight_nonselected_windows)
10213 && NILP (w->region_showing)
10214 && NILP (Vshow_trailing_whitespace)
10215 && !cursor_in_echo_area)
10216 {
10217 struct it it;
10218 struct glyph_row *row;
10219
10220 /* Skip from tlbufpos to PT and see where it is. Note that
10221 PT may be in invisible text. If so, we will end at the
10222 next visible position. */
10223 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10224 NULL, DEFAULT_FACE_ID);
10225 it.current_x = this_line_start_x;
10226 it.current_y = this_line_y;
10227 it.vpos = this_line_vpos;
10228
10229 /* The call to move_it_to stops in front of PT, but
10230 moves over before-strings. */
10231 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10232
10233 if (it.vpos == this_line_vpos
10234 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10235 row->enabled_p))
10236 {
10237 xassert (this_line_vpos == it.vpos);
10238 xassert (this_line_y == it.current_y);
10239 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10240 #if GLYPH_DEBUG
10241 *w->desired_matrix->method = 0;
10242 debug_method_add (w, "optimization 3");
10243 #endif
10244 goto update;
10245 }
10246 else
10247 goto cancel;
10248 }
10249
10250 cancel:
10251 /* Text changed drastically or point moved off of line. */
10252 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10253 }
10254
10255 CHARPOS (this_line_start_pos) = 0;
10256 consider_all_windows_p |= buffer_shared > 1;
10257 ++clear_face_cache_count;
10258
10259
10260 /* Build desired matrices, and update the display. If
10261 consider_all_windows_p is non-zero, do it for all windows on all
10262 frames. Otherwise do it for selected_window, only. */
10263
10264 if (consider_all_windows_p)
10265 {
10266 Lisp_Object tail, frame;
10267 int i, n = 0, size = 50;
10268 struct frame **updated
10269 = (struct frame **) alloca (size * sizeof *updated);
10270
10271 /* Clear the face cache eventually. */
10272 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10273 {
10274 clear_face_cache (0);
10275 clear_face_cache_count = 0;
10276 }
10277
10278 /* Recompute # windows showing selected buffer. This will be
10279 incremented each time such a window is displayed. */
10280 buffer_shared = 0;
10281
10282 FOR_EACH_FRAME (tail, frame)
10283 {
10284 struct frame *f = XFRAME (frame);
10285
10286 if (FRAME_WINDOW_P (f) || f == sf)
10287 {
10288 if (! EQ (frame, selected_frame))
10289 /* Select the frame, for the sake of frame-local
10290 variables. */
10291 select_frame_for_redisplay (frame);
10292
10293 #ifdef HAVE_WINDOW_SYSTEM
10294 if (clear_face_cache_count % 50 == 0
10295 && FRAME_WINDOW_P (f))
10296 clear_image_cache (f, 0);
10297 #endif /* HAVE_WINDOW_SYSTEM */
10298
10299 /* Mark all the scroll bars to be removed; we'll redeem
10300 the ones we want when we redisplay their windows. */
10301 if (condemn_scroll_bars_hook)
10302 condemn_scroll_bars_hook (f);
10303
10304 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10305 redisplay_windows (FRAME_ROOT_WINDOW (f));
10306
10307 /* Any scroll bars which redisplay_windows should have
10308 nuked should now go away. */
10309 if (judge_scroll_bars_hook)
10310 judge_scroll_bars_hook (f);
10311
10312 /* If fonts changed, display again. */
10313 /* ??? rms: I suspect it is a mistake to jump all the way
10314 back to retry here. It should just retry this frame. */
10315 if (fonts_changed_p)
10316 goto retry;
10317
10318 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10319 {
10320 /* See if we have to hscroll. */
10321 if (hscroll_windows (f->root_window))
10322 goto retry;
10323
10324 /* Prevent various kinds of signals during display
10325 update. stdio is not robust about handling
10326 signals, which can cause an apparent I/O
10327 error. */
10328 if (interrupt_input)
10329 unrequest_sigio ();
10330 STOP_POLLING;
10331
10332 /* Update the display. */
10333 set_window_update_flags (XWINDOW (f->root_window), 1);
10334 pause |= update_frame (f, 0, 0);
10335 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10336 if (pause)
10337 break;
10338 #endif
10339
10340 if (n == size)
10341 {
10342 int nbytes = size * sizeof *updated;
10343 struct frame **p = (struct frame **) alloca (2 * nbytes);
10344 bcopy (updated, p, nbytes);
10345 size *= 2;
10346 }
10347
10348 updated[n++] = f;
10349 }
10350 }
10351 }
10352
10353 if (!pause)
10354 {
10355 /* Do the mark_window_display_accurate after all windows have
10356 been redisplayed because this call resets flags in buffers
10357 which are needed for proper redisplay. */
10358 for (i = 0; i < n; ++i)
10359 {
10360 struct frame *f = updated[i];
10361 mark_window_display_accurate (f->root_window, 1);
10362 if (frame_up_to_date_hook)
10363 frame_up_to_date_hook (f);
10364 }
10365 }
10366 }
10367 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10368 {
10369 Lisp_Object mini_window;
10370 struct frame *mini_frame;
10371
10372 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10373 /* Use list_of_error, not Qerror, so that
10374 we catch only errors and don't run the debugger. */
10375 internal_condition_case_1 (redisplay_window_1, selected_window,
10376 list_of_error,
10377 redisplay_window_error);
10378
10379 /* Compare desired and current matrices, perform output. */
10380
10381 update:
10382 /* If fonts changed, display again. */
10383 if (fonts_changed_p)
10384 goto retry;
10385
10386 /* Prevent various kinds of signals during display update.
10387 stdio is not robust about handling signals,
10388 which can cause an apparent I/O error. */
10389 if (interrupt_input)
10390 unrequest_sigio ();
10391 STOP_POLLING;
10392
10393 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10394 {
10395 if (hscroll_windows (selected_window))
10396 goto retry;
10397
10398 XWINDOW (selected_window)->must_be_updated_p = 1;
10399 pause = update_frame (sf, 0, 0);
10400 }
10401
10402 /* We may have called echo_area_display at the top of this
10403 function. If the echo area is on another frame, that may
10404 have put text on a frame other than the selected one, so the
10405 above call to update_frame would not have caught it. Catch
10406 it here. */
10407 mini_window = FRAME_MINIBUF_WINDOW (sf);
10408 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10409
10410 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10411 {
10412 XWINDOW (mini_window)->must_be_updated_p = 1;
10413 pause |= update_frame (mini_frame, 0, 0);
10414 if (!pause && hscroll_windows (mini_window))
10415 goto retry;
10416 }
10417 }
10418
10419 /* If display was paused because of pending input, make sure we do a
10420 thorough update the next time. */
10421 if (pause)
10422 {
10423 /* Prevent the optimization at the beginning of
10424 redisplay_internal that tries a single-line update of the
10425 line containing the cursor in the selected window. */
10426 CHARPOS (this_line_start_pos) = 0;
10427
10428 /* Let the overlay arrow be updated the next time. */
10429 update_overlay_arrows (0);
10430
10431 /* If we pause after scrolling, some rows in the current
10432 matrices of some windows are not valid. */
10433 if (!WINDOW_FULL_WIDTH_P (w)
10434 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10435 update_mode_lines = 1;
10436 }
10437 else
10438 {
10439 if (!consider_all_windows_p)
10440 {
10441 /* This has already been done above if
10442 consider_all_windows_p is set. */
10443 mark_window_display_accurate_1 (w, 1);
10444
10445 /* Say overlay arrows are up to date. */
10446 update_overlay_arrows (1);
10447
10448 if (frame_up_to_date_hook != 0)
10449 frame_up_to_date_hook (sf);
10450 }
10451
10452 update_mode_lines = 0;
10453 windows_or_buffers_changed = 0;
10454 cursor_type_changed = 0;
10455 }
10456
10457 /* Start SIGIO interrupts coming again. Having them off during the
10458 code above makes it less likely one will discard output, but not
10459 impossible, since there might be stuff in the system buffer here.
10460 But it is much hairier to try to do anything about that. */
10461 if (interrupt_input)
10462 request_sigio ();
10463 RESUME_POLLING;
10464
10465 /* If a frame has become visible which was not before, redisplay
10466 again, so that we display it. Expose events for such a frame
10467 (which it gets when becoming visible) don't call the parts of
10468 redisplay constructing glyphs, so simply exposing a frame won't
10469 display anything in this case. So, we have to display these
10470 frames here explicitly. */
10471 if (!pause)
10472 {
10473 Lisp_Object tail, frame;
10474 int new_count = 0;
10475
10476 FOR_EACH_FRAME (tail, frame)
10477 {
10478 int this_is_visible = 0;
10479
10480 if (XFRAME (frame)->visible)
10481 this_is_visible = 1;
10482 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10483 if (XFRAME (frame)->visible)
10484 this_is_visible = 1;
10485
10486 if (this_is_visible)
10487 new_count++;
10488 }
10489
10490 if (new_count != number_of_visible_frames)
10491 windows_or_buffers_changed++;
10492 }
10493
10494 /* Change frame size now if a change is pending. */
10495 do_pending_window_change (1);
10496
10497 /* If we just did a pending size change, or have additional
10498 visible frames, redisplay again. */
10499 if (windows_or_buffers_changed && !pause)
10500 goto retry;
10501
10502 end_of_redisplay:
10503 unbind_to (count, Qnil);
10504 RESUME_POLLING;
10505 }
10506
10507
10508 /* Redisplay, but leave alone any recent echo area message unless
10509 another message has been requested in its place.
10510
10511 This is useful in situations where you need to redisplay but no
10512 user action has occurred, making it inappropriate for the message
10513 area to be cleared. See tracking_off and
10514 wait_reading_process_output for examples of these situations.
10515
10516 FROM_WHERE is an integer saying from where this function was
10517 called. This is useful for debugging. */
10518
10519 void
10520 redisplay_preserve_echo_area (from_where)
10521 int from_where;
10522 {
10523 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10524
10525 if (!NILP (echo_area_buffer[1]))
10526 {
10527 /* We have a previously displayed message, but no current
10528 message. Redisplay the previous message. */
10529 display_last_displayed_message_p = 1;
10530 redisplay_internal (1);
10531 display_last_displayed_message_p = 0;
10532 }
10533 else
10534 redisplay_internal (1);
10535
10536 if (rif != NULL && rif->flush_display_optional)
10537 rif->flush_display_optional (NULL);
10538 }
10539
10540
10541 /* Function registered with record_unwind_protect in
10542 redisplay_internal. Reset redisplaying_p to the value it had
10543 before redisplay_internal was called, and clear
10544 prevent_freeing_realized_faces_p. It also selects the previously
10545 selected frame. */
10546
10547 static Lisp_Object
10548 unwind_redisplay (val)
10549 Lisp_Object val;
10550 {
10551 Lisp_Object old_redisplaying_p, old_frame;
10552
10553 old_redisplaying_p = XCAR (val);
10554 redisplaying_p = XFASTINT (old_redisplaying_p);
10555 old_frame = XCDR (val);
10556 if (! EQ (old_frame, selected_frame))
10557 select_frame_for_redisplay (old_frame);
10558 return Qnil;
10559 }
10560
10561
10562 /* Mark the display of window W as accurate or inaccurate. If
10563 ACCURATE_P is non-zero mark display of W as accurate. If
10564 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10565 redisplay_internal is called. */
10566
10567 static void
10568 mark_window_display_accurate_1 (w, accurate_p)
10569 struct window *w;
10570 int accurate_p;
10571 {
10572 if (BUFFERP (w->buffer))
10573 {
10574 struct buffer *b = XBUFFER (w->buffer);
10575
10576 w->last_modified
10577 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10578 w->last_overlay_modified
10579 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10580 w->last_had_star
10581 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10582
10583 if (accurate_p)
10584 {
10585 b->clip_changed = 0;
10586 b->prevent_redisplay_optimizations_p = 0;
10587
10588 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10589 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10590 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10591 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10592
10593 w->current_matrix->buffer = b;
10594 w->current_matrix->begv = BUF_BEGV (b);
10595 w->current_matrix->zv = BUF_ZV (b);
10596
10597 w->last_cursor = w->cursor;
10598 w->last_cursor_off_p = w->cursor_off_p;
10599
10600 if (w == XWINDOW (selected_window))
10601 w->last_point = make_number (BUF_PT (b));
10602 else
10603 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10604 }
10605 }
10606
10607 if (accurate_p)
10608 {
10609 w->window_end_valid = w->buffer;
10610 #if 0 /* This is incorrect with variable-height lines. */
10611 xassert (XINT (w->window_end_vpos)
10612 < (WINDOW_TOTAL_LINES (w)
10613 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10614 #endif
10615 w->update_mode_line = Qnil;
10616 }
10617 }
10618
10619
10620 /* Mark the display of windows in the window tree rooted at WINDOW as
10621 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10622 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10623 be redisplayed the next time redisplay_internal is called. */
10624
10625 void
10626 mark_window_display_accurate (window, accurate_p)
10627 Lisp_Object window;
10628 int accurate_p;
10629 {
10630 struct window *w;
10631
10632 for (; !NILP (window); window = w->next)
10633 {
10634 w = XWINDOW (window);
10635 mark_window_display_accurate_1 (w, accurate_p);
10636
10637 if (!NILP (w->vchild))
10638 mark_window_display_accurate (w->vchild, accurate_p);
10639 if (!NILP (w->hchild))
10640 mark_window_display_accurate (w->hchild, accurate_p);
10641 }
10642
10643 if (accurate_p)
10644 {
10645 update_overlay_arrows (1);
10646 }
10647 else
10648 {
10649 /* Force a thorough redisplay the next time by setting
10650 last_arrow_position and last_arrow_string to t, which is
10651 unequal to any useful value of Voverlay_arrow_... */
10652 update_overlay_arrows (-1);
10653 }
10654 }
10655
10656
10657 /* Return value in display table DP (Lisp_Char_Table *) for character
10658 C. Since a display table doesn't have any parent, we don't have to
10659 follow parent. Do not call this function directly but use the
10660 macro DISP_CHAR_VECTOR. */
10661
10662 Lisp_Object
10663 disp_char_vector (dp, c)
10664 struct Lisp_Char_Table *dp;
10665 int c;
10666 {
10667 Lisp_Object val;
10668
10669 if (ASCII_CHAR_P (c))
10670 {
10671 val = dp->ascii;
10672 if (SUB_CHAR_TABLE_P (val))
10673 val = XSUB_CHAR_TABLE (val)->contents[c];
10674 }
10675 else
10676 {
10677 Lisp_Object table;
10678
10679 XSETCHAR_TABLE (table, dp);
10680 val = char_table_ref (table, c);
10681 }
10682 if (NILP (val))
10683 val = dp->defalt;
10684 return val;
10685 }
10686
10687
10688 \f
10689 /***********************************************************************
10690 Window Redisplay
10691 ***********************************************************************/
10692
10693 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10694
10695 static void
10696 redisplay_windows (window)
10697 Lisp_Object window;
10698 {
10699 while (!NILP (window))
10700 {
10701 struct window *w = XWINDOW (window);
10702
10703 if (!NILP (w->hchild))
10704 redisplay_windows (w->hchild);
10705 else if (!NILP (w->vchild))
10706 redisplay_windows (w->vchild);
10707 else
10708 {
10709 displayed_buffer = XBUFFER (w->buffer);
10710 /* Use list_of_error, not Qerror, so that
10711 we catch only errors and don't run the debugger. */
10712 internal_condition_case_1 (redisplay_window_0, window,
10713 list_of_error,
10714 redisplay_window_error);
10715 }
10716
10717 window = w->next;
10718 }
10719 }
10720
10721 static Lisp_Object
10722 redisplay_window_error ()
10723 {
10724 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10725 return Qnil;
10726 }
10727
10728 static Lisp_Object
10729 redisplay_window_0 (window)
10730 Lisp_Object window;
10731 {
10732 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10733 redisplay_window (window, 0);
10734 return Qnil;
10735 }
10736
10737 static Lisp_Object
10738 redisplay_window_1 (window)
10739 Lisp_Object window;
10740 {
10741 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10742 redisplay_window (window, 1);
10743 return Qnil;
10744 }
10745 \f
10746
10747 /* Increment GLYPH until it reaches END or CONDITION fails while
10748 adding (GLYPH)->pixel_width to X. */
10749
10750 #define SKIP_GLYPHS(glyph, end, x, condition) \
10751 do \
10752 { \
10753 (x) += (glyph)->pixel_width; \
10754 ++(glyph); \
10755 } \
10756 while ((glyph) < (end) && (condition))
10757
10758
10759 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10760 DELTA is the number of bytes by which positions recorded in ROW
10761 differ from current buffer positions. */
10762
10763 void
10764 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10765 struct window *w;
10766 struct glyph_row *row;
10767 struct glyph_matrix *matrix;
10768 int delta, delta_bytes, dy, dvpos;
10769 {
10770 struct glyph *glyph = row->glyphs[TEXT_AREA];
10771 struct glyph *end = glyph + row->used[TEXT_AREA];
10772 struct glyph *cursor = NULL;
10773 /* The first glyph that starts a sequence of glyphs from string. */
10774 struct glyph *string_start;
10775 /* The X coordinate of string_start. */
10776 int string_start_x;
10777 /* The last known character position. */
10778 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10779 /* The last known character position before string_start. */
10780 int string_before_pos;
10781 int x = row->x;
10782 int cursor_x = x;
10783 int cursor_from_overlay_pos = 0;
10784 int pt_old = PT - delta;
10785
10786 /* Skip over glyphs not having an object at the start of the row.
10787 These are special glyphs like truncation marks on terminal
10788 frames. */
10789 if (row->displays_text_p)
10790 while (glyph < end
10791 && INTEGERP (glyph->object)
10792 && glyph->charpos < 0)
10793 {
10794 x += glyph->pixel_width;
10795 ++glyph;
10796 }
10797
10798 string_start = NULL;
10799 while (glyph < end
10800 && !INTEGERP (glyph->object)
10801 && (!BUFFERP (glyph->object)
10802 || (last_pos = glyph->charpos) < pt_old))
10803 {
10804 if (! STRINGP (glyph->object))
10805 {
10806 string_start = NULL;
10807 x += glyph->pixel_width;
10808 ++glyph;
10809 if (cursor_from_overlay_pos
10810 && last_pos > cursor_from_overlay_pos)
10811 {
10812 cursor_from_overlay_pos = 0;
10813 cursor = 0;
10814 }
10815 }
10816 else
10817 {
10818 string_before_pos = last_pos;
10819 string_start = glyph;
10820 string_start_x = x;
10821 /* Skip all glyphs from string. */
10822 do
10823 {
10824 int pos;
10825 if ((cursor == NULL || glyph > cursor)
10826 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10827 Qcursor, (glyph)->object))
10828 && (pos = string_buffer_position (w, glyph->object,
10829 string_before_pos),
10830 (pos == 0 /* From overlay */
10831 || pos == pt_old)))
10832 {
10833 /* Estimate overlay buffer position from the buffer
10834 positions of the glyphs before and after the overlay.
10835 Add 1 to last_pos so that if point corresponds to the
10836 glyph right after the overlay, we still use a 'cursor'
10837 property found in that overlay. */
10838 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10839 cursor = glyph;
10840 cursor_x = x;
10841 }
10842 x += glyph->pixel_width;
10843 ++glyph;
10844 }
10845 while (glyph < end && STRINGP (glyph->object));
10846 }
10847 }
10848
10849 if (cursor != NULL)
10850 {
10851 glyph = cursor;
10852 x = cursor_x;
10853 }
10854 else if (string_start
10855 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10856 {
10857 /* We may have skipped over point because the previous glyphs
10858 are from string. As there's no easy way to know the
10859 character position of the current glyph, find the correct
10860 glyph on point by scanning from string_start again. */
10861 Lisp_Object limit;
10862 Lisp_Object string;
10863 int pos;
10864
10865 limit = make_number (pt_old + 1);
10866 end = glyph;
10867 glyph = string_start;
10868 x = string_start_x;
10869 string = glyph->object;
10870 pos = string_buffer_position (w, string, string_before_pos);
10871 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10872 because we always put cursor after overlay strings. */
10873 while (pos == 0 && glyph < end)
10874 {
10875 string = glyph->object;
10876 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10877 if (glyph < end)
10878 pos = string_buffer_position (w, glyph->object, string_before_pos);
10879 }
10880
10881 while (glyph < end)
10882 {
10883 pos = XINT (Fnext_single_char_property_change
10884 (make_number (pos), Qdisplay, Qnil, limit));
10885 if (pos > pt_old)
10886 break;
10887 /* Skip glyphs from the same string. */
10888 string = glyph->object;
10889 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10890 /* Skip glyphs from an overlay. */
10891 while (glyph < end
10892 && ! string_buffer_position (w, glyph->object, pos))
10893 {
10894 string = glyph->object;
10895 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10896 }
10897 }
10898 }
10899
10900 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10901 w->cursor.x = x;
10902 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10903 w->cursor.y = row->y + dy;
10904
10905 if (w == XWINDOW (selected_window))
10906 {
10907 if (!row->continued_p
10908 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10909 && row->x == 0)
10910 {
10911 this_line_buffer = XBUFFER (w->buffer);
10912
10913 CHARPOS (this_line_start_pos)
10914 = MATRIX_ROW_START_CHARPOS (row) + delta;
10915 BYTEPOS (this_line_start_pos)
10916 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10917
10918 CHARPOS (this_line_end_pos)
10919 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10920 BYTEPOS (this_line_end_pos)
10921 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10922
10923 this_line_y = w->cursor.y;
10924 this_line_pixel_height = row->height;
10925 this_line_vpos = w->cursor.vpos;
10926 this_line_start_x = row->x;
10927 }
10928 else
10929 CHARPOS (this_line_start_pos) = 0;
10930 }
10931 }
10932
10933
10934 /* Run window scroll functions, if any, for WINDOW with new window
10935 start STARTP. Sets the window start of WINDOW to that position.
10936
10937 We assume that the window's buffer is really current. */
10938
10939 static INLINE struct text_pos
10940 run_window_scroll_functions (window, startp)
10941 Lisp_Object window;
10942 struct text_pos startp;
10943 {
10944 struct window *w = XWINDOW (window);
10945 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10946
10947 if (current_buffer != XBUFFER (w->buffer))
10948 abort ();
10949
10950 if (!NILP (Vwindow_scroll_functions))
10951 {
10952 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10953 make_number (CHARPOS (startp)));
10954 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10955 /* In case the hook functions switch buffers. */
10956 if (current_buffer != XBUFFER (w->buffer))
10957 set_buffer_internal_1 (XBUFFER (w->buffer));
10958 }
10959
10960 return startp;
10961 }
10962
10963
10964 /* Make sure the line containing the cursor is fully visible.
10965 A value of 1 means there is nothing to be done.
10966 (Either the line is fully visible, or it cannot be made so,
10967 or we cannot tell.)
10968
10969 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10970 is higher than window.
10971
10972 A value of 0 means the caller should do scrolling
10973 as if point had gone off the screen. */
10974
10975 static int
10976 make_cursor_line_fully_visible (w, force_p)
10977 struct window *w;
10978 int force_p;
10979 {
10980 struct glyph_matrix *matrix;
10981 struct glyph_row *row;
10982 int window_height;
10983
10984 /* It's not always possible to find the cursor, e.g, when a window
10985 is full of overlay strings. Don't do anything in that case. */
10986 if (w->cursor.vpos < 0)
10987 return 1;
10988
10989 matrix = w->desired_matrix;
10990 row = MATRIX_ROW (matrix, w->cursor.vpos);
10991
10992 /* If the cursor row is not partially visible, there's nothing to do. */
10993 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10994 return 1;
10995
10996 /* If the row the cursor is in is taller than the window's height,
10997 it's not clear what to do, so do nothing. */
10998 window_height = window_box_height (w);
10999 if (row->height >= window_height)
11000 {
11001 if (!force_p || w->vscroll)
11002 return 1;
11003 }
11004 return 0;
11005
11006 #if 0
11007 /* This code used to try to scroll the window just enough to make
11008 the line visible. It returned 0 to say that the caller should
11009 allocate larger glyph matrices. */
11010
11011 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11012 {
11013 int dy = row->height - row->visible_height;
11014 w->vscroll = 0;
11015 w->cursor.y += dy;
11016 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11017 }
11018 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11019 {
11020 int dy = - (row->height - row->visible_height);
11021 w->vscroll = dy;
11022 w->cursor.y += dy;
11023 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11024 }
11025
11026 /* When we change the cursor y-position of the selected window,
11027 change this_line_y as well so that the display optimization for
11028 the cursor line of the selected window in redisplay_internal uses
11029 the correct y-position. */
11030 if (w == XWINDOW (selected_window))
11031 this_line_y = w->cursor.y;
11032
11033 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11034 redisplay with larger matrices. */
11035 if (matrix->nrows < required_matrix_height (w))
11036 {
11037 fonts_changed_p = 1;
11038 return 0;
11039 }
11040
11041 return 1;
11042 #endif /* 0 */
11043 }
11044
11045
11046 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11047 non-zero means only WINDOW is redisplayed in redisplay_internal.
11048 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11049 in redisplay_window to bring a partially visible line into view in
11050 the case that only the cursor has moved.
11051
11052 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11053 last screen line's vertical height extends past the end of the screen.
11054
11055 Value is
11056
11057 1 if scrolling succeeded
11058
11059 0 if scrolling didn't find point.
11060
11061 -1 if new fonts have been loaded so that we must interrupt
11062 redisplay, adjust glyph matrices, and try again. */
11063
11064 enum
11065 {
11066 SCROLLING_SUCCESS,
11067 SCROLLING_FAILED,
11068 SCROLLING_NEED_LARGER_MATRICES
11069 };
11070
11071 static int
11072 try_scrolling (window, just_this_one_p, scroll_conservatively,
11073 scroll_step, temp_scroll_step, last_line_misfit)
11074 Lisp_Object window;
11075 int just_this_one_p;
11076 EMACS_INT scroll_conservatively, scroll_step;
11077 int temp_scroll_step;
11078 int last_line_misfit;
11079 {
11080 struct window *w = XWINDOW (window);
11081 struct frame *f = XFRAME (w->frame);
11082 struct text_pos scroll_margin_pos;
11083 struct text_pos pos;
11084 struct text_pos startp;
11085 struct it it;
11086 Lisp_Object window_end;
11087 int this_scroll_margin;
11088 int dy = 0;
11089 int scroll_max;
11090 int rc;
11091 int amount_to_scroll = 0;
11092 Lisp_Object aggressive;
11093 int height;
11094 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11095
11096 #if GLYPH_DEBUG
11097 debug_method_add (w, "try_scrolling");
11098 #endif
11099
11100 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11101
11102 /* Compute scroll margin height in pixels. We scroll when point is
11103 within this distance from the top or bottom of the window. */
11104 if (scroll_margin > 0)
11105 {
11106 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11107 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11108 }
11109 else
11110 this_scroll_margin = 0;
11111
11112 /* Force scroll_conservatively to have a reasonable value so it doesn't
11113 cause an overflow while computing how much to scroll. */
11114 if (scroll_conservatively)
11115 scroll_conservatively = min (scroll_conservatively,
11116 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11117
11118 /* Compute how much we should try to scroll maximally to bring point
11119 into view. */
11120 if (scroll_step || scroll_conservatively || temp_scroll_step)
11121 scroll_max = max (scroll_step,
11122 max (scroll_conservatively, temp_scroll_step));
11123 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11124 || NUMBERP (current_buffer->scroll_up_aggressively))
11125 /* We're trying to scroll because of aggressive scrolling
11126 but no scroll_step is set. Choose an arbitrary one. Maybe
11127 there should be a variable for this. */
11128 scroll_max = 10;
11129 else
11130 scroll_max = 0;
11131 scroll_max *= FRAME_LINE_HEIGHT (f);
11132
11133 /* Decide whether we have to scroll down. Start at the window end
11134 and move this_scroll_margin up to find the position of the scroll
11135 margin. */
11136 window_end = Fwindow_end (window, Qt);
11137
11138 too_near_end:
11139
11140 CHARPOS (scroll_margin_pos) = XINT (window_end);
11141 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11142
11143 if (this_scroll_margin || extra_scroll_margin_lines)
11144 {
11145 start_display (&it, w, scroll_margin_pos);
11146 if (this_scroll_margin)
11147 move_it_vertically (&it, - this_scroll_margin);
11148 if (extra_scroll_margin_lines)
11149 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11150 scroll_margin_pos = it.current.pos;
11151 }
11152
11153 if (PT >= CHARPOS (scroll_margin_pos))
11154 {
11155 int y0;
11156
11157 /* Point is in the scroll margin at the bottom of the window, or
11158 below. Compute a new window start that makes point visible. */
11159
11160 /* Compute the distance from the scroll margin to PT.
11161 Give up if the distance is greater than scroll_max. */
11162 start_display (&it, w, scroll_margin_pos);
11163 y0 = it.current_y;
11164 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11165 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11166
11167 /* To make point visible, we have to move the window start
11168 down so that the line the cursor is in is visible, which
11169 means we have to add in the height of the cursor line. */
11170 dy = line_bottom_y (&it) - y0;
11171
11172 if (dy > scroll_max)
11173 return SCROLLING_FAILED;
11174
11175 /* Move the window start down. If scrolling conservatively,
11176 move it just enough down to make point visible. If
11177 scroll_step is set, move it down by scroll_step. */
11178 start_display (&it, w, startp);
11179
11180 if (scroll_conservatively)
11181 /* Set AMOUNT_TO_SCROLL to at least one line,
11182 and at most scroll_conservatively lines. */
11183 amount_to_scroll
11184 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11185 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11186 else if (scroll_step || temp_scroll_step)
11187 amount_to_scroll = scroll_max;
11188 else
11189 {
11190 aggressive = current_buffer->scroll_up_aggressively;
11191 height = WINDOW_BOX_TEXT_HEIGHT (w);
11192 if (NUMBERP (aggressive))
11193 {
11194 double float_amount = XFLOATINT (aggressive) * height;
11195 amount_to_scroll = float_amount;
11196 if (amount_to_scroll == 0 && float_amount > 0)
11197 amount_to_scroll = 1;
11198 }
11199 }
11200
11201 if (amount_to_scroll <= 0)
11202 return SCROLLING_FAILED;
11203
11204 /* If moving by amount_to_scroll leaves STARTP unchanged,
11205 move it down one screen line. */
11206
11207 move_it_vertically (&it, amount_to_scroll);
11208 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11209 move_it_by_lines (&it, 1, 1);
11210 startp = it.current.pos;
11211 }
11212 else
11213 {
11214 /* See if point is inside the scroll margin at the top of the
11215 window. */
11216 scroll_margin_pos = startp;
11217 if (this_scroll_margin)
11218 {
11219 start_display (&it, w, startp);
11220 move_it_vertically (&it, this_scroll_margin);
11221 scroll_margin_pos = it.current.pos;
11222 }
11223
11224 if (PT < CHARPOS (scroll_margin_pos))
11225 {
11226 /* Point is in the scroll margin at the top of the window or
11227 above what is displayed in the window. */
11228 int y0;
11229
11230 /* Compute the vertical distance from PT to the scroll
11231 margin position. Give up if distance is greater than
11232 scroll_max. */
11233 SET_TEXT_POS (pos, PT, PT_BYTE);
11234 start_display (&it, w, pos);
11235 y0 = it.current_y;
11236 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11237 it.last_visible_y, -1,
11238 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11239 dy = it.current_y - y0;
11240 if (dy > scroll_max)
11241 return SCROLLING_FAILED;
11242
11243 /* Compute new window start. */
11244 start_display (&it, w, startp);
11245
11246 if (scroll_conservatively)
11247 amount_to_scroll
11248 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11249 else if (scroll_step || temp_scroll_step)
11250 amount_to_scroll = scroll_max;
11251 else
11252 {
11253 aggressive = current_buffer->scroll_down_aggressively;
11254 height = WINDOW_BOX_TEXT_HEIGHT (w);
11255 if (NUMBERP (aggressive))
11256 {
11257 double float_amount = XFLOATINT (aggressive) * height;
11258 amount_to_scroll = float_amount;
11259 if (amount_to_scroll == 0 && float_amount > 0)
11260 amount_to_scroll = 1;
11261 }
11262 }
11263
11264 if (amount_to_scroll <= 0)
11265 return SCROLLING_FAILED;
11266
11267 move_it_vertically (&it, - amount_to_scroll);
11268 startp = it.current.pos;
11269 }
11270 }
11271
11272 /* Run window scroll functions. */
11273 startp = run_window_scroll_functions (window, startp);
11274
11275 /* Display the window. Give up if new fonts are loaded, or if point
11276 doesn't appear. */
11277 if (!try_window (window, startp))
11278 rc = SCROLLING_NEED_LARGER_MATRICES;
11279 else if (w->cursor.vpos < 0)
11280 {
11281 clear_glyph_matrix (w->desired_matrix);
11282 rc = SCROLLING_FAILED;
11283 }
11284 else
11285 {
11286 /* Maybe forget recorded base line for line number display. */
11287 if (!just_this_one_p
11288 || current_buffer->clip_changed
11289 || BEG_UNCHANGED < CHARPOS (startp))
11290 w->base_line_number = Qnil;
11291
11292 /* If cursor ends up on a partially visible line,
11293 treat that as being off the bottom of the screen. */
11294 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11295 {
11296 clear_glyph_matrix (w->desired_matrix);
11297 ++extra_scroll_margin_lines;
11298 goto too_near_end;
11299 }
11300 rc = SCROLLING_SUCCESS;
11301 }
11302
11303 return rc;
11304 }
11305
11306
11307 /* Compute a suitable window start for window W if display of W starts
11308 on a continuation line. Value is non-zero if a new window start
11309 was computed.
11310
11311 The new window start will be computed, based on W's width, starting
11312 from the start of the continued line. It is the start of the
11313 screen line with the minimum distance from the old start W->start. */
11314
11315 static int
11316 compute_window_start_on_continuation_line (w)
11317 struct window *w;
11318 {
11319 struct text_pos pos, start_pos;
11320 int window_start_changed_p = 0;
11321
11322 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11323
11324 /* If window start is on a continuation line... Window start may be
11325 < BEGV in case there's invisible text at the start of the
11326 buffer (M-x rmail, for example). */
11327 if (CHARPOS (start_pos) > BEGV
11328 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11329 {
11330 struct it it;
11331 struct glyph_row *row;
11332
11333 /* Handle the case that the window start is out of range. */
11334 if (CHARPOS (start_pos) < BEGV)
11335 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11336 else if (CHARPOS (start_pos) > ZV)
11337 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11338
11339 /* Find the start of the continued line. This should be fast
11340 because scan_buffer is fast (newline cache). */
11341 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11342 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11343 row, DEFAULT_FACE_ID);
11344 reseat_at_previous_visible_line_start (&it);
11345
11346 /* If the line start is "too far" away from the window start,
11347 say it takes too much time to compute a new window start. */
11348 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11349 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11350 {
11351 int min_distance, distance;
11352
11353 /* Move forward by display lines to find the new window
11354 start. If window width was enlarged, the new start can
11355 be expected to be > the old start. If window width was
11356 decreased, the new window start will be < the old start.
11357 So, we're looking for the display line start with the
11358 minimum distance from the old window start. */
11359 pos = it.current.pos;
11360 min_distance = INFINITY;
11361 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11362 distance < min_distance)
11363 {
11364 min_distance = distance;
11365 pos = it.current.pos;
11366 move_it_by_lines (&it, 1, 0);
11367 }
11368
11369 /* Set the window start there. */
11370 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11371 window_start_changed_p = 1;
11372 }
11373 }
11374
11375 return window_start_changed_p;
11376 }
11377
11378
11379 /* Try cursor movement in case text has not changed in window WINDOW,
11380 with window start STARTP. Value is
11381
11382 CURSOR_MOVEMENT_SUCCESS if successful
11383
11384 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11385
11386 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11387 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11388 we want to scroll as if scroll-step were set to 1. See the code.
11389
11390 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11391 which case we have to abort this redisplay, and adjust matrices
11392 first. */
11393
11394 enum
11395 {
11396 CURSOR_MOVEMENT_SUCCESS,
11397 CURSOR_MOVEMENT_CANNOT_BE_USED,
11398 CURSOR_MOVEMENT_MUST_SCROLL,
11399 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11400 };
11401
11402 static int
11403 try_cursor_movement (window, startp, scroll_step)
11404 Lisp_Object window;
11405 struct text_pos startp;
11406 int *scroll_step;
11407 {
11408 struct window *w = XWINDOW (window);
11409 struct frame *f = XFRAME (w->frame);
11410 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11411
11412 #if GLYPH_DEBUG
11413 if (inhibit_try_cursor_movement)
11414 return rc;
11415 #endif
11416
11417 /* Handle case where text has not changed, only point, and it has
11418 not moved off the frame. */
11419 if (/* Point may be in this window. */
11420 PT >= CHARPOS (startp)
11421 /* Selective display hasn't changed. */
11422 && !current_buffer->clip_changed
11423 /* Function force-mode-line-update is used to force a thorough
11424 redisplay. It sets either windows_or_buffers_changed or
11425 update_mode_lines. So don't take a shortcut here for these
11426 cases. */
11427 && !update_mode_lines
11428 && !windows_or_buffers_changed
11429 && !cursor_type_changed
11430 /* Can't use this case if highlighting a region. When a
11431 region exists, cursor movement has to do more than just
11432 set the cursor. */
11433 && !(!NILP (Vtransient_mark_mode)
11434 && !NILP (current_buffer->mark_active))
11435 && NILP (w->region_showing)
11436 && NILP (Vshow_trailing_whitespace)
11437 /* Right after splitting windows, last_point may be nil. */
11438 && INTEGERP (w->last_point)
11439 /* This code is not used for mini-buffer for the sake of the case
11440 of redisplaying to replace an echo area message; since in
11441 that case the mini-buffer contents per se are usually
11442 unchanged. This code is of no real use in the mini-buffer
11443 since the handling of this_line_start_pos, etc., in redisplay
11444 handles the same cases. */
11445 && !EQ (window, minibuf_window)
11446 /* When splitting windows or for new windows, it happens that
11447 redisplay is called with a nil window_end_vpos or one being
11448 larger than the window. This should really be fixed in
11449 window.c. I don't have this on my list, now, so we do
11450 approximately the same as the old redisplay code. --gerd. */
11451 && INTEGERP (w->window_end_vpos)
11452 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11453 && (FRAME_WINDOW_P (f)
11454 || !overlay_arrow_in_current_buffer_p ()))
11455 {
11456 int this_scroll_margin, top_scroll_margin;
11457 struct glyph_row *row = NULL;
11458
11459 #if GLYPH_DEBUG
11460 debug_method_add (w, "cursor movement");
11461 #endif
11462
11463 /* Scroll if point within this distance from the top or bottom
11464 of the window. This is a pixel value. */
11465 this_scroll_margin = max (0, scroll_margin);
11466 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11467 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11468
11469 top_scroll_margin = this_scroll_margin;
11470 if (WINDOW_WANTS_HEADER_LINE_P (w))
11471 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11472
11473 /* Start with the row the cursor was displayed during the last
11474 not paused redisplay. Give up if that row is not valid. */
11475 if (w->last_cursor.vpos < 0
11476 || w->last_cursor.vpos >= w->current_matrix->nrows)
11477 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11478 else
11479 {
11480 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11481 if (row->mode_line_p)
11482 ++row;
11483 if (!row->enabled_p)
11484 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11485 }
11486
11487 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11488 {
11489 int scroll_p = 0;
11490 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11491
11492 if (PT > XFASTINT (w->last_point))
11493 {
11494 /* Point has moved forward. */
11495 while (MATRIX_ROW_END_CHARPOS (row) < PT
11496 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11497 {
11498 xassert (row->enabled_p);
11499 ++row;
11500 }
11501
11502 /* The end position of a row equals the start position
11503 of the next row. If PT is there, we would rather
11504 display it in the next line. */
11505 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11506 && MATRIX_ROW_END_CHARPOS (row) == PT
11507 && !cursor_row_p (w, row))
11508 ++row;
11509
11510 /* If within the scroll margin, scroll. Note that
11511 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11512 the next line would be drawn, and that
11513 this_scroll_margin can be zero. */
11514 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11515 || PT > MATRIX_ROW_END_CHARPOS (row)
11516 /* Line is completely visible last line in window
11517 and PT is to be set in the next line. */
11518 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11519 && PT == MATRIX_ROW_END_CHARPOS (row)
11520 && !row->ends_at_zv_p
11521 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11522 scroll_p = 1;
11523 }
11524 else if (PT < XFASTINT (w->last_point))
11525 {
11526 /* Cursor has to be moved backward. Note that PT >=
11527 CHARPOS (startp) because of the outer if-statement. */
11528 while (!row->mode_line_p
11529 && (MATRIX_ROW_START_CHARPOS (row) > PT
11530 || (MATRIX_ROW_START_CHARPOS (row) == PT
11531 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11532 && (row->y > top_scroll_margin
11533 || CHARPOS (startp) == BEGV))
11534 {
11535 xassert (row->enabled_p);
11536 --row;
11537 }
11538
11539 /* Consider the following case: Window starts at BEGV,
11540 there is invisible, intangible text at BEGV, so that
11541 display starts at some point START > BEGV. It can
11542 happen that we are called with PT somewhere between
11543 BEGV and START. Try to handle that case. */
11544 if (row < w->current_matrix->rows
11545 || row->mode_line_p)
11546 {
11547 row = w->current_matrix->rows;
11548 if (row->mode_line_p)
11549 ++row;
11550 }
11551
11552 /* Due to newlines in overlay strings, we may have to
11553 skip forward over overlay strings. */
11554 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11555 && MATRIX_ROW_END_CHARPOS (row) == PT
11556 && !cursor_row_p (w, row))
11557 ++row;
11558
11559 /* If within the scroll margin, scroll. */
11560 if (row->y < top_scroll_margin
11561 && CHARPOS (startp) != BEGV)
11562 scroll_p = 1;
11563 }
11564
11565 if (PT < MATRIX_ROW_START_CHARPOS (row)
11566 || PT > MATRIX_ROW_END_CHARPOS (row))
11567 {
11568 /* if PT is not in the glyph row, give up. */
11569 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11570 }
11571 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11572 {
11573 if (PT == MATRIX_ROW_END_CHARPOS (row)
11574 && !row->ends_at_zv_p
11575 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11576 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11577 else if (row->height > window_box_height (w))
11578 {
11579 /* If we end up in a partially visible line, let's
11580 make it fully visible, except when it's taller
11581 than the window, in which case we can't do much
11582 about it. */
11583 *scroll_step = 1;
11584 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11585 }
11586 else
11587 {
11588 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11589 if (!make_cursor_line_fully_visible (w, 0))
11590 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11591 else
11592 rc = CURSOR_MOVEMENT_SUCCESS;
11593 }
11594 }
11595 else if (scroll_p)
11596 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11597 else
11598 {
11599 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11600 rc = CURSOR_MOVEMENT_SUCCESS;
11601 }
11602 }
11603 }
11604
11605 return rc;
11606 }
11607
11608 void
11609 set_vertical_scroll_bar (w)
11610 struct window *w;
11611 {
11612 int start, end, whole;
11613
11614 /* Calculate the start and end positions for the current window.
11615 At some point, it would be nice to choose between scrollbars
11616 which reflect the whole buffer size, with special markers
11617 indicating narrowing, and scrollbars which reflect only the
11618 visible region.
11619
11620 Note that mini-buffers sometimes aren't displaying any text. */
11621 if (!MINI_WINDOW_P (w)
11622 || (w == XWINDOW (minibuf_window)
11623 && NILP (echo_area_buffer[0])))
11624 {
11625 struct buffer *buf = XBUFFER (w->buffer);
11626 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11627 start = marker_position (w->start) - BUF_BEGV (buf);
11628 /* I don't think this is guaranteed to be right. For the
11629 moment, we'll pretend it is. */
11630 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11631
11632 if (end < start)
11633 end = start;
11634 if (whole < (end - start))
11635 whole = end - start;
11636 }
11637 else
11638 start = end = whole = 0;
11639
11640 /* Indicate what this scroll bar ought to be displaying now. */
11641 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11642 }
11643
11644
11645 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11646 selected_window is redisplayed.
11647
11648 We can return without actually redisplaying the window if
11649 fonts_changed_p is nonzero. In that case, redisplay_internal will
11650 retry. */
11651
11652 static void
11653 redisplay_window (window, just_this_one_p)
11654 Lisp_Object window;
11655 int just_this_one_p;
11656 {
11657 struct window *w = XWINDOW (window);
11658 struct frame *f = XFRAME (w->frame);
11659 struct buffer *buffer = XBUFFER (w->buffer);
11660 struct buffer *old = current_buffer;
11661 struct text_pos lpoint, opoint, startp;
11662 int update_mode_line;
11663 int tem;
11664 struct it it;
11665 /* Record it now because it's overwritten. */
11666 int current_matrix_up_to_date_p = 0;
11667 int used_current_matrix_p = 0;
11668 /* This is less strict than current_matrix_up_to_date_p.
11669 It indictes that the buffer contents and narrowing are unchanged. */
11670 int buffer_unchanged_p = 0;
11671 int temp_scroll_step = 0;
11672 int count = SPECPDL_INDEX ();
11673 int rc;
11674 int centering_position;
11675 int last_line_misfit = 0;
11676
11677 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11678 opoint = lpoint;
11679
11680 /* W must be a leaf window here. */
11681 xassert (!NILP (w->buffer));
11682 #if GLYPH_DEBUG
11683 *w->desired_matrix->method = 0;
11684 #endif
11685
11686 specbind (Qinhibit_point_motion_hooks, Qt);
11687
11688 reconsider_clip_changes (w, buffer);
11689
11690 /* Has the mode line to be updated? */
11691 update_mode_line = (!NILP (w->update_mode_line)
11692 || update_mode_lines
11693 || buffer->clip_changed
11694 || buffer->prevent_redisplay_optimizations_p);
11695
11696 if (MINI_WINDOW_P (w))
11697 {
11698 if (w == XWINDOW (echo_area_window)
11699 && !NILP (echo_area_buffer[0]))
11700 {
11701 if (update_mode_line)
11702 /* We may have to update a tty frame's menu bar or a
11703 tool-bar. Example `M-x C-h C-h C-g'. */
11704 goto finish_menu_bars;
11705 else
11706 /* We've already displayed the echo area glyphs in this window. */
11707 goto finish_scroll_bars;
11708 }
11709 else if ((w != XWINDOW (minibuf_window)
11710 || minibuf_level == 0)
11711 /* When buffer is nonempty, redisplay window normally. */
11712 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11713 /* Quail displays non-mini buffers in minibuffer window.
11714 In that case, redisplay the window normally. */
11715 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11716 {
11717 /* W is a mini-buffer window, but it's not active, so clear
11718 it. */
11719 int yb = window_text_bottom_y (w);
11720 struct glyph_row *row;
11721 int y;
11722
11723 for (y = 0, row = w->desired_matrix->rows;
11724 y < yb;
11725 y += row->height, ++row)
11726 blank_row (w, row, y);
11727 goto finish_scroll_bars;
11728 }
11729
11730 clear_glyph_matrix (w->desired_matrix);
11731 }
11732
11733 /* Otherwise set up data on this window; select its buffer and point
11734 value. */
11735 /* Really select the buffer, for the sake of buffer-local
11736 variables. */
11737 set_buffer_internal_1 (XBUFFER (w->buffer));
11738 SET_TEXT_POS (opoint, PT, PT_BYTE);
11739
11740 current_matrix_up_to_date_p
11741 = (!NILP (w->window_end_valid)
11742 && !current_buffer->clip_changed
11743 && !current_buffer->prevent_redisplay_optimizations_p
11744 && XFASTINT (w->last_modified) >= MODIFF
11745 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11746
11747 buffer_unchanged_p
11748 = (!NILP (w->window_end_valid)
11749 && !current_buffer->clip_changed
11750 && XFASTINT (w->last_modified) >= MODIFF
11751 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11752
11753 /* When windows_or_buffers_changed is non-zero, we can't rely on
11754 the window end being valid, so set it to nil there. */
11755 if (windows_or_buffers_changed)
11756 {
11757 /* If window starts on a continuation line, maybe adjust the
11758 window start in case the window's width changed. */
11759 if (XMARKER (w->start)->buffer == current_buffer)
11760 compute_window_start_on_continuation_line (w);
11761
11762 w->window_end_valid = Qnil;
11763 }
11764
11765 /* Some sanity checks. */
11766 CHECK_WINDOW_END (w);
11767 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11768 abort ();
11769 if (BYTEPOS (opoint) < CHARPOS (opoint))
11770 abort ();
11771
11772 /* If %c is in mode line, update it if needed. */
11773 if (!NILP (w->column_number_displayed)
11774 /* This alternative quickly identifies a common case
11775 where no change is needed. */
11776 && !(PT == XFASTINT (w->last_point)
11777 && XFASTINT (w->last_modified) >= MODIFF
11778 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11779 && (XFASTINT (w->column_number_displayed)
11780 != (int) current_column ())) /* iftc */
11781 update_mode_line = 1;
11782
11783 /* Count number of windows showing the selected buffer. An indirect
11784 buffer counts as its base buffer. */
11785 if (!just_this_one_p)
11786 {
11787 struct buffer *current_base, *window_base;
11788 current_base = current_buffer;
11789 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11790 if (current_base->base_buffer)
11791 current_base = current_base->base_buffer;
11792 if (window_base->base_buffer)
11793 window_base = window_base->base_buffer;
11794 if (current_base == window_base)
11795 buffer_shared++;
11796 }
11797
11798 /* Point refers normally to the selected window. For any other
11799 window, set up appropriate value. */
11800 if (!EQ (window, selected_window))
11801 {
11802 int new_pt = XMARKER (w->pointm)->charpos;
11803 int new_pt_byte = marker_byte_position (w->pointm);
11804 if (new_pt < BEGV)
11805 {
11806 new_pt = BEGV;
11807 new_pt_byte = BEGV_BYTE;
11808 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11809 }
11810 else if (new_pt > (ZV - 1))
11811 {
11812 new_pt = ZV;
11813 new_pt_byte = ZV_BYTE;
11814 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11815 }
11816
11817 /* We don't use SET_PT so that the point-motion hooks don't run. */
11818 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11819 }
11820
11821 /* If any of the character widths specified in the display table
11822 have changed, invalidate the width run cache. It's true that
11823 this may be a bit late to catch such changes, but the rest of
11824 redisplay goes (non-fatally) haywire when the display table is
11825 changed, so why should we worry about doing any better? */
11826 if (current_buffer->width_run_cache)
11827 {
11828 struct Lisp_Char_Table *disptab = buffer_display_table ();
11829
11830 if (! disptab_matches_widthtab (disptab,
11831 XVECTOR (current_buffer->width_table)))
11832 {
11833 invalidate_region_cache (current_buffer,
11834 current_buffer->width_run_cache,
11835 BEG, Z);
11836 recompute_width_table (current_buffer, disptab);
11837 }
11838 }
11839
11840 /* If window-start is screwed up, choose a new one. */
11841 if (XMARKER (w->start)->buffer != current_buffer)
11842 goto recenter;
11843
11844 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11845
11846 /* If someone specified a new starting point but did not insist,
11847 check whether it can be used. */
11848 if (!NILP (w->optional_new_start)
11849 && CHARPOS (startp) >= BEGV
11850 && CHARPOS (startp) <= ZV)
11851 {
11852 w->optional_new_start = Qnil;
11853 start_display (&it, w, startp);
11854 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11855 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11856 if (IT_CHARPOS (it) == PT)
11857 w->force_start = Qt;
11858 /* IT may overshoot PT if text at PT is invisible. */
11859 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11860 w->force_start = Qt;
11861
11862
11863 }
11864
11865 /* Handle case where place to start displaying has been specified,
11866 unless the specified location is outside the accessible range. */
11867 if (!NILP (w->force_start)
11868 || w->frozen_window_start_p)
11869 {
11870 /* We set this later on if we have to adjust point. */
11871 int new_vpos = -1;
11872
11873 w->force_start = Qnil;
11874 w->vscroll = 0;
11875 w->window_end_valid = Qnil;
11876
11877 /* Forget any recorded base line for line number display. */
11878 if (!buffer_unchanged_p)
11879 w->base_line_number = Qnil;
11880
11881 /* Redisplay the mode line. Select the buffer properly for that.
11882 Also, run the hook window-scroll-functions
11883 because we have scrolled. */
11884 /* Note, we do this after clearing force_start because
11885 if there's an error, it is better to forget about force_start
11886 than to get into an infinite loop calling the hook functions
11887 and having them get more errors. */
11888 if (!update_mode_line
11889 || ! NILP (Vwindow_scroll_functions))
11890 {
11891 update_mode_line = 1;
11892 w->update_mode_line = Qt;
11893 startp = run_window_scroll_functions (window, startp);
11894 }
11895
11896 w->last_modified = make_number (0);
11897 w->last_overlay_modified = make_number (0);
11898 if (CHARPOS (startp) < BEGV)
11899 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11900 else if (CHARPOS (startp) > ZV)
11901 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11902
11903 /* Redisplay, then check if cursor has been set during the
11904 redisplay. Give up if new fonts were loaded. */
11905 if (!try_window (window, startp))
11906 {
11907 w->force_start = Qt;
11908 clear_glyph_matrix (w->desired_matrix);
11909 goto need_larger_matrices;
11910 }
11911
11912 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11913 {
11914 /* If point does not appear, try to move point so it does
11915 appear. The desired matrix has been built above, so we
11916 can use it here. */
11917 new_vpos = window_box_height (w) / 2;
11918 }
11919
11920 if (!make_cursor_line_fully_visible (w, 0))
11921 {
11922 /* Point does appear, but on a line partly visible at end of window.
11923 Move it back to a fully-visible line. */
11924 new_vpos = window_box_height (w);
11925 }
11926
11927 /* If we need to move point for either of the above reasons,
11928 now actually do it. */
11929 if (new_vpos >= 0)
11930 {
11931 struct glyph_row *row;
11932
11933 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11934 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11935 ++row;
11936
11937 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11938 MATRIX_ROW_START_BYTEPOS (row));
11939
11940 if (w != XWINDOW (selected_window))
11941 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11942 else if (current_buffer == old)
11943 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11944
11945 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11946
11947 /* If we are highlighting the region, then we just changed
11948 the region, so redisplay to show it. */
11949 if (!NILP (Vtransient_mark_mode)
11950 && !NILP (current_buffer->mark_active))
11951 {
11952 clear_glyph_matrix (w->desired_matrix);
11953 if (!try_window (window, startp))
11954 goto need_larger_matrices;
11955 }
11956 }
11957
11958 #if GLYPH_DEBUG
11959 debug_method_add (w, "forced window start");
11960 #endif
11961 goto done;
11962 }
11963
11964 /* Handle case where text has not changed, only point, and it has
11965 not moved off the frame, and we are not retrying after hscroll.
11966 (current_matrix_up_to_date_p is nonzero when retrying.) */
11967 if (current_matrix_up_to_date_p
11968 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11969 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11970 {
11971 switch (rc)
11972 {
11973 case CURSOR_MOVEMENT_SUCCESS:
11974 used_current_matrix_p = 1;
11975 goto done;
11976
11977 #if 0 /* try_cursor_movement never returns this value. */
11978 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11979 goto need_larger_matrices;
11980 #endif
11981
11982 case CURSOR_MOVEMENT_MUST_SCROLL:
11983 goto try_to_scroll;
11984
11985 default:
11986 abort ();
11987 }
11988 }
11989 /* If current starting point was originally the beginning of a line
11990 but no longer is, find a new starting point. */
11991 else if (!NILP (w->start_at_line_beg)
11992 && !(CHARPOS (startp) <= BEGV
11993 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11994 {
11995 #if GLYPH_DEBUG
11996 debug_method_add (w, "recenter 1");
11997 #endif
11998 goto recenter;
11999 }
12000
12001 /* Try scrolling with try_window_id. Value is > 0 if update has
12002 been done, it is -1 if we know that the same window start will
12003 not work. It is 0 if unsuccessful for some other reason. */
12004 else if ((tem = try_window_id (w)) != 0)
12005 {
12006 #if GLYPH_DEBUG
12007 debug_method_add (w, "try_window_id %d", tem);
12008 #endif
12009
12010 if (fonts_changed_p)
12011 goto need_larger_matrices;
12012 if (tem > 0)
12013 goto done;
12014
12015 /* Otherwise try_window_id has returned -1 which means that we
12016 don't want the alternative below this comment to execute. */
12017 }
12018 else if (CHARPOS (startp) >= BEGV
12019 && CHARPOS (startp) <= ZV
12020 && PT >= CHARPOS (startp)
12021 && (CHARPOS (startp) < ZV
12022 /* Avoid starting at end of buffer. */
12023 || CHARPOS (startp) == BEGV
12024 || (XFASTINT (w->last_modified) >= MODIFF
12025 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12026 {
12027 #if GLYPH_DEBUG
12028 debug_method_add (w, "same window start");
12029 #endif
12030
12031 /* Try to redisplay starting at same place as before.
12032 If point has not moved off frame, accept the results. */
12033 if (!current_matrix_up_to_date_p
12034 /* Don't use try_window_reusing_current_matrix in this case
12035 because a window scroll function can have changed the
12036 buffer. */
12037 || !NILP (Vwindow_scroll_functions)
12038 || MINI_WINDOW_P (w)
12039 || !(used_current_matrix_p
12040 = try_window_reusing_current_matrix (w)))
12041 {
12042 IF_DEBUG (debug_method_add (w, "1"));
12043 try_window (window, startp);
12044 }
12045
12046 if (fonts_changed_p)
12047 goto need_larger_matrices;
12048
12049 if (w->cursor.vpos >= 0)
12050 {
12051 if (!just_this_one_p
12052 || current_buffer->clip_changed
12053 || BEG_UNCHANGED < CHARPOS (startp))
12054 /* Forget any recorded base line for line number display. */
12055 w->base_line_number = Qnil;
12056
12057 if (!make_cursor_line_fully_visible (w, 1))
12058 {
12059 clear_glyph_matrix (w->desired_matrix);
12060 last_line_misfit = 1;
12061 }
12062 /* Drop through and scroll. */
12063 else
12064 goto done;
12065 }
12066 else
12067 clear_glyph_matrix (w->desired_matrix);
12068 }
12069
12070 try_to_scroll:
12071
12072 w->last_modified = make_number (0);
12073 w->last_overlay_modified = make_number (0);
12074
12075 /* Redisplay the mode line. Select the buffer properly for that. */
12076 if (!update_mode_line)
12077 {
12078 update_mode_line = 1;
12079 w->update_mode_line = Qt;
12080 }
12081
12082 /* Try to scroll by specified few lines. */
12083 if ((scroll_conservatively
12084 || scroll_step
12085 || temp_scroll_step
12086 || NUMBERP (current_buffer->scroll_up_aggressively)
12087 || NUMBERP (current_buffer->scroll_down_aggressively))
12088 && !current_buffer->clip_changed
12089 && CHARPOS (startp) >= BEGV
12090 && CHARPOS (startp) <= ZV)
12091 {
12092 /* The function returns -1 if new fonts were loaded, 1 if
12093 successful, 0 if not successful. */
12094 int rc = try_scrolling (window, just_this_one_p,
12095 scroll_conservatively,
12096 scroll_step,
12097 temp_scroll_step, last_line_misfit);
12098 switch (rc)
12099 {
12100 case SCROLLING_SUCCESS:
12101 goto done;
12102
12103 case SCROLLING_NEED_LARGER_MATRICES:
12104 goto need_larger_matrices;
12105
12106 case SCROLLING_FAILED:
12107 break;
12108
12109 default:
12110 abort ();
12111 }
12112 }
12113
12114 /* Finally, just choose place to start which centers point */
12115
12116 recenter:
12117 centering_position = window_box_height (w) / 2;
12118
12119 point_at_top:
12120 /* Jump here with centering_position already set to 0. */
12121
12122 #if GLYPH_DEBUG
12123 debug_method_add (w, "recenter");
12124 #endif
12125
12126 /* w->vscroll = 0; */
12127
12128 /* Forget any previously recorded base line for line number display. */
12129 if (!buffer_unchanged_p)
12130 w->base_line_number = Qnil;
12131
12132 /* Move backward half the height of the window. */
12133 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12134 it.current_y = it.last_visible_y;
12135 move_it_vertically_backward (&it, centering_position);
12136 xassert (IT_CHARPOS (it) >= BEGV);
12137
12138 /* The function move_it_vertically_backward may move over more
12139 than the specified y-distance. If it->w is small, e.g. a
12140 mini-buffer window, we may end up in front of the window's
12141 display area. Start displaying at the start of the line
12142 containing PT in this case. */
12143 if (it.current_y <= 0)
12144 {
12145 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12146 move_it_vertically (&it, 0);
12147 xassert (IT_CHARPOS (it) <= PT);
12148 it.current_y = 0;
12149 }
12150
12151 it.current_x = it.hpos = 0;
12152
12153 /* Set startp here explicitly in case that helps avoid an infinite loop
12154 in case the window-scroll-functions functions get errors. */
12155 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12156
12157 /* Run scroll hooks. */
12158 startp = run_window_scroll_functions (window, it.current.pos);
12159
12160 /* Redisplay the window. */
12161 if (!current_matrix_up_to_date_p
12162 || windows_or_buffers_changed
12163 || cursor_type_changed
12164 /* Don't use try_window_reusing_current_matrix in this case
12165 because it can have changed the buffer. */
12166 || !NILP (Vwindow_scroll_functions)
12167 || !just_this_one_p
12168 || MINI_WINDOW_P (w)
12169 || !(used_current_matrix_p
12170 = try_window_reusing_current_matrix (w)))
12171 try_window (window, startp);
12172
12173 /* If new fonts have been loaded (due to fontsets), give up. We
12174 have to start a new redisplay since we need to re-adjust glyph
12175 matrices. */
12176 if (fonts_changed_p)
12177 goto need_larger_matrices;
12178
12179 /* If cursor did not appear assume that the middle of the window is
12180 in the first line of the window. Do it again with the next line.
12181 (Imagine a window of height 100, displaying two lines of height
12182 60. Moving back 50 from it->last_visible_y will end in the first
12183 line.) */
12184 if (w->cursor.vpos < 0)
12185 {
12186 if (!NILP (w->window_end_valid)
12187 && PT >= Z - XFASTINT (w->window_end_pos))
12188 {
12189 clear_glyph_matrix (w->desired_matrix);
12190 move_it_by_lines (&it, 1, 0);
12191 try_window (window, it.current.pos);
12192 }
12193 else if (PT < IT_CHARPOS (it))
12194 {
12195 clear_glyph_matrix (w->desired_matrix);
12196 move_it_by_lines (&it, -1, 0);
12197 try_window (window, it.current.pos);
12198 }
12199 else
12200 {
12201 /* Not much we can do about it. */
12202 }
12203 }
12204
12205 /* Consider the following case: Window starts at BEGV, there is
12206 invisible, intangible text at BEGV, so that display starts at
12207 some point START > BEGV. It can happen that we are called with
12208 PT somewhere between BEGV and START. Try to handle that case. */
12209 if (w->cursor.vpos < 0)
12210 {
12211 struct glyph_row *row = w->current_matrix->rows;
12212 if (row->mode_line_p)
12213 ++row;
12214 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12215 }
12216
12217 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12218 {
12219 /* If vscroll is enabled, disable it and try again. */
12220 if (w->vscroll)
12221 {
12222 w->vscroll = 0;
12223 clear_glyph_matrix (w->desired_matrix);
12224 goto recenter;
12225 }
12226
12227 /* If centering point failed to make the whole line visible,
12228 put point at the top instead. That has to make the whole line
12229 visible, if it can be done. */
12230 clear_glyph_matrix (w->desired_matrix);
12231 centering_position = 0;
12232 goto point_at_top;
12233 }
12234
12235 done:
12236
12237 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12238 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12239 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12240 ? Qt : Qnil);
12241
12242 /* Display the mode line, if we must. */
12243 if ((update_mode_line
12244 /* If window not full width, must redo its mode line
12245 if (a) the window to its side is being redone and
12246 (b) we do a frame-based redisplay. This is a consequence
12247 of how inverted lines are drawn in frame-based redisplay. */
12248 || (!just_this_one_p
12249 && !FRAME_WINDOW_P (f)
12250 && !WINDOW_FULL_WIDTH_P (w))
12251 /* Line number to display. */
12252 || INTEGERP (w->base_line_pos)
12253 /* Column number is displayed and different from the one displayed. */
12254 || (!NILP (w->column_number_displayed)
12255 && (XFASTINT (w->column_number_displayed)
12256 != (int) current_column ()))) /* iftc */
12257 /* This means that the window has a mode line. */
12258 && (WINDOW_WANTS_MODELINE_P (w)
12259 || WINDOW_WANTS_HEADER_LINE_P (w)))
12260 {
12261 display_mode_lines (w);
12262
12263 /* If mode line height has changed, arrange for a thorough
12264 immediate redisplay using the correct mode line height. */
12265 if (WINDOW_WANTS_MODELINE_P (w)
12266 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12267 {
12268 fonts_changed_p = 1;
12269 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12270 = DESIRED_MODE_LINE_HEIGHT (w);
12271 }
12272
12273 /* If top line height has changed, arrange for a thorough
12274 immediate redisplay using the correct mode line height. */
12275 if (WINDOW_WANTS_HEADER_LINE_P (w)
12276 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12277 {
12278 fonts_changed_p = 1;
12279 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12280 = DESIRED_HEADER_LINE_HEIGHT (w);
12281 }
12282
12283 if (fonts_changed_p)
12284 goto need_larger_matrices;
12285 }
12286
12287 if (!line_number_displayed
12288 && !BUFFERP (w->base_line_pos))
12289 {
12290 w->base_line_pos = Qnil;
12291 w->base_line_number = Qnil;
12292 }
12293
12294 finish_menu_bars:
12295
12296 /* When we reach a frame's selected window, redo the frame's menu bar. */
12297 if (update_mode_line
12298 && EQ (FRAME_SELECTED_WINDOW (f), window))
12299 {
12300 int redisplay_menu_p = 0;
12301 int redisplay_tool_bar_p = 0;
12302
12303 if (FRAME_WINDOW_P (f))
12304 {
12305 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12306 || defined (USE_GTK)
12307 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12308 #else
12309 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12310 #endif
12311 }
12312 else
12313 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12314
12315 if (redisplay_menu_p)
12316 display_menu_bar (w);
12317
12318 #ifdef HAVE_WINDOW_SYSTEM
12319 #ifdef USE_GTK
12320 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12321 #else
12322 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12323 && (FRAME_TOOL_BAR_LINES (f) > 0
12324 || auto_resize_tool_bars_p);
12325
12326 #endif
12327
12328 if (redisplay_tool_bar_p)
12329 redisplay_tool_bar (f);
12330 #endif
12331 }
12332
12333 #ifdef HAVE_WINDOW_SYSTEM
12334 if (FRAME_WINDOW_P (f)
12335 && update_window_fringes (w, 0)
12336 && !just_this_one_p
12337 && (used_current_matrix_p || overlay_arrow_seen)
12338 && !w->pseudo_window_p)
12339 {
12340 update_begin (f);
12341 BLOCK_INPUT;
12342 if (draw_window_fringes (w, 1))
12343 x_draw_vertical_border (w);
12344 UNBLOCK_INPUT;
12345 update_end (f);
12346 }
12347 #endif /* HAVE_WINDOW_SYSTEM */
12348
12349 /* We go to this label, with fonts_changed_p nonzero,
12350 if it is necessary to try again using larger glyph matrices.
12351 We have to redeem the scroll bar even in this case,
12352 because the loop in redisplay_internal expects that. */
12353 need_larger_matrices:
12354 ;
12355 finish_scroll_bars:
12356
12357 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12358 {
12359 /* Set the thumb's position and size. */
12360 set_vertical_scroll_bar (w);
12361
12362 /* Note that we actually used the scroll bar attached to this
12363 window, so it shouldn't be deleted at the end of redisplay. */
12364 redeem_scroll_bar_hook (w);
12365 }
12366
12367 /* Restore current_buffer and value of point in it. */
12368 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12369 set_buffer_internal_1 (old);
12370 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12371
12372 unbind_to (count, Qnil);
12373 }
12374
12375
12376 /* Build the complete desired matrix of WINDOW with a window start
12377 buffer position POS. Value is non-zero if successful. It is zero
12378 if fonts were loaded during redisplay which makes re-adjusting
12379 glyph matrices necessary. */
12380
12381 int
12382 try_window (window, pos)
12383 Lisp_Object window;
12384 struct text_pos pos;
12385 {
12386 struct window *w = XWINDOW (window);
12387 struct it it;
12388 struct glyph_row *last_text_row = NULL;
12389
12390 /* Make POS the new window start. */
12391 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12392
12393 /* Mark cursor position as unknown. No overlay arrow seen. */
12394 w->cursor.vpos = -1;
12395 overlay_arrow_seen = 0;
12396
12397 /* Initialize iterator and info to start at POS. */
12398 start_display (&it, w, pos);
12399
12400 /* Display all lines of W. */
12401 while (it.current_y < it.last_visible_y)
12402 {
12403 if (display_line (&it))
12404 last_text_row = it.glyph_row - 1;
12405 if (fonts_changed_p)
12406 return 0;
12407 }
12408
12409 /* If bottom moved off end of frame, change mode line percentage. */
12410 if (XFASTINT (w->window_end_pos) <= 0
12411 && Z != IT_CHARPOS (it))
12412 w->update_mode_line = Qt;
12413
12414 /* Set window_end_pos to the offset of the last character displayed
12415 on the window from the end of current_buffer. Set
12416 window_end_vpos to its row number. */
12417 if (last_text_row)
12418 {
12419 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12420 w->window_end_bytepos
12421 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12422 w->window_end_pos
12423 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12424 w->window_end_vpos
12425 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12426 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12427 ->displays_text_p);
12428 }
12429 else
12430 {
12431 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12432 w->window_end_pos = make_number (Z - ZV);
12433 w->window_end_vpos = make_number (0);
12434 }
12435
12436 /* But that is not valid info until redisplay finishes. */
12437 w->window_end_valid = Qnil;
12438 return 1;
12439 }
12440
12441
12442 \f
12443 /************************************************************************
12444 Window redisplay reusing current matrix when buffer has not changed
12445 ************************************************************************/
12446
12447 /* Try redisplay of window W showing an unchanged buffer with a
12448 different window start than the last time it was displayed by
12449 reusing its current matrix. Value is non-zero if successful.
12450 W->start is the new window start. */
12451
12452 static int
12453 try_window_reusing_current_matrix (w)
12454 struct window *w;
12455 {
12456 struct frame *f = XFRAME (w->frame);
12457 struct glyph_row *row, *bottom_row;
12458 struct it it;
12459 struct run run;
12460 struct text_pos start, new_start;
12461 int nrows_scrolled, i;
12462 struct glyph_row *last_text_row;
12463 struct glyph_row *last_reused_text_row;
12464 struct glyph_row *start_row;
12465 int start_vpos, min_y, max_y;
12466
12467 #if GLYPH_DEBUG
12468 if (inhibit_try_window_reusing)
12469 return 0;
12470 #endif
12471
12472 if (/* This function doesn't handle terminal frames. */
12473 !FRAME_WINDOW_P (f)
12474 /* Don't try to reuse the display if windows have been split
12475 or such. */
12476 || windows_or_buffers_changed
12477 || cursor_type_changed)
12478 return 0;
12479
12480 /* Can't do this if region may have changed. */
12481 if ((!NILP (Vtransient_mark_mode)
12482 && !NILP (current_buffer->mark_active))
12483 || !NILP (w->region_showing)
12484 || !NILP (Vshow_trailing_whitespace))
12485 return 0;
12486
12487 /* If top-line visibility has changed, give up. */
12488 if (WINDOW_WANTS_HEADER_LINE_P (w)
12489 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12490 return 0;
12491
12492 /* Give up if old or new display is scrolled vertically. We could
12493 make this function handle this, but right now it doesn't. */
12494 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12495 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12496 return 0;
12497
12498 /* The variable new_start now holds the new window start. The old
12499 start `start' can be determined from the current matrix. */
12500 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12501 start = start_row->start.pos;
12502 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12503
12504 /* Clear the desired matrix for the display below. */
12505 clear_glyph_matrix (w->desired_matrix);
12506
12507 if (CHARPOS (new_start) <= CHARPOS (start))
12508 {
12509 int first_row_y;
12510
12511 /* Don't use this method if the display starts with an ellipsis
12512 displayed for invisible text. It's not easy to handle that case
12513 below, and it's certainly not worth the effort since this is
12514 not a frequent case. */
12515 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12516 return 0;
12517
12518 IF_DEBUG (debug_method_add (w, "twu1"));
12519
12520 /* Display up to a row that can be reused. The variable
12521 last_text_row is set to the last row displayed that displays
12522 text. Note that it.vpos == 0 if or if not there is a
12523 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12524 start_display (&it, w, new_start);
12525 first_row_y = it.current_y;
12526 w->cursor.vpos = -1;
12527 last_text_row = last_reused_text_row = NULL;
12528
12529 while (it.current_y < it.last_visible_y
12530 && !fonts_changed_p)
12531 {
12532 /* If we have reached into the characters in the START row,
12533 that means the line boundaries have changed. So we
12534 can't start copying with the row START. Maybe it will
12535 work to start copying with the following row. */
12536 while (IT_CHARPOS (it) > CHARPOS (start))
12537 {
12538 /* Advance to the next row as the "start". */
12539 start_row++;
12540 start = start_row->start.pos;
12541 /* If there are no more rows to try, or just one, give up. */
12542 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12543 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row)
12544 || CHARPOS (start) == ZV)
12545 {
12546 clear_glyph_matrix (w->desired_matrix);
12547 return 0;
12548 }
12549
12550 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12551 }
12552 /* If we have reached alignment,
12553 we can copy the rest of the rows. */
12554 if (IT_CHARPOS (it) == CHARPOS (start))
12555 break;
12556
12557 if (display_line (&it))
12558 last_text_row = it.glyph_row - 1;
12559 }
12560
12561 /* A value of current_y < last_visible_y means that we stopped
12562 at the previous window start, which in turn means that we
12563 have at least one reusable row. */
12564 if (it.current_y < it.last_visible_y)
12565 {
12566 /* IT.vpos always starts from 0; it counts text lines. */
12567 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12568
12569 /* Find PT if not already found in the lines displayed. */
12570 if (w->cursor.vpos < 0)
12571 {
12572 int dy = it.current_y - start_row->y;
12573
12574 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12575 row = row_containing_pos (w, PT, row, NULL, dy);
12576 if (row)
12577 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12578 dy, nrows_scrolled);
12579 else
12580 {
12581 clear_glyph_matrix (w->desired_matrix);
12582 return 0;
12583 }
12584 }
12585
12586 /* Scroll the display. Do it before the current matrix is
12587 changed. The problem here is that update has not yet
12588 run, i.e. part of the current matrix is not up to date.
12589 scroll_run_hook will clear the cursor, and use the
12590 current matrix to get the height of the row the cursor is
12591 in. */
12592 run.current_y = start_row->y;
12593 run.desired_y = it.current_y;
12594 run.height = it.last_visible_y - it.current_y;
12595
12596 if (run.height > 0 && run.current_y != run.desired_y)
12597 {
12598 update_begin (f);
12599 rif->update_window_begin_hook (w);
12600 rif->clear_window_mouse_face (w);
12601 rif->scroll_run_hook (w, &run);
12602 rif->update_window_end_hook (w, 0, 0);
12603 update_end (f);
12604 }
12605
12606 /* Shift current matrix down by nrows_scrolled lines. */
12607 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12608 rotate_matrix (w->current_matrix,
12609 start_vpos,
12610 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12611 nrows_scrolled);
12612
12613 /* Disable lines that must be updated. */
12614 for (i = 0; i < it.vpos; ++i)
12615 (start_row + i)->enabled_p = 0;
12616
12617 /* Re-compute Y positions. */
12618 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12619 max_y = it.last_visible_y;
12620 for (row = start_row + nrows_scrolled;
12621 row < bottom_row;
12622 ++row)
12623 {
12624 row->y = it.current_y;
12625 row->visible_height = row->height;
12626
12627 if (row->y < min_y)
12628 row->visible_height -= min_y - row->y;
12629 if (row->y + row->height > max_y)
12630 row->visible_height -= row->y + row->height - max_y;
12631 row->redraw_fringe_bitmaps_p = 1;
12632
12633 it.current_y += row->height;
12634
12635 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12636 last_reused_text_row = row;
12637 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12638 break;
12639 }
12640
12641 /* Disable lines in the current matrix which are now
12642 below the window. */
12643 for (++row; row < bottom_row; ++row)
12644 row->enabled_p = 0;
12645 }
12646
12647 /* Update window_end_pos etc.; last_reused_text_row is the last
12648 reused row from the current matrix containing text, if any.
12649 The value of last_text_row is the last displayed line
12650 containing text. */
12651 if (last_reused_text_row)
12652 {
12653 w->window_end_bytepos
12654 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12655 w->window_end_pos
12656 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12657 w->window_end_vpos
12658 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12659 w->current_matrix));
12660 }
12661 else if (last_text_row)
12662 {
12663 w->window_end_bytepos
12664 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12665 w->window_end_pos
12666 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12667 w->window_end_vpos
12668 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12669 }
12670 else
12671 {
12672 /* This window must be completely empty. */
12673 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12674 w->window_end_pos = make_number (Z - ZV);
12675 w->window_end_vpos = make_number (0);
12676 }
12677 w->window_end_valid = Qnil;
12678
12679 /* Update hint: don't try scrolling again in update_window. */
12680 w->desired_matrix->no_scrolling_p = 1;
12681
12682 #if GLYPH_DEBUG
12683 debug_method_add (w, "try_window_reusing_current_matrix 1");
12684 #endif
12685 return 1;
12686 }
12687 else if (CHARPOS (new_start) > CHARPOS (start))
12688 {
12689 struct glyph_row *pt_row, *row;
12690 struct glyph_row *first_reusable_row;
12691 struct glyph_row *first_row_to_display;
12692 int dy;
12693 int yb = window_text_bottom_y (w);
12694
12695 /* Find the row starting at new_start, if there is one. Don't
12696 reuse a partially visible line at the end. */
12697 first_reusable_row = start_row;
12698 while (first_reusable_row->enabled_p
12699 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12700 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12701 < CHARPOS (new_start)))
12702 ++first_reusable_row;
12703
12704 /* Give up if there is no row to reuse. */
12705 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12706 || !first_reusable_row->enabled_p
12707 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12708 != CHARPOS (new_start)))
12709 return 0;
12710
12711 /* We can reuse fully visible rows beginning with
12712 first_reusable_row to the end of the window. Set
12713 first_row_to_display to the first row that cannot be reused.
12714 Set pt_row to the row containing point, if there is any. */
12715 pt_row = NULL;
12716 for (first_row_to_display = first_reusable_row;
12717 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12718 ++first_row_to_display)
12719 {
12720 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12721 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12722 pt_row = first_row_to_display;
12723 }
12724
12725 /* Start displaying at the start of first_row_to_display. */
12726 xassert (first_row_to_display->y < yb);
12727 init_to_row_start (&it, w, first_row_to_display);
12728
12729 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12730 - start_vpos);
12731 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12732 - nrows_scrolled);
12733 it.current_y = (first_row_to_display->y - first_reusable_row->y
12734 + WINDOW_HEADER_LINE_HEIGHT (w));
12735
12736 /* Display lines beginning with first_row_to_display in the
12737 desired matrix. Set last_text_row to the last row displayed
12738 that displays text. */
12739 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12740 if (pt_row == NULL)
12741 w->cursor.vpos = -1;
12742 last_text_row = NULL;
12743 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12744 if (display_line (&it))
12745 last_text_row = it.glyph_row - 1;
12746
12747 /* Give up If point isn't in a row displayed or reused. */
12748 if (w->cursor.vpos < 0)
12749 {
12750 clear_glyph_matrix (w->desired_matrix);
12751 return 0;
12752 }
12753
12754 /* If point is in a reused row, adjust y and vpos of the cursor
12755 position. */
12756 if (pt_row)
12757 {
12758 w->cursor.vpos -= nrows_scrolled;
12759 w->cursor.y -= first_reusable_row->y - start_row->y;
12760 }
12761
12762 /* Scroll the display. */
12763 run.current_y = first_reusable_row->y;
12764 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12765 run.height = it.last_visible_y - run.current_y;
12766 dy = run.current_y - run.desired_y;
12767
12768 if (run.height)
12769 {
12770 update_begin (f);
12771 rif->update_window_begin_hook (w);
12772 rif->clear_window_mouse_face (w);
12773 rif->scroll_run_hook (w, &run);
12774 rif->update_window_end_hook (w, 0, 0);
12775 update_end (f);
12776 }
12777
12778 /* Adjust Y positions of reused rows. */
12779 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12780 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12781 max_y = it.last_visible_y;
12782 for (row = first_reusable_row; row < first_row_to_display; ++row)
12783 {
12784 row->y -= dy;
12785 row->visible_height = row->height;
12786 if (row->y < min_y)
12787 row->visible_height -= min_y - row->y;
12788 if (row->y + row->height > max_y)
12789 row->visible_height -= row->y + row->height - max_y;
12790 row->redraw_fringe_bitmaps_p = 1;
12791 }
12792
12793 /* Scroll the current matrix. */
12794 xassert (nrows_scrolled > 0);
12795 rotate_matrix (w->current_matrix,
12796 start_vpos,
12797 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12798 -nrows_scrolled);
12799
12800 /* Disable rows not reused. */
12801 for (row -= nrows_scrolled; row < bottom_row; ++row)
12802 row->enabled_p = 0;
12803
12804 /* Point may have moved to a different line, so we cannot assume that
12805 the previous cursor position is valid; locate the correct row. */
12806 if (pt_row)
12807 {
12808 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12809 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12810 row++)
12811 {
12812 w->cursor.vpos++;
12813 w->cursor.y = row->y;
12814 }
12815 if (row < bottom_row)
12816 {
12817 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12818 while (glyph->charpos < PT)
12819 {
12820 w->cursor.hpos++;
12821 w->cursor.x += glyph->pixel_width;
12822 glyph++;
12823 }
12824 }
12825 }
12826
12827 /* Adjust window end. A null value of last_text_row means that
12828 the window end is in reused rows which in turn means that
12829 only its vpos can have changed. */
12830 if (last_text_row)
12831 {
12832 w->window_end_bytepos
12833 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12834 w->window_end_pos
12835 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12836 w->window_end_vpos
12837 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12838 }
12839 else
12840 {
12841 w->window_end_vpos
12842 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12843 }
12844
12845 w->window_end_valid = Qnil;
12846 w->desired_matrix->no_scrolling_p = 1;
12847
12848 #if GLYPH_DEBUG
12849 debug_method_add (w, "try_window_reusing_current_matrix 2");
12850 #endif
12851 return 1;
12852 }
12853
12854 return 0;
12855 }
12856
12857
12858 \f
12859 /************************************************************************
12860 Window redisplay reusing current matrix when buffer has changed
12861 ************************************************************************/
12862
12863 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12864 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12865 int *, int *));
12866 static struct glyph_row *
12867 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12868 struct glyph_row *));
12869
12870
12871 /* Return the last row in MATRIX displaying text. If row START is
12872 non-null, start searching with that row. IT gives the dimensions
12873 of the display. Value is null if matrix is empty; otherwise it is
12874 a pointer to the row found. */
12875
12876 static struct glyph_row *
12877 find_last_row_displaying_text (matrix, it, start)
12878 struct glyph_matrix *matrix;
12879 struct it *it;
12880 struct glyph_row *start;
12881 {
12882 struct glyph_row *row, *row_found;
12883
12884 /* Set row_found to the last row in IT->w's current matrix
12885 displaying text. The loop looks funny but think of partially
12886 visible lines. */
12887 row_found = NULL;
12888 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12889 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12890 {
12891 xassert (row->enabled_p);
12892 row_found = row;
12893 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12894 break;
12895 ++row;
12896 }
12897
12898 return row_found;
12899 }
12900
12901
12902 /* Return the last row in the current matrix of W that is not affected
12903 by changes at the start of current_buffer that occurred since W's
12904 current matrix was built. Value is null if no such row exists.
12905
12906 BEG_UNCHANGED us the number of characters unchanged at the start of
12907 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12908 first changed character in current_buffer. Characters at positions <
12909 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12910 when the current matrix was built. */
12911
12912 static struct glyph_row *
12913 find_last_unchanged_at_beg_row (w)
12914 struct window *w;
12915 {
12916 int first_changed_pos = BEG + BEG_UNCHANGED;
12917 struct glyph_row *row;
12918 struct glyph_row *row_found = NULL;
12919 int yb = window_text_bottom_y (w);
12920
12921 /* Find the last row displaying unchanged text. */
12922 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12923 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12924 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12925 {
12926 if (/* If row ends before first_changed_pos, it is unchanged,
12927 except in some case. */
12928 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12929 /* When row ends in ZV and we write at ZV it is not
12930 unchanged. */
12931 && !row->ends_at_zv_p
12932 /* When first_changed_pos is the end of a continued line,
12933 row is not unchanged because it may be no longer
12934 continued. */
12935 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12936 && (row->continued_p
12937 || row->exact_window_width_line_p)))
12938 row_found = row;
12939
12940 /* Stop if last visible row. */
12941 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12942 break;
12943
12944 ++row;
12945 }
12946
12947 return row_found;
12948 }
12949
12950
12951 /* Find the first glyph row in the current matrix of W that is not
12952 affected by changes at the end of current_buffer since the
12953 time W's current matrix was built.
12954
12955 Return in *DELTA the number of chars by which buffer positions in
12956 unchanged text at the end of current_buffer must be adjusted.
12957
12958 Return in *DELTA_BYTES the corresponding number of bytes.
12959
12960 Value is null if no such row exists, i.e. all rows are affected by
12961 changes. */
12962
12963 static struct glyph_row *
12964 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12965 struct window *w;
12966 int *delta, *delta_bytes;
12967 {
12968 struct glyph_row *row;
12969 struct glyph_row *row_found = NULL;
12970
12971 *delta = *delta_bytes = 0;
12972
12973 /* Display must not have been paused, otherwise the current matrix
12974 is not up to date. */
12975 if (NILP (w->window_end_valid))
12976 abort ();
12977
12978 /* A value of window_end_pos >= END_UNCHANGED means that the window
12979 end is in the range of changed text. If so, there is no
12980 unchanged row at the end of W's current matrix. */
12981 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12982 return NULL;
12983
12984 /* Set row to the last row in W's current matrix displaying text. */
12985 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12986
12987 /* If matrix is entirely empty, no unchanged row exists. */
12988 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12989 {
12990 /* The value of row is the last glyph row in the matrix having a
12991 meaningful buffer position in it. The end position of row
12992 corresponds to window_end_pos. This allows us to translate
12993 buffer positions in the current matrix to current buffer
12994 positions for characters not in changed text. */
12995 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12996 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12997 int last_unchanged_pos, last_unchanged_pos_old;
12998 struct glyph_row *first_text_row
12999 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13000
13001 *delta = Z - Z_old;
13002 *delta_bytes = Z_BYTE - Z_BYTE_old;
13003
13004 /* Set last_unchanged_pos to the buffer position of the last
13005 character in the buffer that has not been changed. Z is the
13006 index + 1 of the last character in current_buffer, i.e. by
13007 subtracting END_UNCHANGED we get the index of the last
13008 unchanged character, and we have to add BEG to get its buffer
13009 position. */
13010 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13011 last_unchanged_pos_old = last_unchanged_pos - *delta;
13012
13013 /* Search backward from ROW for a row displaying a line that
13014 starts at a minimum position >= last_unchanged_pos_old. */
13015 for (; row > first_text_row; --row)
13016 {
13017 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13018 abort ();
13019
13020 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13021 row_found = row;
13022 }
13023 }
13024
13025 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13026 abort ();
13027
13028 return row_found;
13029 }
13030
13031
13032 /* Make sure that glyph rows in the current matrix of window W
13033 reference the same glyph memory as corresponding rows in the
13034 frame's frame matrix. This function is called after scrolling W's
13035 current matrix on a terminal frame in try_window_id and
13036 try_window_reusing_current_matrix. */
13037
13038 static void
13039 sync_frame_with_window_matrix_rows (w)
13040 struct window *w;
13041 {
13042 struct frame *f = XFRAME (w->frame);
13043 struct glyph_row *window_row, *window_row_end, *frame_row;
13044
13045 /* Preconditions: W must be a leaf window and full-width. Its frame
13046 must have a frame matrix. */
13047 xassert (NILP (w->hchild) && NILP (w->vchild));
13048 xassert (WINDOW_FULL_WIDTH_P (w));
13049 xassert (!FRAME_WINDOW_P (f));
13050
13051 /* If W is a full-width window, glyph pointers in W's current matrix
13052 have, by definition, to be the same as glyph pointers in the
13053 corresponding frame matrix. Note that frame matrices have no
13054 marginal areas (see build_frame_matrix). */
13055 window_row = w->current_matrix->rows;
13056 window_row_end = window_row + w->current_matrix->nrows;
13057 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13058 while (window_row < window_row_end)
13059 {
13060 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13061 struct glyph *end = window_row->glyphs[LAST_AREA];
13062
13063 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13064 frame_row->glyphs[TEXT_AREA] = start;
13065 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13066 frame_row->glyphs[LAST_AREA] = end;
13067
13068 /* Disable frame rows whose corresponding window rows have
13069 been disabled in try_window_id. */
13070 if (!window_row->enabled_p)
13071 frame_row->enabled_p = 0;
13072
13073 ++window_row, ++frame_row;
13074 }
13075 }
13076
13077
13078 /* Find the glyph row in window W containing CHARPOS. Consider all
13079 rows between START and END (not inclusive). END null means search
13080 all rows to the end of the display area of W. Value is the row
13081 containing CHARPOS or null. */
13082
13083 struct glyph_row *
13084 row_containing_pos (w, charpos, start, end, dy)
13085 struct window *w;
13086 int charpos;
13087 struct glyph_row *start, *end;
13088 int dy;
13089 {
13090 struct glyph_row *row = start;
13091 int last_y;
13092
13093 /* If we happen to start on a header-line, skip that. */
13094 if (row->mode_line_p)
13095 ++row;
13096
13097 if ((end && row >= end) || !row->enabled_p)
13098 return NULL;
13099
13100 last_y = window_text_bottom_y (w) - dy;
13101
13102 while (1)
13103 {
13104 /* Give up if we have gone too far. */
13105 if (end && row >= end)
13106 return NULL;
13107 /* This formerly returned if they were equal.
13108 I think that both quantities are of a "last plus one" type;
13109 if so, when they are equal, the row is within the screen. -- rms. */
13110 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13111 return NULL;
13112
13113 /* If it is in this row, return this row. */
13114 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13115 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13116 /* The end position of a row equals the start
13117 position of the next row. If CHARPOS is there, we
13118 would rather display it in the next line, except
13119 when this line ends in ZV. */
13120 && !row->ends_at_zv_p
13121 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13122 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13123 return row;
13124 ++row;
13125 }
13126 }
13127
13128
13129 /* Try to redisplay window W by reusing its existing display. W's
13130 current matrix must be up to date when this function is called,
13131 i.e. window_end_valid must not be nil.
13132
13133 Value is
13134
13135 1 if display has been updated
13136 0 if otherwise unsuccessful
13137 -1 if redisplay with same window start is known not to succeed
13138
13139 The following steps are performed:
13140
13141 1. Find the last row in the current matrix of W that is not
13142 affected by changes at the start of current_buffer. If no such row
13143 is found, give up.
13144
13145 2. Find the first row in W's current matrix that is not affected by
13146 changes at the end of current_buffer. Maybe there is no such row.
13147
13148 3. Display lines beginning with the row + 1 found in step 1 to the
13149 row found in step 2 or, if step 2 didn't find a row, to the end of
13150 the window.
13151
13152 4. If cursor is not known to appear on the window, give up.
13153
13154 5. If display stopped at the row found in step 2, scroll the
13155 display and current matrix as needed.
13156
13157 6. Maybe display some lines at the end of W, if we must. This can
13158 happen under various circumstances, like a partially visible line
13159 becoming fully visible, or because newly displayed lines are displayed
13160 in smaller font sizes.
13161
13162 7. Update W's window end information. */
13163
13164 static int
13165 try_window_id (w)
13166 struct window *w;
13167 {
13168 struct frame *f = XFRAME (w->frame);
13169 struct glyph_matrix *current_matrix = w->current_matrix;
13170 struct glyph_matrix *desired_matrix = w->desired_matrix;
13171 struct glyph_row *last_unchanged_at_beg_row;
13172 struct glyph_row *first_unchanged_at_end_row;
13173 struct glyph_row *row;
13174 struct glyph_row *bottom_row;
13175 int bottom_vpos;
13176 struct it it;
13177 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13178 struct text_pos start_pos;
13179 struct run run;
13180 int first_unchanged_at_end_vpos = 0;
13181 struct glyph_row *last_text_row, *last_text_row_at_end;
13182 struct text_pos start;
13183 int first_changed_charpos, last_changed_charpos;
13184
13185 #if GLYPH_DEBUG
13186 if (inhibit_try_window_id)
13187 return 0;
13188 #endif
13189
13190 /* This is handy for debugging. */
13191 #if 0
13192 #define GIVE_UP(X) \
13193 do { \
13194 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13195 return 0; \
13196 } while (0)
13197 #else
13198 #define GIVE_UP(X) return 0
13199 #endif
13200
13201 SET_TEXT_POS_FROM_MARKER (start, w->start);
13202
13203 /* Don't use this for mini-windows because these can show
13204 messages and mini-buffers, and we don't handle that here. */
13205 if (MINI_WINDOW_P (w))
13206 GIVE_UP (1);
13207
13208 /* This flag is used to prevent redisplay optimizations. */
13209 if (windows_or_buffers_changed || cursor_type_changed)
13210 GIVE_UP (2);
13211
13212 /* Verify that narrowing has not changed.
13213 Also verify that we were not told to prevent redisplay optimizations.
13214 It would be nice to further
13215 reduce the number of cases where this prevents try_window_id. */
13216 if (current_buffer->clip_changed
13217 || current_buffer->prevent_redisplay_optimizations_p)
13218 GIVE_UP (3);
13219
13220 /* Window must either use window-based redisplay or be full width. */
13221 if (!FRAME_WINDOW_P (f)
13222 && (!line_ins_del_ok
13223 || !WINDOW_FULL_WIDTH_P (w)))
13224 GIVE_UP (4);
13225
13226 /* Give up if point is not known NOT to appear in W. */
13227 if (PT < CHARPOS (start))
13228 GIVE_UP (5);
13229
13230 /* Another way to prevent redisplay optimizations. */
13231 if (XFASTINT (w->last_modified) == 0)
13232 GIVE_UP (6);
13233
13234 /* Verify that window is not hscrolled. */
13235 if (XFASTINT (w->hscroll) != 0)
13236 GIVE_UP (7);
13237
13238 /* Verify that display wasn't paused. */
13239 if (NILP (w->window_end_valid))
13240 GIVE_UP (8);
13241
13242 /* Can't use this if highlighting a region because a cursor movement
13243 will do more than just set the cursor. */
13244 if (!NILP (Vtransient_mark_mode)
13245 && !NILP (current_buffer->mark_active))
13246 GIVE_UP (9);
13247
13248 /* Likewise if highlighting trailing whitespace. */
13249 if (!NILP (Vshow_trailing_whitespace))
13250 GIVE_UP (11);
13251
13252 /* Likewise if showing a region. */
13253 if (!NILP (w->region_showing))
13254 GIVE_UP (10);
13255
13256 /* Can use this if overlay arrow position and or string have changed. */
13257 if (overlay_arrows_changed_p ())
13258 GIVE_UP (12);
13259
13260
13261 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13262 only if buffer has really changed. The reason is that the gap is
13263 initially at Z for freshly visited files. The code below would
13264 set end_unchanged to 0 in that case. */
13265 if (MODIFF > SAVE_MODIFF
13266 /* This seems to happen sometimes after saving a buffer. */
13267 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13268 {
13269 if (GPT - BEG < BEG_UNCHANGED)
13270 BEG_UNCHANGED = GPT - BEG;
13271 if (Z - GPT < END_UNCHANGED)
13272 END_UNCHANGED = Z - GPT;
13273 }
13274
13275 /* The position of the first and last character that has been changed. */
13276 first_changed_charpos = BEG + BEG_UNCHANGED;
13277 last_changed_charpos = Z - END_UNCHANGED;
13278
13279 /* If window starts after a line end, and the last change is in
13280 front of that newline, then changes don't affect the display.
13281 This case happens with stealth-fontification. Note that although
13282 the display is unchanged, glyph positions in the matrix have to
13283 be adjusted, of course. */
13284 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13285 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13286 && ((last_changed_charpos < CHARPOS (start)
13287 && CHARPOS (start) == BEGV)
13288 || (last_changed_charpos < CHARPOS (start) - 1
13289 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13290 {
13291 int Z_old, delta, Z_BYTE_old, delta_bytes;
13292 struct glyph_row *r0;
13293
13294 /* Compute how many chars/bytes have been added to or removed
13295 from the buffer. */
13296 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13297 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13298 delta = Z - Z_old;
13299 delta_bytes = Z_BYTE - Z_BYTE_old;
13300
13301 /* Give up if PT is not in the window. Note that it already has
13302 been checked at the start of try_window_id that PT is not in
13303 front of the window start. */
13304 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13305 GIVE_UP (13);
13306
13307 /* If window start is unchanged, we can reuse the whole matrix
13308 as is, after adjusting glyph positions. No need to compute
13309 the window end again, since its offset from Z hasn't changed. */
13310 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13311 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13312 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13313 /* PT must not be in a partially visible line. */
13314 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13315 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13316 {
13317 /* Adjust positions in the glyph matrix. */
13318 if (delta || delta_bytes)
13319 {
13320 struct glyph_row *r1
13321 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13322 increment_matrix_positions (w->current_matrix,
13323 MATRIX_ROW_VPOS (r0, current_matrix),
13324 MATRIX_ROW_VPOS (r1, current_matrix),
13325 delta, delta_bytes);
13326 }
13327
13328 /* Set the cursor. */
13329 row = row_containing_pos (w, PT, r0, NULL, 0);
13330 if (row)
13331 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13332 else
13333 abort ();
13334 return 1;
13335 }
13336 }
13337
13338 /* Handle the case that changes are all below what is displayed in
13339 the window, and that PT is in the window. This shortcut cannot
13340 be taken if ZV is visible in the window, and text has been added
13341 there that is visible in the window. */
13342 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13343 /* ZV is not visible in the window, or there are no
13344 changes at ZV, actually. */
13345 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13346 || first_changed_charpos == last_changed_charpos))
13347 {
13348 struct glyph_row *r0;
13349
13350 /* Give up if PT is not in the window. Note that it already has
13351 been checked at the start of try_window_id that PT is not in
13352 front of the window start. */
13353 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13354 GIVE_UP (14);
13355
13356 /* If window start is unchanged, we can reuse the whole matrix
13357 as is, without changing glyph positions since no text has
13358 been added/removed in front of the window end. */
13359 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13360 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13361 /* PT must not be in a partially visible line. */
13362 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13363 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13364 {
13365 /* We have to compute the window end anew since text
13366 can have been added/removed after it. */
13367 w->window_end_pos
13368 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13369 w->window_end_bytepos
13370 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13371
13372 /* Set the cursor. */
13373 row = row_containing_pos (w, PT, r0, NULL, 0);
13374 if (row)
13375 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13376 else
13377 abort ();
13378 return 2;
13379 }
13380 }
13381
13382 /* Give up if window start is in the changed area.
13383
13384 The condition used to read
13385
13386 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13387
13388 but why that was tested escapes me at the moment. */
13389 if (CHARPOS (start) >= first_changed_charpos
13390 && CHARPOS (start) <= last_changed_charpos)
13391 GIVE_UP (15);
13392
13393 /* Check that window start agrees with the start of the first glyph
13394 row in its current matrix. Check this after we know the window
13395 start is not in changed text, otherwise positions would not be
13396 comparable. */
13397 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13398 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13399 GIVE_UP (16);
13400
13401 /* Give up if the window ends in strings. Overlay strings
13402 at the end are difficult to handle, so don't try. */
13403 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13404 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13405 GIVE_UP (20);
13406
13407 /* Compute the position at which we have to start displaying new
13408 lines. Some of the lines at the top of the window might be
13409 reusable because they are not displaying changed text. Find the
13410 last row in W's current matrix not affected by changes at the
13411 start of current_buffer. Value is null if changes start in the
13412 first line of window. */
13413 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13414 if (last_unchanged_at_beg_row)
13415 {
13416 /* Avoid starting to display in the moddle of a character, a TAB
13417 for instance. This is easier than to set up the iterator
13418 exactly, and it's not a frequent case, so the additional
13419 effort wouldn't really pay off. */
13420 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13421 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13422 && last_unchanged_at_beg_row > w->current_matrix->rows)
13423 --last_unchanged_at_beg_row;
13424
13425 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13426 GIVE_UP (17);
13427
13428 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13429 GIVE_UP (18);
13430 start_pos = it.current.pos;
13431
13432 /* Start displaying new lines in the desired matrix at the same
13433 vpos we would use in the current matrix, i.e. below
13434 last_unchanged_at_beg_row. */
13435 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13436 current_matrix);
13437 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13438 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13439
13440 xassert (it.hpos == 0 && it.current_x == 0);
13441 }
13442 else
13443 {
13444 /* There are no reusable lines at the start of the window.
13445 Start displaying in the first text line. */
13446 start_display (&it, w, start);
13447 it.vpos = it.first_vpos;
13448 start_pos = it.current.pos;
13449 }
13450
13451 /* Find the first row that is not affected by changes at the end of
13452 the buffer. Value will be null if there is no unchanged row, in
13453 which case we must redisplay to the end of the window. delta
13454 will be set to the value by which buffer positions beginning with
13455 first_unchanged_at_end_row have to be adjusted due to text
13456 changes. */
13457 first_unchanged_at_end_row
13458 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13459 IF_DEBUG (debug_delta = delta);
13460 IF_DEBUG (debug_delta_bytes = delta_bytes);
13461
13462 /* Set stop_pos to the buffer position up to which we will have to
13463 display new lines. If first_unchanged_at_end_row != NULL, this
13464 is the buffer position of the start of the line displayed in that
13465 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13466 that we don't stop at a buffer position. */
13467 stop_pos = 0;
13468 if (first_unchanged_at_end_row)
13469 {
13470 xassert (last_unchanged_at_beg_row == NULL
13471 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13472
13473 /* If this is a continuation line, move forward to the next one
13474 that isn't. Changes in lines above affect this line.
13475 Caution: this may move first_unchanged_at_end_row to a row
13476 not displaying text. */
13477 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13478 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13479 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13480 < it.last_visible_y))
13481 ++first_unchanged_at_end_row;
13482
13483 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13484 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13485 >= it.last_visible_y))
13486 first_unchanged_at_end_row = NULL;
13487 else
13488 {
13489 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13490 + delta);
13491 first_unchanged_at_end_vpos
13492 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13493 xassert (stop_pos >= Z - END_UNCHANGED);
13494 }
13495 }
13496 else if (last_unchanged_at_beg_row == NULL)
13497 GIVE_UP (19);
13498
13499
13500 #if GLYPH_DEBUG
13501
13502 /* Either there is no unchanged row at the end, or the one we have
13503 now displays text. This is a necessary condition for the window
13504 end pos calculation at the end of this function. */
13505 xassert (first_unchanged_at_end_row == NULL
13506 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13507
13508 debug_last_unchanged_at_beg_vpos
13509 = (last_unchanged_at_beg_row
13510 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13511 : -1);
13512 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13513
13514 #endif /* GLYPH_DEBUG != 0 */
13515
13516
13517 /* Display new lines. Set last_text_row to the last new line
13518 displayed which has text on it, i.e. might end up as being the
13519 line where the window_end_vpos is. */
13520 w->cursor.vpos = -1;
13521 last_text_row = NULL;
13522 overlay_arrow_seen = 0;
13523 while (it.current_y < it.last_visible_y
13524 && !fonts_changed_p
13525 && (first_unchanged_at_end_row == NULL
13526 || IT_CHARPOS (it) < stop_pos))
13527 {
13528 if (display_line (&it))
13529 last_text_row = it.glyph_row - 1;
13530 }
13531
13532 if (fonts_changed_p)
13533 return -1;
13534
13535
13536 /* Compute differences in buffer positions, y-positions etc. for
13537 lines reused at the bottom of the window. Compute what we can
13538 scroll. */
13539 if (first_unchanged_at_end_row
13540 /* No lines reused because we displayed everything up to the
13541 bottom of the window. */
13542 && it.current_y < it.last_visible_y)
13543 {
13544 dvpos = (it.vpos
13545 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13546 current_matrix));
13547 dy = it.current_y - first_unchanged_at_end_row->y;
13548 run.current_y = first_unchanged_at_end_row->y;
13549 run.desired_y = run.current_y + dy;
13550 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13551 }
13552 else
13553 {
13554 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13555 first_unchanged_at_end_row = NULL;
13556 }
13557 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13558
13559
13560 /* Find the cursor if not already found. We have to decide whether
13561 PT will appear on this window (it sometimes doesn't, but this is
13562 not a very frequent case.) This decision has to be made before
13563 the current matrix is altered. A value of cursor.vpos < 0 means
13564 that PT is either in one of the lines beginning at
13565 first_unchanged_at_end_row or below the window. Don't care for
13566 lines that might be displayed later at the window end; as
13567 mentioned, this is not a frequent case. */
13568 if (w->cursor.vpos < 0)
13569 {
13570 /* Cursor in unchanged rows at the top? */
13571 if (PT < CHARPOS (start_pos)
13572 && last_unchanged_at_beg_row)
13573 {
13574 row = row_containing_pos (w, PT,
13575 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13576 last_unchanged_at_beg_row + 1, 0);
13577 if (row)
13578 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13579 }
13580
13581 /* Start from first_unchanged_at_end_row looking for PT. */
13582 else if (first_unchanged_at_end_row)
13583 {
13584 row = row_containing_pos (w, PT - delta,
13585 first_unchanged_at_end_row, NULL, 0);
13586 if (row)
13587 set_cursor_from_row (w, row, w->current_matrix, delta,
13588 delta_bytes, dy, dvpos);
13589 }
13590
13591 /* Give up if cursor was not found. */
13592 if (w->cursor.vpos < 0)
13593 {
13594 clear_glyph_matrix (w->desired_matrix);
13595 return -1;
13596 }
13597 }
13598
13599 /* Don't let the cursor end in the scroll margins. */
13600 {
13601 int this_scroll_margin, cursor_height;
13602
13603 this_scroll_margin = max (0, scroll_margin);
13604 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13605 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13606 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13607
13608 if ((w->cursor.y < this_scroll_margin
13609 && CHARPOS (start) > BEGV)
13610 /* Old redisplay didn't take scroll margin into account at the bottom,
13611 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13612 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
13613 {
13614 w->cursor.vpos = -1;
13615 clear_glyph_matrix (w->desired_matrix);
13616 return -1;
13617 }
13618 }
13619
13620 /* Scroll the display. Do it before changing the current matrix so
13621 that xterm.c doesn't get confused about where the cursor glyph is
13622 found. */
13623 if (dy && run.height)
13624 {
13625 update_begin (f);
13626
13627 if (FRAME_WINDOW_P (f))
13628 {
13629 rif->update_window_begin_hook (w);
13630 rif->clear_window_mouse_face (w);
13631 rif->scroll_run_hook (w, &run);
13632 rif->update_window_end_hook (w, 0, 0);
13633 }
13634 else
13635 {
13636 /* Terminal frame. In this case, dvpos gives the number of
13637 lines to scroll by; dvpos < 0 means scroll up. */
13638 int first_unchanged_at_end_vpos
13639 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13640 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13641 int end = (WINDOW_TOP_EDGE_LINE (w)
13642 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13643 + window_internal_height (w));
13644
13645 /* Perform the operation on the screen. */
13646 if (dvpos > 0)
13647 {
13648 /* Scroll last_unchanged_at_beg_row to the end of the
13649 window down dvpos lines. */
13650 set_terminal_window (end);
13651
13652 /* On dumb terminals delete dvpos lines at the end
13653 before inserting dvpos empty lines. */
13654 if (!scroll_region_ok)
13655 ins_del_lines (end - dvpos, -dvpos);
13656
13657 /* Insert dvpos empty lines in front of
13658 last_unchanged_at_beg_row. */
13659 ins_del_lines (from, dvpos);
13660 }
13661 else if (dvpos < 0)
13662 {
13663 /* Scroll up last_unchanged_at_beg_vpos to the end of
13664 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13665 set_terminal_window (end);
13666
13667 /* Delete dvpos lines in front of
13668 last_unchanged_at_beg_vpos. ins_del_lines will set
13669 the cursor to the given vpos and emit |dvpos| delete
13670 line sequences. */
13671 ins_del_lines (from + dvpos, dvpos);
13672
13673 /* On a dumb terminal insert dvpos empty lines at the
13674 end. */
13675 if (!scroll_region_ok)
13676 ins_del_lines (end + dvpos, -dvpos);
13677 }
13678
13679 set_terminal_window (0);
13680 }
13681
13682 update_end (f);
13683 }
13684
13685 /* Shift reused rows of the current matrix to the right position.
13686 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13687 text. */
13688 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13689 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13690 if (dvpos < 0)
13691 {
13692 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13693 bottom_vpos, dvpos);
13694 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13695 bottom_vpos, 0);
13696 }
13697 else if (dvpos > 0)
13698 {
13699 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13700 bottom_vpos, dvpos);
13701 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13702 first_unchanged_at_end_vpos + dvpos, 0);
13703 }
13704
13705 /* For frame-based redisplay, make sure that current frame and window
13706 matrix are in sync with respect to glyph memory. */
13707 if (!FRAME_WINDOW_P (f))
13708 sync_frame_with_window_matrix_rows (w);
13709
13710 /* Adjust buffer positions in reused rows. */
13711 if (delta)
13712 increment_matrix_positions (current_matrix,
13713 first_unchanged_at_end_vpos + dvpos,
13714 bottom_vpos, delta, delta_bytes);
13715
13716 /* Adjust Y positions. */
13717 if (dy)
13718 shift_glyph_matrix (w, current_matrix,
13719 first_unchanged_at_end_vpos + dvpos,
13720 bottom_vpos, dy);
13721
13722 if (first_unchanged_at_end_row)
13723 first_unchanged_at_end_row += dvpos;
13724
13725 /* If scrolling up, there may be some lines to display at the end of
13726 the window. */
13727 last_text_row_at_end = NULL;
13728 if (dy < 0)
13729 {
13730 /* Scrolling up can leave for example a partially visible line
13731 at the end of the window to be redisplayed. */
13732 /* Set last_row to the glyph row in the current matrix where the
13733 window end line is found. It has been moved up or down in
13734 the matrix by dvpos. */
13735 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13736 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13737
13738 /* If last_row is the window end line, it should display text. */
13739 xassert (last_row->displays_text_p);
13740
13741 /* If window end line was partially visible before, begin
13742 displaying at that line. Otherwise begin displaying with the
13743 line following it. */
13744 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13745 {
13746 init_to_row_start (&it, w, last_row);
13747 it.vpos = last_vpos;
13748 it.current_y = last_row->y;
13749 }
13750 else
13751 {
13752 init_to_row_end (&it, w, last_row);
13753 it.vpos = 1 + last_vpos;
13754 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13755 ++last_row;
13756 }
13757
13758 /* We may start in a continuation line. If so, we have to
13759 get the right continuation_lines_width and current_x. */
13760 it.continuation_lines_width = last_row->continuation_lines_width;
13761 it.hpos = it.current_x = 0;
13762
13763 /* Display the rest of the lines at the window end. */
13764 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13765 while (it.current_y < it.last_visible_y
13766 && !fonts_changed_p)
13767 {
13768 /* Is it always sure that the display agrees with lines in
13769 the current matrix? I don't think so, so we mark rows
13770 displayed invalid in the current matrix by setting their
13771 enabled_p flag to zero. */
13772 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13773 if (display_line (&it))
13774 last_text_row_at_end = it.glyph_row - 1;
13775 }
13776 }
13777
13778 /* Update window_end_pos and window_end_vpos. */
13779 if (first_unchanged_at_end_row
13780 && first_unchanged_at_end_row->y < it.last_visible_y
13781 && !last_text_row_at_end)
13782 {
13783 /* Window end line if one of the preserved rows from the current
13784 matrix. Set row to the last row displaying text in current
13785 matrix starting at first_unchanged_at_end_row, after
13786 scrolling. */
13787 xassert (first_unchanged_at_end_row->displays_text_p);
13788 row = find_last_row_displaying_text (w->current_matrix, &it,
13789 first_unchanged_at_end_row);
13790 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13791
13792 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13793 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13794 w->window_end_vpos
13795 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13796 xassert (w->window_end_bytepos >= 0);
13797 IF_DEBUG (debug_method_add (w, "A"));
13798 }
13799 else if (last_text_row_at_end)
13800 {
13801 w->window_end_pos
13802 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13803 w->window_end_bytepos
13804 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13805 w->window_end_vpos
13806 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13807 xassert (w->window_end_bytepos >= 0);
13808 IF_DEBUG (debug_method_add (w, "B"));
13809 }
13810 else if (last_text_row)
13811 {
13812 /* We have displayed either to the end of the window or at the
13813 end of the window, i.e. the last row with text is to be found
13814 in the desired matrix. */
13815 w->window_end_pos
13816 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13817 w->window_end_bytepos
13818 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13819 w->window_end_vpos
13820 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13821 xassert (w->window_end_bytepos >= 0);
13822 }
13823 else if (first_unchanged_at_end_row == NULL
13824 && last_text_row == NULL
13825 && last_text_row_at_end == NULL)
13826 {
13827 /* Displayed to end of window, but no line containing text was
13828 displayed. Lines were deleted at the end of the window. */
13829 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13830 int vpos = XFASTINT (w->window_end_vpos);
13831 struct glyph_row *current_row = current_matrix->rows + vpos;
13832 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13833
13834 for (row = NULL;
13835 row == NULL && vpos >= first_vpos;
13836 --vpos, --current_row, --desired_row)
13837 {
13838 if (desired_row->enabled_p)
13839 {
13840 if (desired_row->displays_text_p)
13841 row = desired_row;
13842 }
13843 else if (current_row->displays_text_p)
13844 row = current_row;
13845 }
13846
13847 xassert (row != NULL);
13848 w->window_end_vpos = make_number (vpos + 1);
13849 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13850 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13851 xassert (w->window_end_bytepos >= 0);
13852 IF_DEBUG (debug_method_add (w, "C"));
13853 }
13854 else
13855 abort ();
13856
13857 #if 0 /* This leads to problems, for instance when the cursor is
13858 at ZV, and the cursor line displays no text. */
13859 /* Disable rows below what's displayed in the window. This makes
13860 debugging easier. */
13861 enable_glyph_matrix_rows (current_matrix,
13862 XFASTINT (w->window_end_vpos) + 1,
13863 bottom_vpos, 0);
13864 #endif
13865
13866 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13867 debug_end_vpos = XFASTINT (w->window_end_vpos));
13868
13869 /* Record that display has not been completed. */
13870 w->window_end_valid = Qnil;
13871 w->desired_matrix->no_scrolling_p = 1;
13872 return 3;
13873
13874 #undef GIVE_UP
13875 }
13876
13877
13878 \f
13879 /***********************************************************************
13880 More debugging support
13881 ***********************************************************************/
13882
13883 #if GLYPH_DEBUG
13884
13885 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13886 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13887 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13888
13889
13890 /* Dump the contents of glyph matrix MATRIX on stderr.
13891
13892 GLYPHS 0 means don't show glyph contents.
13893 GLYPHS 1 means show glyphs in short form
13894 GLYPHS > 1 means show glyphs in long form. */
13895
13896 void
13897 dump_glyph_matrix (matrix, glyphs)
13898 struct glyph_matrix *matrix;
13899 int glyphs;
13900 {
13901 int i;
13902 for (i = 0; i < matrix->nrows; ++i)
13903 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13904 }
13905
13906
13907 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13908 the glyph row and area where the glyph comes from. */
13909
13910 void
13911 dump_glyph (row, glyph, area)
13912 struct glyph_row *row;
13913 struct glyph *glyph;
13914 int area;
13915 {
13916 if (glyph->type == CHAR_GLYPH)
13917 {
13918 fprintf (stderr,
13919 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13920 glyph - row->glyphs[TEXT_AREA],
13921 'C',
13922 glyph->charpos,
13923 (BUFFERP (glyph->object)
13924 ? 'B'
13925 : (STRINGP (glyph->object)
13926 ? 'S'
13927 : '-')),
13928 glyph->pixel_width,
13929 glyph->u.ch,
13930 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13931 ? glyph->u.ch
13932 : '.'),
13933 glyph->face_id,
13934 glyph->left_box_line_p,
13935 glyph->right_box_line_p);
13936 }
13937 else if (glyph->type == STRETCH_GLYPH)
13938 {
13939 fprintf (stderr,
13940 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13941 glyph - row->glyphs[TEXT_AREA],
13942 'S',
13943 glyph->charpos,
13944 (BUFFERP (glyph->object)
13945 ? 'B'
13946 : (STRINGP (glyph->object)
13947 ? 'S'
13948 : '-')),
13949 glyph->pixel_width,
13950 0,
13951 '.',
13952 glyph->face_id,
13953 glyph->left_box_line_p,
13954 glyph->right_box_line_p);
13955 }
13956 else if (glyph->type == IMAGE_GLYPH)
13957 {
13958 fprintf (stderr,
13959 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13960 glyph - row->glyphs[TEXT_AREA],
13961 'I',
13962 glyph->charpos,
13963 (BUFFERP (glyph->object)
13964 ? 'B'
13965 : (STRINGP (glyph->object)
13966 ? 'S'
13967 : '-')),
13968 glyph->pixel_width,
13969 glyph->u.img_id,
13970 '.',
13971 glyph->face_id,
13972 glyph->left_box_line_p,
13973 glyph->right_box_line_p);
13974 }
13975 }
13976
13977
13978 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13979 GLYPHS 0 means don't show glyph contents.
13980 GLYPHS 1 means show glyphs in short form
13981 GLYPHS > 1 means show glyphs in long form. */
13982
13983 void
13984 dump_glyph_row (row, vpos, glyphs)
13985 struct glyph_row *row;
13986 int vpos, glyphs;
13987 {
13988 if (glyphs != 1)
13989 {
13990 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13991 fprintf (stderr, "=======================================================================\n");
13992
13993 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13994 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13995 vpos,
13996 MATRIX_ROW_START_CHARPOS (row),
13997 MATRIX_ROW_END_CHARPOS (row),
13998 row->used[TEXT_AREA],
13999 row->contains_overlapping_glyphs_p,
14000 row->enabled_p,
14001 row->truncated_on_left_p,
14002 row->truncated_on_right_p,
14003 row->overlay_arrow_p,
14004 row->continued_p,
14005 MATRIX_ROW_CONTINUATION_LINE_P (row),
14006 row->displays_text_p,
14007 row->ends_at_zv_p,
14008 row->fill_line_p,
14009 row->ends_in_middle_of_char_p,
14010 row->starts_in_middle_of_char_p,
14011 row->mouse_face_p,
14012 row->x,
14013 row->y,
14014 row->pixel_width,
14015 row->height,
14016 row->visible_height,
14017 row->ascent,
14018 row->phys_ascent);
14019 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14020 row->end.overlay_string_index,
14021 row->continuation_lines_width);
14022 fprintf (stderr, "%9d %5d\n",
14023 CHARPOS (row->start.string_pos),
14024 CHARPOS (row->end.string_pos));
14025 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14026 row->end.dpvec_index);
14027 }
14028
14029 if (glyphs > 1)
14030 {
14031 int area;
14032
14033 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14034 {
14035 struct glyph *glyph = row->glyphs[area];
14036 struct glyph *glyph_end = glyph + row->used[area];
14037
14038 /* Glyph for a line end in text. */
14039 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14040 ++glyph_end;
14041
14042 if (glyph < glyph_end)
14043 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14044
14045 for (; glyph < glyph_end; ++glyph)
14046 dump_glyph (row, glyph, area);
14047 }
14048 }
14049 else if (glyphs == 1)
14050 {
14051 int area;
14052
14053 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14054 {
14055 char *s = (char *) alloca (row->used[area] + 1);
14056 int i;
14057
14058 for (i = 0; i < row->used[area]; ++i)
14059 {
14060 struct glyph *glyph = row->glyphs[area] + i;
14061 if (glyph->type == CHAR_GLYPH
14062 && glyph->u.ch < 0x80
14063 && glyph->u.ch >= ' ')
14064 s[i] = glyph->u.ch;
14065 else
14066 s[i] = '.';
14067 }
14068
14069 s[i] = '\0';
14070 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14071 }
14072 }
14073 }
14074
14075
14076 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14077 Sdump_glyph_matrix, 0, 1, "p",
14078 doc: /* Dump the current matrix of the selected window to stderr.
14079 Shows contents of glyph row structures. With non-nil
14080 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14081 glyphs in short form, otherwise show glyphs in long form. */)
14082 (glyphs)
14083 Lisp_Object glyphs;
14084 {
14085 struct window *w = XWINDOW (selected_window);
14086 struct buffer *buffer = XBUFFER (w->buffer);
14087
14088 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14089 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14090 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14091 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14092 fprintf (stderr, "=============================================\n");
14093 dump_glyph_matrix (w->current_matrix,
14094 NILP (glyphs) ? 0 : XINT (glyphs));
14095 return Qnil;
14096 }
14097
14098
14099 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14100 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14101 ()
14102 {
14103 struct frame *f = XFRAME (selected_frame);
14104 dump_glyph_matrix (f->current_matrix, 1);
14105 return Qnil;
14106 }
14107
14108
14109 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14110 doc: /* Dump glyph row ROW to stderr.
14111 GLYPH 0 means don't dump glyphs.
14112 GLYPH 1 means dump glyphs in short form.
14113 GLYPH > 1 or omitted means dump glyphs in long form. */)
14114 (row, glyphs)
14115 Lisp_Object row, glyphs;
14116 {
14117 struct glyph_matrix *matrix;
14118 int vpos;
14119
14120 CHECK_NUMBER (row);
14121 matrix = XWINDOW (selected_window)->current_matrix;
14122 vpos = XINT (row);
14123 if (vpos >= 0 && vpos < matrix->nrows)
14124 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14125 vpos,
14126 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14127 return Qnil;
14128 }
14129
14130
14131 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14132 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14133 GLYPH 0 means don't dump glyphs.
14134 GLYPH 1 means dump glyphs in short form.
14135 GLYPH > 1 or omitted means dump glyphs in long form. */)
14136 (row, glyphs)
14137 Lisp_Object row, glyphs;
14138 {
14139 struct frame *sf = SELECTED_FRAME ();
14140 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14141 int vpos;
14142
14143 CHECK_NUMBER (row);
14144 vpos = XINT (row);
14145 if (vpos >= 0 && vpos < m->nrows)
14146 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14147 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14148 return Qnil;
14149 }
14150
14151
14152 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14153 doc: /* Toggle tracing of redisplay.
14154 With ARG, turn tracing on if and only if ARG is positive. */)
14155 (arg)
14156 Lisp_Object arg;
14157 {
14158 if (NILP (arg))
14159 trace_redisplay_p = !trace_redisplay_p;
14160 else
14161 {
14162 arg = Fprefix_numeric_value (arg);
14163 trace_redisplay_p = XINT (arg) > 0;
14164 }
14165
14166 return Qnil;
14167 }
14168
14169
14170 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14171 doc: /* Like `format', but print result to stderr.
14172 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14173 (nargs, args)
14174 int nargs;
14175 Lisp_Object *args;
14176 {
14177 Lisp_Object s = Fformat (nargs, args);
14178 fprintf (stderr, "%s", SDATA (s));
14179 return Qnil;
14180 }
14181
14182 #endif /* GLYPH_DEBUG */
14183
14184
14185 \f
14186 /***********************************************************************
14187 Building Desired Matrix Rows
14188 ***********************************************************************/
14189
14190 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14191 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14192
14193 static struct glyph_row *
14194 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14195 struct window *w;
14196 Lisp_Object overlay_arrow_string;
14197 {
14198 struct frame *f = XFRAME (WINDOW_FRAME (w));
14199 struct buffer *buffer = XBUFFER (w->buffer);
14200 struct buffer *old = current_buffer;
14201 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14202 int arrow_len = SCHARS (overlay_arrow_string);
14203 const unsigned char *arrow_end = arrow_string + arrow_len;
14204 const unsigned char *p;
14205 struct it it;
14206 int multibyte_p;
14207 int n_glyphs_before;
14208
14209 set_buffer_temp (buffer);
14210 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14211 it.glyph_row->used[TEXT_AREA] = 0;
14212 SET_TEXT_POS (it.position, 0, 0);
14213
14214 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14215 p = arrow_string;
14216 while (p < arrow_end)
14217 {
14218 Lisp_Object face, ilisp;
14219
14220 /* Get the next character. */
14221 if (multibyte_p)
14222 it.c = string_char_and_length (p, arrow_len, &it.len);
14223 else
14224 it.c = *p, it.len = 1;
14225 p += it.len;
14226
14227 /* Get its face. */
14228 ilisp = make_number (p - arrow_string);
14229 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14230 it.face_id = compute_char_face (f, it.c, face);
14231
14232 /* Compute its width, get its glyphs. */
14233 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14234 SET_TEXT_POS (it.position, -1, -1);
14235 PRODUCE_GLYPHS (&it);
14236
14237 /* If this character doesn't fit any more in the line, we have
14238 to remove some glyphs. */
14239 if (it.current_x > it.last_visible_x)
14240 {
14241 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14242 break;
14243 }
14244 }
14245
14246 set_buffer_temp (old);
14247 return it.glyph_row;
14248 }
14249
14250
14251 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14252 glyphs are only inserted for terminal frames since we can't really
14253 win with truncation glyphs when partially visible glyphs are
14254 involved. Which glyphs to insert is determined by
14255 produce_special_glyphs. */
14256
14257 static void
14258 insert_left_trunc_glyphs (it)
14259 struct it *it;
14260 {
14261 struct it truncate_it;
14262 struct glyph *from, *end, *to, *toend;
14263
14264 xassert (!FRAME_WINDOW_P (it->f));
14265
14266 /* Get the truncation glyphs. */
14267 truncate_it = *it;
14268 truncate_it.current_x = 0;
14269 truncate_it.face_id = DEFAULT_FACE_ID;
14270 truncate_it.glyph_row = &scratch_glyph_row;
14271 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14272 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14273 truncate_it.object = make_number (0);
14274 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14275
14276 /* Overwrite glyphs from IT with truncation glyphs. */
14277 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14278 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14279 to = it->glyph_row->glyphs[TEXT_AREA];
14280 toend = to + it->glyph_row->used[TEXT_AREA];
14281
14282 while (from < end)
14283 *to++ = *from++;
14284
14285 /* There may be padding glyphs left over. Overwrite them too. */
14286 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14287 {
14288 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14289 while (from < end)
14290 *to++ = *from++;
14291 }
14292
14293 if (to > toend)
14294 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14295 }
14296
14297
14298 /* Compute the pixel height and width of IT->glyph_row.
14299
14300 Most of the time, ascent and height of a display line will be equal
14301 to the max_ascent and max_height values of the display iterator
14302 structure. This is not the case if
14303
14304 1. We hit ZV without displaying anything. In this case, max_ascent
14305 and max_height will be zero.
14306
14307 2. We have some glyphs that don't contribute to the line height.
14308 (The glyph row flag contributes_to_line_height_p is for future
14309 pixmap extensions).
14310
14311 The first case is easily covered by using default values because in
14312 these cases, the line height does not really matter, except that it
14313 must not be zero. */
14314
14315 static void
14316 compute_line_metrics (it)
14317 struct it *it;
14318 {
14319 struct glyph_row *row = it->glyph_row;
14320 int area, i;
14321
14322 if (FRAME_WINDOW_P (it->f))
14323 {
14324 int i, min_y, max_y;
14325
14326 /* The line may consist of one space only, that was added to
14327 place the cursor on it. If so, the row's height hasn't been
14328 computed yet. */
14329 if (row->height == 0)
14330 {
14331 if (it->max_ascent + it->max_descent == 0)
14332 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14333 row->ascent = it->max_ascent;
14334 row->height = it->max_ascent + it->max_descent;
14335 row->phys_ascent = it->max_phys_ascent;
14336 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14337 }
14338
14339 /* Compute the width of this line. */
14340 row->pixel_width = row->x;
14341 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14342 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14343
14344 xassert (row->pixel_width >= 0);
14345 xassert (row->ascent >= 0 && row->height > 0);
14346
14347 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14348 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14349
14350 /* If first line's physical ascent is larger than its logical
14351 ascent, use the physical ascent, and make the row taller.
14352 This makes accented characters fully visible. */
14353 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14354 && row->phys_ascent > row->ascent)
14355 {
14356 row->height += row->phys_ascent - row->ascent;
14357 row->ascent = row->phys_ascent;
14358 }
14359
14360 /* Compute how much of the line is visible. */
14361 row->visible_height = row->height;
14362
14363 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14364 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14365
14366 if (row->y < min_y)
14367 row->visible_height -= min_y - row->y;
14368 if (row->y + row->height > max_y)
14369 row->visible_height -= row->y + row->height - max_y;
14370 }
14371 else
14372 {
14373 row->pixel_width = row->used[TEXT_AREA];
14374 if (row->continued_p)
14375 row->pixel_width -= it->continuation_pixel_width;
14376 else if (row->truncated_on_right_p)
14377 row->pixel_width -= it->truncation_pixel_width;
14378 row->ascent = row->phys_ascent = 0;
14379 row->height = row->phys_height = row->visible_height = 1;
14380 }
14381
14382 /* Compute a hash code for this row. */
14383 row->hash = 0;
14384 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14385 for (i = 0; i < row->used[area]; ++i)
14386 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14387 + row->glyphs[area][i].u.val
14388 + row->glyphs[area][i].face_id
14389 + row->glyphs[area][i].padding_p
14390 + (row->glyphs[area][i].type << 2));
14391
14392 it->max_ascent = it->max_descent = 0;
14393 it->max_phys_ascent = it->max_phys_descent = 0;
14394 }
14395
14396
14397 /* Append one space to the glyph row of iterator IT if doing a
14398 window-based redisplay. The space has the same face as
14399 IT->face_id. Value is non-zero if a space was added.
14400
14401 This function is called to make sure that there is always one glyph
14402 at the end of a glyph row that the cursor can be set on under
14403 window-systems. (If there weren't such a glyph we would not know
14404 how wide and tall a box cursor should be displayed).
14405
14406 At the same time this space let's a nicely handle clearing to the
14407 end of the line if the row ends in italic text. */
14408
14409 static int
14410 append_space_for_newline (it, default_face_p)
14411 struct it *it;
14412 int default_face_p;
14413 {
14414 if (FRAME_WINDOW_P (it->f))
14415 {
14416 int n = it->glyph_row->used[TEXT_AREA];
14417
14418 if (it->glyph_row->glyphs[TEXT_AREA] + n
14419 < it->glyph_row->glyphs[1 + TEXT_AREA])
14420 {
14421 /* Save some values that must not be changed.
14422 Must save IT->c and IT->len because otherwise
14423 ITERATOR_AT_END_P wouldn't work anymore after
14424 append_space_for_newline has been called. */
14425 enum display_element_type saved_what = it->what;
14426 int saved_c = it->c, saved_len = it->len;
14427 int saved_x = it->current_x;
14428 int saved_face_id = it->face_id;
14429 struct text_pos saved_pos;
14430 Lisp_Object saved_object;
14431 struct face *face;
14432
14433 saved_object = it->object;
14434 saved_pos = it->position;
14435
14436 it->what = IT_CHARACTER;
14437 bzero (&it->position, sizeof it->position);
14438 it->object = make_number (0);
14439 it->c = ' ';
14440 it->len = 1;
14441
14442 if (default_face_p)
14443 it->face_id = DEFAULT_FACE_ID;
14444 else if (it->face_before_selective_p)
14445 it->face_id = it->saved_face_id;
14446 face = FACE_FROM_ID (it->f, it->face_id);
14447 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
14448
14449 PRODUCE_GLYPHS (it);
14450
14451 it->override_ascent = -1;
14452 it->constrain_row_ascent_descent_p = 0;
14453 it->current_x = saved_x;
14454 it->object = saved_object;
14455 it->position = saved_pos;
14456 it->what = saved_what;
14457 it->face_id = saved_face_id;
14458 it->len = saved_len;
14459 it->c = saved_c;
14460 return 1;
14461 }
14462 }
14463
14464 return 0;
14465 }
14466
14467
14468 /* Extend the face of the last glyph in the text area of IT->glyph_row
14469 to the end of the display line. Called from display_line.
14470 If the glyph row is empty, add a space glyph to it so that we
14471 know the face to draw. Set the glyph row flag fill_line_p. */
14472
14473 static void
14474 extend_face_to_end_of_line (it)
14475 struct it *it;
14476 {
14477 struct face *face;
14478 struct frame *f = it->f;
14479
14480 /* If line is already filled, do nothing. */
14481 if (it->current_x >= it->last_visible_x)
14482 return;
14483
14484 /* Face extension extends the background and box of IT->face_id
14485 to the end of the line. If the background equals the background
14486 of the frame, we don't have to do anything. */
14487 if (it->face_before_selective_p)
14488 face = FACE_FROM_ID (it->f, it->saved_face_id);
14489 else
14490 face = FACE_FROM_ID (f, it->face_id);
14491
14492 if (FRAME_WINDOW_P (f)
14493 && face->box == FACE_NO_BOX
14494 && face->background == FRAME_BACKGROUND_PIXEL (f)
14495 && !face->stipple)
14496 return;
14497
14498 /* Set the glyph row flag indicating that the face of the last glyph
14499 in the text area has to be drawn to the end of the text area. */
14500 it->glyph_row->fill_line_p = 1;
14501
14502 /* If current character of IT is not ASCII, make sure we have the
14503 ASCII face. This will be automatically undone the next time
14504 get_next_display_element returns a multibyte character. Note
14505 that the character will always be single byte in unibyte text. */
14506 if (!ASCII_CHAR_P (it->c))
14507 {
14508 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
14509 }
14510
14511 if (FRAME_WINDOW_P (f))
14512 {
14513 /* If the row is empty, add a space with the current face of IT,
14514 so that we know which face to draw. */
14515 if (it->glyph_row->used[TEXT_AREA] == 0)
14516 {
14517 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14518 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14519 it->glyph_row->used[TEXT_AREA] = 1;
14520 }
14521 }
14522 else
14523 {
14524 /* Save some values that must not be changed. */
14525 int saved_x = it->current_x;
14526 struct text_pos saved_pos;
14527 Lisp_Object saved_object;
14528 enum display_element_type saved_what = it->what;
14529 int saved_face_id = it->face_id;
14530
14531 saved_object = it->object;
14532 saved_pos = it->position;
14533
14534 it->what = IT_CHARACTER;
14535 bzero (&it->position, sizeof it->position);
14536 it->object = make_number (0);
14537 it->c = ' ';
14538 it->len = 1;
14539 it->face_id = face->id;
14540
14541 PRODUCE_GLYPHS (it);
14542
14543 while (it->current_x <= it->last_visible_x)
14544 PRODUCE_GLYPHS (it);
14545
14546 /* Don't count these blanks really. It would let us insert a left
14547 truncation glyph below and make us set the cursor on them, maybe. */
14548 it->current_x = saved_x;
14549 it->object = saved_object;
14550 it->position = saved_pos;
14551 it->what = saved_what;
14552 it->face_id = saved_face_id;
14553 }
14554 }
14555
14556
14557 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14558 trailing whitespace. */
14559
14560 static int
14561 trailing_whitespace_p (charpos)
14562 int charpos;
14563 {
14564 int bytepos = CHAR_TO_BYTE (charpos);
14565 int c = 0;
14566
14567 while (bytepos < ZV_BYTE
14568 && (c = FETCH_CHAR (bytepos),
14569 c == ' ' || c == '\t'))
14570 ++bytepos;
14571
14572 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14573 {
14574 if (bytepos != PT_BYTE)
14575 return 1;
14576 }
14577 return 0;
14578 }
14579
14580
14581 /* Highlight trailing whitespace, if any, in ROW. */
14582
14583 void
14584 highlight_trailing_whitespace (f, row)
14585 struct frame *f;
14586 struct glyph_row *row;
14587 {
14588 int used = row->used[TEXT_AREA];
14589
14590 if (used)
14591 {
14592 struct glyph *start = row->glyphs[TEXT_AREA];
14593 struct glyph *glyph = start + used - 1;
14594
14595 /* Skip over glyphs inserted to display the cursor at the
14596 end of a line, for extending the face of the last glyph
14597 to the end of the line on terminals, and for truncation
14598 and continuation glyphs. */
14599 while (glyph >= start
14600 && glyph->type == CHAR_GLYPH
14601 && INTEGERP (glyph->object))
14602 --glyph;
14603
14604 /* If last glyph is a space or stretch, and it's trailing
14605 whitespace, set the face of all trailing whitespace glyphs in
14606 IT->glyph_row to `trailing-whitespace'. */
14607 if (glyph >= start
14608 && BUFFERP (glyph->object)
14609 && (glyph->type == STRETCH_GLYPH
14610 || (glyph->type == CHAR_GLYPH
14611 && glyph->u.ch == ' '))
14612 && trailing_whitespace_p (glyph->charpos))
14613 {
14614 int face_id = lookup_named_face (f, Qtrailing_whitespace);
14615
14616 while (glyph >= start
14617 && BUFFERP (glyph->object)
14618 && (glyph->type == STRETCH_GLYPH
14619 || (glyph->type == CHAR_GLYPH
14620 && glyph->u.ch == ' ')))
14621 (glyph--)->face_id = face_id;
14622 }
14623 }
14624 }
14625
14626
14627 /* Value is non-zero if glyph row ROW in window W should be
14628 used to hold the cursor. */
14629
14630 static int
14631 cursor_row_p (w, row)
14632 struct window *w;
14633 struct glyph_row *row;
14634 {
14635 int cursor_row_p = 1;
14636
14637 if (PT == MATRIX_ROW_END_CHARPOS (row))
14638 {
14639 /* If the row ends with a newline from a string, we don't want
14640 the cursor there (if the row is continued it doesn't end in a
14641 newline). */
14642 if (CHARPOS (row->end.string_pos) >= 0
14643 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14644 cursor_row_p = row->continued_p;
14645
14646 /* If the row ends at ZV, display the cursor at the end of that
14647 row instead of at the start of the row below. */
14648 else if (row->ends_at_zv_p)
14649 cursor_row_p = 1;
14650 else
14651 cursor_row_p = 0;
14652 }
14653
14654 return cursor_row_p;
14655 }
14656
14657
14658 /* Construct the glyph row IT->glyph_row in the desired matrix of
14659 IT->w from text at the current position of IT. See dispextern.h
14660 for an overview of struct it. Value is non-zero if
14661 IT->glyph_row displays text, as opposed to a line displaying ZV
14662 only. */
14663
14664 static int
14665 display_line (it)
14666 struct it *it;
14667 {
14668 struct glyph_row *row = it->glyph_row;
14669 int overlay_arrow_bitmap;
14670 Lisp_Object overlay_arrow_string;
14671
14672 /* We always start displaying at hpos zero even if hscrolled. */
14673 xassert (it->hpos == 0 && it->current_x == 0);
14674
14675 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14676 >= it->w->desired_matrix->nrows)
14677 {
14678 it->w->nrows_scale_factor++;
14679 fonts_changed_p = 1;
14680 return 0;
14681 }
14682
14683 /* Is IT->w showing the region? */
14684 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14685
14686 /* Clear the result glyph row and enable it. */
14687 prepare_desired_row (row);
14688
14689 row->y = it->current_y;
14690 row->start = it->start;
14691 row->continuation_lines_width = it->continuation_lines_width;
14692 row->displays_text_p = 1;
14693 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14694 it->starts_in_middle_of_char_p = 0;
14695
14696 /* Arrange the overlays nicely for our purposes. Usually, we call
14697 display_line on only one line at a time, in which case this
14698 can't really hurt too much, or we call it on lines which appear
14699 one after another in the buffer, in which case all calls to
14700 recenter_overlay_lists but the first will be pretty cheap. */
14701 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14702
14703 /* Move over display elements that are not visible because we are
14704 hscrolled. This may stop at an x-position < IT->first_visible_x
14705 if the first glyph is partially visible or if we hit a line end. */
14706 if (it->current_x < it->first_visible_x)
14707 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14708 MOVE_TO_POS | MOVE_TO_X);
14709
14710 /* Get the initial row height. This is either the height of the
14711 text hscrolled, if there is any, or zero. */
14712 row->ascent = it->max_ascent;
14713 row->height = it->max_ascent + it->max_descent;
14714 row->phys_ascent = it->max_phys_ascent;
14715 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14716
14717 /* Loop generating characters. The loop is left with IT on the next
14718 character to display. */
14719 while (1)
14720 {
14721 int n_glyphs_before, hpos_before, x_before;
14722 int x, i, nglyphs;
14723 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14724
14725 /* Retrieve the next thing to display. Value is zero if end of
14726 buffer reached. */
14727 if (!get_next_display_element (it))
14728 {
14729 /* Maybe add a space at the end of this line that is used to
14730 display the cursor there under X. Set the charpos of the
14731 first glyph of blank lines not corresponding to any text
14732 to -1. */
14733 #ifdef HAVE_WINDOW_SYSTEM
14734 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14735 row->exact_window_width_line_p = 1;
14736 else
14737 #endif /* HAVE_WINDOW_SYSTEM */
14738 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14739 || row->used[TEXT_AREA] == 0)
14740 {
14741 row->glyphs[TEXT_AREA]->charpos = -1;
14742 row->displays_text_p = 0;
14743
14744 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14745 && (!MINI_WINDOW_P (it->w)
14746 || (minibuf_level && EQ (it->window, minibuf_window))))
14747 row->indicate_empty_line_p = 1;
14748 }
14749
14750 it->continuation_lines_width = 0;
14751 row->ends_at_zv_p = 1;
14752 break;
14753 }
14754
14755 /* Now, get the metrics of what we want to display. This also
14756 generates glyphs in `row' (which is IT->glyph_row). */
14757 n_glyphs_before = row->used[TEXT_AREA];
14758 x = it->current_x;
14759
14760 /* Remember the line height so far in case the next element doesn't
14761 fit on the line. */
14762 if (!it->truncate_lines_p)
14763 {
14764 ascent = it->max_ascent;
14765 descent = it->max_descent;
14766 phys_ascent = it->max_phys_ascent;
14767 phys_descent = it->max_phys_descent;
14768 }
14769
14770 PRODUCE_GLYPHS (it);
14771
14772 /* If this display element was in marginal areas, continue with
14773 the next one. */
14774 if (it->area != TEXT_AREA)
14775 {
14776 row->ascent = max (row->ascent, it->max_ascent);
14777 row->height = max (row->height, it->max_ascent + it->max_descent);
14778 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14779 row->phys_height = max (row->phys_height,
14780 it->max_phys_ascent + it->max_phys_descent);
14781 set_iterator_to_next (it, 1);
14782 continue;
14783 }
14784
14785 /* Does the display element fit on the line? If we truncate
14786 lines, we should draw past the right edge of the window. If
14787 we don't truncate, we want to stop so that we can display the
14788 continuation glyph before the right margin. If lines are
14789 continued, there are two possible strategies for characters
14790 resulting in more than 1 glyph (e.g. tabs): Display as many
14791 glyphs as possible in this line and leave the rest for the
14792 continuation line, or display the whole element in the next
14793 line. Original redisplay did the former, so we do it also. */
14794 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14795 hpos_before = it->hpos;
14796 x_before = x;
14797
14798 if (/* Not a newline. */
14799 nglyphs > 0
14800 /* Glyphs produced fit entirely in the line. */
14801 && it->current_x < it->last_visible_x)
14802 {
14803 it->hpos += nglyphs;
14804 row->ascent = max (row->ascent, it->max_ascent);
14805 row->height = max (row->height, it->max_ascent + it->max_descent);
14806 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14807 row->phys_height = max (row->phys_height,
14808 it->max_phys_ascent + it->max_phys_descent);
14809 if (it->current_x - it->pixel_width < it->first_visible_x)
14810 row->x = x - it->first_visible_x;
14811 }
14812 else
14813 {
14814 int new_x;
14815 struct glyph *glyph;
14816
14817 for (i = 0; i < nglyphs; ++i, x = new_x)
14818 {
14819 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14820 new_x = x + glyph->pixel_width;
14821
14822 if (/* Lines are continued. */
14823 !it->truncate_lines_p
14824 && (/* Glyph doesn't fit on the line. */
14825 new_x > it->last_visible_x
14826 /* Or it fits exactly on a window system frame. */
14827 || (new_x == it->last_visible_x
14828 && FRAME_WINDOW_P (it->f))))
14829 {
14830 /* End of a continued line. */
14831
14832 if (it->hpos == 0
14833 || (new_x == it->last_visible_x
14834 && FRAME_WINDOW_P (it->f)))
14835 {
14836 /* Current glyph is the only one on the line or
14837 fits exactly on the line. We must continue
14838 the line because we can't draw the cursor
14839 after the glyph. */
14840 row->continued_p = 1;
14841 it->current_x = new_x;
14842 it->continuation_lines_width += new_x;
14843 ++it->hpos;
14844 if (i == nglyphs - 1)
14845 {
14846 set_iterator_to_next (it, 1);
14847 #ifdef HAVE_WINDOW_SYSTEM
14848 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14849 {
14850 if (!get_next_display_element (it))
14851 {
14852 row->exact_window_width_line_p = 1;
14853 it->continuation_lines_width = 0;
14854 row->continued_p = 0;
14855 row->ends_at_zv_p = 1;
14856 }
14857 else if (ITERATOR_AT_END_OF_LINE_P (it))
14858 {
14859 row->continued_p = 0;
14860 row->exact_window_width_line_p = 1;
14861 }
14862 }
14863 #endif /* HAVE_WINDOW_SYSTEM */
14864 }
14865 }
14866 else if (CHAR_GLYPH_PADDING_P (*glyph)
14867 && !FRAME_WINDOW_P (it->f))
14868 {
14869 /* A padding glyph that doesn't fit on this line.
14870 This means the whole character doesn't fit
14871 on the line. */
14872 row->used[TEXT_AREA] = n_glyphs_before;
14873
14874 /* Fill the rest of the row with continuation
14875 glyphs like in 20.x. */
14876 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14877 < row->glyphs[1 + TEXT_AREA])
14878 produce_special_glyphs (it, IT_CONTINUATION);
14879
14880 row->continued_p = 1;
14881 it->current_x = x_before;
14882 it->continuation_lines_width += x_before;
14883
14884 /* Restore the height to what it was before the
14885 element not fitting on the line. */
14886 it->max_ascent = ascent;
14887 it->max_descent = descent;
14888 it->max_phys_ascent = phys_ascent;
14889 it->max_phys_descent = phys_descent;
14890 }
14891 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14892 {
14893 /* A TAB that extends past the right edge of the
14894 window. This produces a single glyph on
14895 window system frames. We leave the glyph in
14896 this row and let it fill the row, but don't
14897 consume the TAB. */
14898 it->continuation_lines_width += it->last_visible_x;
14899 row->ends_in_middle_of_char_p = 1;
14900 row->continued_p = 1;
14901 glyph->pixel_width = it->last_visible_x - x;
14902 it->starts_in_middle_of_char_p = 1;
14903 }
14904 else
14905 {
14906 /* Something other than a TAB that draws past
14907 the right edge of the window. Restore
14908 positions to values before the element. */
14909 row->used[TEXT_AREA] = n_glyphs_before + i;
14910
14911 /* Display continuation glyphs. */
14912 if (!FRAME_WINDOW_P (it->f))
14913 produce_special_glyphs (it, IT_CONTINUATION);
14914 row->continued_p = 1;
14915
14916 it->continuation_lines_width += x;
14917
14918 if (nglyphs > 1 && i > 0)
14919 {
14920 row->ends_in_middle_of_char_p = 1;
14921 it->starts_in_middle_of_char_p = 1;
14922 }
14923
14924 /* Restore the height to what it was before the
14925 element not fitting on the line. */
14926 it->max_ascent = ascent;
14927 it->max_descent = descent;
14928 it->max_phys_ascent = phys_ascent;
14929 it->max_phys_descent = phys_descent;
14930 }
14931
14932 break;
14933 }
14934 else if (new_x > it->first_visible_x)
14935 {
14936 /* Increment number of glyphs actually displayed. */
14937 ++it->hpos;
14938
14939 if (x < it->first_visible_x)
14940 /* Glyph is partially visible, i.e. row starts at
14941 negative X position. */
14942 row->x = x - it->first_visible_x;
14943 }
14944 else
14945 {
14946 /* Glyph is completely off the left margin of the
14947 window. This should not happen because of the
14948 move_it_in_display_line at the start of this
14949 function, unless the text display area of the
14950 window is empty. */
14951 xassert (it->first_visible_x <= it->last_visible_x);
14952 }
14953 }
14954
14955 row->ascent = max (row->ascent, it->max_ascent);
14956 row->height = max (row->height, it->max_ascent + it->max_descent);
14957 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14958 row->phys_height = max (row->phys_height,
14959 it->max_phys_ascent + it->max_phys_descent);
14960
14961 /* End of this display line if row is continued. */
14962 if (row->continued_p || row->ends_at_zv_p)
14963 break;
14964 }
14965
14966 at_end_of_line:
14967 /* Is this a line end? If yes, we're also done, after making
14968 sure that a non-default face is extended up to the right
14969 margin of the window. */
14970 if (ITERATOR_AT_END_OF_LINE_P (it))
14971 {
14972 int used_before = row->used[TEXT_AREA];
14973
14974 row->ends_in_newline_from_string_p = STRINGP (it->object);
14975
14976 #ifdef HAVE_WINDOW_SYSTEM
14977 /* Add a space at the end of the line that is used to
14978 display the cursor there. */
14979 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14980 append_space_for_newline (it, 0);
14981 #endif /* HAVE_WINDOW_SYSTEM */
14982
14983 /* Extend the face to the end of the line. */
14984 extend_face_to_end_of_line (it);
14985
14986 /* Make sure we have the position. */
14987 if (used_before == 0)
14988 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14989
14990 /* Consume the line end. This skips over invisible lines. */
14991 set_iterator_to_next (it, 1);
14992 it->continuation_lines_width = 0;
14993 break;
14994 }
14995
14996 /* Proceed with next display element. Note that this skips
14997 over lines invisible because of selective display. */
14998 set_iterator_to_next (it, 1);
14999
15000 /* If we truncate lines, we are done when the last displayed
15001 glyphs reach past the right margin of the window. */
15002 if (it->truncate_lines_p
15003 && (FRAME_WINDOW_P (it->f)
15004 ? (it->current_x >= it->last_visible_x)
15005 : (it->current_x > it->last_visible_x)))
15006 {
15007 /* Maybe add truncation glyphs. */
15008 if (!FRAME_WINDOW_P (it->f))
15009 {
15010 int i, n;
15011
15012 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15013 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15014 break;
15015
15016 for (n = row->used[TEXT_AREA]; i < n; ++i)
15017 {
15018 row->used[TEXT_AREA] = i;
15019 produce_special_glyphs (it, IT_TRUNCATION);
15020 }
15021 }
15022 #ifdef HAVE_WINDOW_SYSTEM
15023 else
15024 {
15025 /* Don't truncate if we can overflow newline into fringe. */
15026 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15027 {
15028 if (!get_next_display_element (it))
15029 {
15030 #ifdef HAVE_WINDOW_SYSTEM
15031 it->continuation_lines_width = 0;
15032 row->ends_at_zv_p = 1;
15033 row->exact_window_width_line_p = 1;
15034 break;
15035 #endif /* HAVE_WINDOW_SYSTEM */
15036 }
15037 if (ITERATOR_AT_END_OF_LINE_P (it))
15038 {
15039 row->exact_window_width_line_p = 1;
15040 goto at_end_of_line;
15041 }
15042 }
15043 }
15044 #endif /* HAVE_WINDOW_SYSTEM */
15045
15046 row->truncated_on_right_p = 1;
15047 it->continuation_lines_width = 0;
15048 reseat_at_next_visible_line_start (it, 0);
15049 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15050 it->hpos = hpos_before;
15051 it->current_x = x_before;
15052 break;
15053 }
15054 }
15055
15056 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15057 at the left window margin. */
15058 if (it->first_visible_x
15059 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15060 {
15061 if (!FRAME_WINDOW_P (it->f))
15062 insert_left_trunc_glyphs (it);
15063 row->truncated_on_left_p = 1;
15064 }
15065
15066 /* If the start of this line is the overlay arrow-position, then
15067 mark this glyph row as the one containing the overlay arrow.
15068 This is clearly a mess with variable size fonts. It would be
15069 better to let it be displayed like cursors under X. */
15070 if (! overlay_arrow_seen
15071 && (overlay_arrow_string
15072 = overlay_arrow_at_row (it, row, &overlay_arrow_bitmap),
15073 !NILP (overlay_arrow_string)))
15074 {
15075 /* Overlay arrow in window redisplay is a fringe bitmap. */
15076 if (STRINGP (overlay_arrow_string))
15077 {
15078 struct glyph_row *arrow_row
15079 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15080 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15081 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15082 struct glyph *p = row->glyphs[TEXT_AREA];
15083 struct glyph *p2, *end;
15084
15085 /* Copy the arrow glyphs. */
15086 while (glyph < arrow_end)
15087 *p++ = *glyph++;
15088
15089 /* Throw away padding glyphs. */
15090 p2 = p;
15091 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15092 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15093 ++p2;
15094 if (p2 > p)
15095 {
15096 while (p2 < end)
15097 *p++ = *p2++;
15098 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15099 }
15100 }
15101 else
15102 {
15103 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
15104 row->overlay_arrow_p = 1;
15105 }
15106 overlay_arrow_seen = 1;
15107 }
15108
15109 /* Compute pixel dimensions of this line. */
15110 compute_line_metrics (it);
15111
15112 /* Remember the position at which this line ends. */
15113 row->end = it->current;
15114
15115 /* Save fringe bitmaps in this row. */
15116 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15117 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15118 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15119 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15120
15121 it->left_user_fringe_bitmap = 0;
15122 it->left_user_fringe_face_id = 0;
15123 it->right_user_fringe_bitmap = 0;
15124 it->right_user_fringe_face_id = 0;
15125
15126 /* Maybe set the cursor. */
15127 if (it->w->cursor.vpos < 0
15128 && PT >= MATRIX_ROW_START_CHARPOS (row)
15129 && PT <= MATRIX_ROW_END_CHARPOS (row)
15130 && cursor_row_p (it->w, row))
15131 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15132
15133 /* Highlight trailing whitespace. */
15134 if (!NILP (Vshow_trailing_whitespace))
15135 highlight_trailing_whitespace (it->f, it->glyph_row);
15136
15137 /* Prepare for the next line. This line starts horizontally at (X
15138 HPOS) = (0 0). Vertical positions are incremented. As a
15139 convenience for the caller, IT->glyph_row is set to the next
15140 row to be used. */
15141 it->current_x = it->hpos = 0;
15142 it->current_y += row->height;
15143 ++it->vpos;
15144 ++it->glyph_row;
15145 it->start = it->current;
15146 return row->displays_text_p;
15147 }
15148
15149
15150 \f
15151 /***********************************************************************
15152 Menu Bar
15153 ***********************************************************************/
15154
15155 /* Redisplay the menu bar in the frame for window W.
15156
15157 The menu bar of X frames that don't have X toolkit support is
15158 displayed in a special window W->frame->menu_bar_window.
15159
15160 The menu bar of terminal frames is treated specially as far as
15161 glyph matrices are concerned. Menu bar lines are not part of
15162 windows, so the update is done directly on the frame matrix rows
15163 for the menu bar. */
15164
15165 static void
15166 display_menu_bar (w)
15167 struct window *w;
15168 {
15169 struct frame *f = XFRAME (WINDOW_FRAME (w));
15170 struct it it;
15171 Lisp_Object items;
15172 int i;
15173
15174 /* Don't do all this for graphical frames. */
15175 #ifdef HAVE_NTGUI
15176 if (!NILP (Vwindow_system))
15177 return;
15178 #endif
15179 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15180 if (FRAME_X_P (f))
15181 return;
15182 #endif
15183 #ifdef MAC_OS
15184 if (FRAME_MAC_P (f))
15185 return;
15186 #endif
15187
15188 #ifdef USE_X_TOOLKIT
15189 xassert (!FRAME_WINDOW_P (f));
15190 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15191 it.first_visible_x = 0;
15192 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15193 #else /* not USE_X_TOOLKIT */
15194 if (FRAME_WINDOW_P (f))
15195 {
15196 /* Menu bar lines are displayed in the desired matrix of the
15197 dummy window menu_bar_window. */
15198 struct window *menu_w;
15199 xassert (WINDOWP (f->menu_bar_window));
15200 menu_w = XWINDOW (f->menu_bar_window);
15201 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15202 MENU_FACE_ID);
15203 it.first_visible_x = 0;
15204 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15205 }
15206 else
15207 {
15208 /* This is a TTY frame, i.e. character hpos/vpos are used as
15209 pixel x/y. */
15210 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15211 MENU_FACE_ID);
15212 it.first_visible_x = 0;
15213 it.last_visible_x = FRAME_COLS (f);
15214 }
15215 #endif /* not USE_X_TOOLKIT */
15216
15217 if (! mode_line_inverse_video)
15218 /* Force the menu-bar to be displayed in the default face. */
15219 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15220
15221 /* Clear all rows of the menu bar. */
15222 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15223 {
15224 struct glyph_row *row = it.glyph_row + i;
15225 clear_glyph_row (row);
15226 row->enabled_p = 1;
15227 row->full_width_p = 1;
15228 }
15229
15230 /* Display all items of the menu bar. */
15231 items = FRAME_MENU_BAR_ITEMS (it.f);
15232 for (i = 0; i < XVECTOR (items)->size; i += 4)
15233 {
15234 Lisp_Object string;
15235
15236 /* Stop at nil string. */
15237 string = AREF (items, i + 1);
15238 if (NILP (string))
15239 break;
15240
15241 /* Remember where item was displayed. */
15242 AREF (items, i + 3) = make_number (it.hpos);
15243
15244 /* Display the item, pad with one space. */
15245 if (it.current_x < it.last_visible_x)
15246 display_string (NULL, string, Qnil, 0, 0, &it,
15247 SCHARS (string) + 1, 0, 0, -1);
15248 }
15249
15250 /* Fill out the line with spaces. */
15251 if (it.current_x < it.last_visible_x)
15252 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15253
15254 /* Compute the total height of the lines. */
15255 compute_line_metrics (&it);
15256 }
15257
15258
15259 \f
15260 /***********************************************************************
15261 Mode Line
15262 ***********************************************************************/
15263
15264 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15265 FORCE is non-zero, redisplay mode lines unconditionally.
15266 Otherwise, redisplay only mode lines that are garbaged. Value is
15267 the number of windows whose mode lines were redisplayed. */
15268
15269 static int
15270 redisplay_mode_lines (window, force)
15271 Lisp_Object window;
15272 int force;
15273 {
15274 int nwindows = 0;
15275
15276 while (!NILP (window))
15277 {
15278 struct window *w = XWINDOW (window);
15279
15280 if (WINDOWP (w->hchild))
15281 nwindows += redisplay_mode_lines (w->hchild, force);
15282 else if (WINDOWP (w->vchild))
15283 nwindows += redisplay_mode_lines (w->vchild, force);
15284 else if (force
15285 || FRAME_GARBAGED_P (XFRAME (w->frame))
15286 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15287 {
15288 struct text_pos lpoint;
15289 struct buffer *old = current_buffer;
15290
15291 /* Set the window's buffer for the mode line display. */
15292 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15293 set_buffer_internal_1 (XBUFFER (w->buffer));
15294
15295 /* Point refers normally to the selected window. For any
15296 other window, set up appropriate value. */
15297 if (!EQ (window, selected_window))
15298 {
15299 struct text_pos pt;
15300
15301 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15302 if (CHARPOS (pt) < BEGV)
15303 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15304 else if (CHARPOS (pt) > (ZV - 1))
15305 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15306 else
15307 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15308 }
15309
15310 /* Display mode lines. */
15311 clear_glyph_matrix (w->desired_matrix);
15312 if (display_mode_lines (w))
15313 {
15314 ++nwindows;
15315 w->must_be_updated_p = 1;
15316 }
15317
15318 /* Restore old settings. */
15319 set_buffer_internal_1 (old);
15320 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15321 }
15322
15323 window = w->next;
15324 }
15325
15326 return nwindows;
15327 }
15328
15329
15330 /* Display the mode and/or top line of window W. Value is the number
15331 of mode lines displayed. */
15332
15333 static int
15334 display_mode_lines (w)
15335 struct window *w;
15336 {
15337 Lisp_Object old_selected_window, old_selected_frame;
15338 int n = 0;
15339
15340 old_selected_frame = selected_frame;
15341 selected_frame = w->frame;
15342 old_selected_window = selected_window;
15343 XSETWINDOW (selected_window, w);
15344
15345 /* These will be set while the mode line specs are processed. */
15346 line_number_displayed = 0;
15347 w->column_number_displayed = Qnil;
15348
15349 if (WINDOW_WANTS_MODELINE_P (w))
15350 {
15351 struct window *sel_w = XWINDOW (old_selected_window);
15352
15353 /* Select mode line face based on the real selected window. */
15354 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15355 current_buffer->mode_line_format);
15356 ++n;
15357 }
15358
15359 if (WINDOW_WANTS_HEADER_LINE_P (w))
15360 {
15361 display_mode_line (w, HEADER_LINE_FACE_ID,
15362 current_buffer->header_line_format);
15363 ++n;
15364 }
15365
15366 selected_frame = old_selected_frame;
15367 selected_window = old_selected_window;
15368 return n;
15369 }
15370
15371
15372 /* Display mode or top line of window W. FACE_ID specifies which line
15373 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15374 FORMAT is the mode line format to display. Value is the pixel
15375 height of the mode line displayed. */
15376
15377 static int
15378 display_mode_line (w, face_id, format)
15379 struct window *w;
15380 enum face_id face_id;
15381 Lisp_Object format;
15382 {
15383 struct it it;
15384 struct face *face;
15385
15386 init_iterator (&it, w, -1, -1, NULL, face_id);
15387 prepare_desired_row (it.glyph_row);
15388
15389 it.glyph_row->mode_line_p = 1;
15390
15391 if (! mode_line_inverse_video)
15392 /* Force the mode-line to be displayed in the default face. */
15393 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15394
15395 /* Temporarily make frame's keyboard the current kboard so that
15396 kboard-local variables in the mode_line_format will get the right
15397 values. */
15398 push_frame_kboard (it.f);
15399 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15400 pop_frame_kboard ();
15401
15402 /* Fill up with spaces. */
15403 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15404
15405 compute_line_metrics (&it);
15406 it.glyph_row->full_width_p = 1;
15407 it.glyph_row->continued_p = 0;
15408 it.glyph_row->truncated_on_left_p = 0;
15409 it.glyph_row->truncated_on_right_p = 0;
15410
15411 /* Make a 3D mode-line have a shadow at its right end. */
15412 face = FACE_FROM_ID (it.f, face_id);
15413 extend_face_to_end_of_line (&it);
15414 if (face->box != FACE_NO_BOX)
15415 {
15416 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15417 + it.glyph_row->used[TEXT_AREA] - 1);
15418 last->right_box_line_p = 1;
15419 }
15420
15421 return it.glyph_row->height;
15422 }
15423
15424 /* Alist that caches the results of :propertize.
15425 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15426 Lisp_Object mode_line_proptrans_alist;
15427
15428 /* List of strings making up the mode-line. */
15429 Lisp_Object mode_line_string_list;
15430
15431 /* Base face property when building propertized mode line string. */
15432 static Lisp_Object mode_line_string_face;
15433 static Lisp_Object mode_line_string_face_prop;
15434
15435
15436 /* Contribute ELT to the mode line for window IT->w. How it
15437 translates into text depends on its data type.
15438
15439 IT describes the display environment in which we display, as usual.
15440
15441 DEPTH is the depth in recursion. It is used to prevent
15442 infinite recursion here.
15443
15444 FIELD_WIDTH is the number of characters the display of ELT should
15445 occupy in the mode line, and PRECISION is the maximum number of
15446 characters to display from ELT's representation. See
15447 display_string for details.
15448
15449 Returns the hpos of the end of the text generated by ELT.
15450
15451 PROPS is a property list to add to any string we encounter.
15452
15453 If RISKY is nonzero, remove (disregard) any properties in any string
15454 we encounter, and ignore :eval and :propertize.
15455
15456 If the global variable `frame_title_ptr' is non-NULL, then the output
15457 is passed to `store_frame_title' instead of `display_string'. */
15458
15459 static int
15460 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15461 struct it *it;
15462 int depth;
15463 int field_width, precision;
15464 Lisp_Object elt, props;
15465 int risky;
15466 {
15467 int n = 0, field, prec;
15468 int literal = 0;
15469
15470 tail_recurse:
15471 if (depth > 100)
15472 elt = build_string ("*too-deep*");
15473
15474 depth++;
15475
15476 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15477 {
15478 case Lisp_String:
15479 {
15480 /* A string: output it and check for %-constructs within it. */
15481 unsigned char c;
15482 const unsigned char *this, *lisp_string;
15483
15484 if (!NILP (props) || risky)
15485 {
15486 Lisp_Object oprops, aelt;
15487 oprops = Ftext_properties_at (make_number (0), elt);
15488
15489 /* If the starting string's properties are not what
15490 we want, translate the string. Also, if the string
15491 is risky, do that anyway. */
15492
15493 if (NILP (Fequal (props, oprops)) || risky)
15494 {
15495 /* If the starting string has properties,
15496 merge the specified ones onto the existing ones. */
15497 if (! NILP (oprops) && !risky)
15498 {
15499 Lisp_Object tem;
15500
15501 oprops = Fcopy_sequence (oprops);
15502 tem = props;
15503 while (CONSP (tem))
15504 {
15505 oprops = Fplist_put (oprops, XCAR (tem),
15506 XCAR (XCDR (tem)));
15507 tem = XCDR (XCDR (tem));
15508 }
15509 props = oprops;
15510 }
15511
15512 aelt = Fassoc (elt, mode_line_proptrans_alist);
15513 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15514 {
15515 mode_line_proptrans_alist
15516 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15517 elt = XCAR (aelt);
15518 }
15519 else
15520 {
15521 Lisp_Object tem;
15522
15523 elt = Fcopy_sequence (elt);
15524 Fset_text_properties (make_number (0), Flength (elt),
15525 props, elt);
15526 /* Add this item to mode_line_proptrans_alist. */
15527 mode_line_proptrans_alist
15528 = Fcons (Fcons (elt, props),
15529 mode_line_proptrans_alist);
15530 /* Truncate mode_line_proptrans_alist
15531 to at most 50 elements. */
15532 tem = Fnthcdr (make_number (50),
15533 mode_line_proptrans_alist);
15534 if (! NILP (tem))
15535 XSETCDR (tem, Qnil);
15536 }
15537 }
15538 }
15539
15540 this = SDATA (elt);
15541 lisp_string = this;
15542
15543 if (literal)
15544 {
15545 prec = precision - n;
15546 if (frame_title_ptr)
15547 n += store_frame_title (SDATA (elt), -1, prec);
15548 else if (!NILP (mode_line_string_list))
15549 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15550 else
15551 n += display_string (NULL, elt, Qnil, 0, 0, it,
15552 0, prec, 0, STRING_MULTIBYTE (elt));
15553
15554 break;
15555 }
15556
15557 while ((precision <= 0 || n < precision)
15558 && *this
15559 && (frame_title_ptr
15560 || !NILP (mode_line_string_list)
15561 || it->current_x < it->last_visible_x))
15562 {
15563 const unsigned char *last = this;
15564
15565 /* Advance to end of string or next format specifier. */
15566 while ((c = *this++) != '\0' && c != '%')
15567 ;
15568
15569 if (this - 1 != last)
15570 {
15571 int nchars, nbytes;
15572
15573 /* Output to end of string or up to '%'. Field width
15574 is length of string. Don't output more than
15575 PRECISION allows us. */
15576 --this;
15577
15578 prec = c_string_width (last, this - last, precision - n,
15579 &nchars, &nbytes);
15580
15581 if (frame_title_ptr)
15582 n += store_frame_title (last, 0, prec);
15583 else if (!NILP (mode_line_string_list))
15584 {
15585 int bytepos = last - lisp_string;
15586 int charpos = string_byte_to_char (elt, bytepos);
15587 int endpos = (precision <= 0 ? SCHARS (elt)
15588 : charpos + nchars);
15589
15590 n += store_mode_line_string (NULL,
15591 Fsubstring (elt, make_number (charpos),
15592 make_number (endpos)),
15593 0, 0, 0, Qnil);
15594 }
15595 else
15596 {
15597 int bytepos = last - lisp_string;
15598 int charpos = string_byte_to_char (elt, bytepos);
15599 n += display_string (NULL, elt, Qnil, 0, charpos,
15600 it, 0, prec, 0,
15601 STRING_MULTIBYTE (elt));
15602 }
15603 }
15604 else /* c == '%' */
15605 {
15606 const unsigned char *percent_position = this;
15607
15608 /* Get the specified minimum width. Zero means
15609 don't pad. */
15610 field = 0;
15611 while ((c = *this++) >= '0' && c <= '9')
15612 field = field * 10 + c - '0';
15613
15614 /* Don't pad beyond the total padding allowed. */
15615 if (field_width - n > 0 && field > field_width - n)
15616 field = field_width - n;
15617
15618 /* Note that either PRECISION <= 0 or N < PRECISION. */
15619 prec = precision - n;
15620
15621 if (c == 'M')
15622 n += display_mode_element (it, depth, field, prec,
15623 Vglobal_mode_string, props,
15624 risky);
15625 else if (c != 0)
15626 {
15627 int multibyte;
15628 int bytepos, charpos;
15629 unsigned char *spec;
15630
15631 bytepos = percent_position - lisp_string;
15632 charpos = (STRING_MULTIBYTE (elt)
15633 ? string_byte_to_char (elt, bytepos)
15634 : bytepos);
15635
15636 spec
15637 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15638
15639 if (frame_title_ptr)
15640 n += store_frame_title (spec, field, prec);
15641 else if (!NILP (mode_line_string_list))
15642 {
15643 int len = strlen (spec);
15644 Lisp_Object tem = make_string (spec, len);
15645 props = Ftext_properties_at (make_number (charpos), elt);
15646 /* Should only keep face property in props */
15647 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15648 }
15649 else
15650 {
15651 int nglyphs_before, nwritten;
15652
15653 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15654 nwritten = display_string (spec, Qnil, elt,
15655 charpos, 0, it,
15656 field, prec, 0,
15657 multibyte);
15658
15659 /* Assign to the glyphs written above the
15660 string where the `%x' came from, position
15661 of the `%'. */
15662 if (nwritten > 0)
15663 {
15664 struct glyph *glyph
15665 = (it->glyph_row->glyphs[TEXT_AREA]
15666 + nglyphs_before);
15667 int i;
15668
15669 for (i = 0; i < nwritten; ++i)
15670 {
15671 glyph[i].object = elt;
15672 glyph[i].charpos = charpos;
15673 }
15674
15675 n += nwritten;
15676 }
15677 }
15678 }
15679 else /* c == 0 */
15680 break;
15681 }
15682 }
15683 }
15684 break;
15685
15686 case Lisp_Symbol:
15687 /* A symbol: process the value of the symbol recursively
15688 as if it appeared here directly. Avoid error if symbol void.
15689 Special case: if value of symbol is a string, output the string
15690 literally. */
15691 {
15692 register Lisp_Object tem;
15693
15694 /* If the variable is not marked as risky to set
15695 then its contents are risky to use. */
15696 if (NILP (Fget (elt, Qrisky_local_variable)))
15697 risky = 1;
15698
15699 tem = Fboundp (elt);
15700 if (!NILP (tem))
15701 {
15702 tem = Fsymbol_value (elt);
15703 /* If value is a string, output that string literally:
15704 don't check for % within it. */
15705 if (STRINGP (tem))
15706 literal = 1;
15707
15708 if (!EQ (tem, elt))
15709 {
15710 /* Give up right away for nil or t. */
15711 elt = tem;
15712 goto tail_recurse;
15713 }
15714 }
15715 }
15716 break;
15717
15718 case Lisp_Cons:
15719 {
15720 register Lisp_Object car, tem;
15721
15722 /* A cons cell: five distinct cases.
15723 If first element is :eval or :propertize, do something special.
15724 If first element is a string or a cons, process all the elements
15725 and effectively concatenate them.
15726 If first element is a negative number, truncate displaying cdr to
15727 at most that many characters. If positive, pad (with spaces)
15728 to at least that many characters.
15729 If first element is a symbol, process the cadr or caddr recursively
15730 according to whether the symbol's value is non-nil or nil. */
15731 car = XCAR (elt);
15732 if (EQ (car, QCeval))
15733 {
15734 /* An element of the form (:eval FORM) means evaluate FORM
15735 and use the result as mode line elements. */
15736
15737 if (risky)
15738 break;
15739
15740 if (CONSP (XCDR (elt)))
15741 {
15742 Lisp_Object spec;
15743 spec = safe_eval (XCAR (XCDR (elt)));
15744 n += display_mode_element (it, depth, field_width - n,
15745 precision - n, spec, props,
15746 risky);
15747 }
15748 }
15749 else if (EQ (car, QCpropertize))
15750 {
15751 /* An element of the form (:propertize ELT PROPS...)
15752 means display ELT but applying properties PROPS. */
15753
15754 if (risky)
15755 break;
15756
15757 if (CONSP (XCDR (elt)))
15758 n += display_mode_element (it, depth, field_width - n,
15759 precision - n, XCAR (XCDR (elt)),
15760 XCDR (XCDR (elt)), risky);
15761 }
15762 else if (SYMBOLP (car))
15763 {
15764 tem = Fboundp (car);
15765 elt = XCDR (elt);
15766 if (!CONSP (elt))
15767 goto invalid;
15768 /* elt is now the cdr, and we know it is a cons cell.
15769 Use its car if CAR has a non-nil value. */
15770 if (!NILP (tem))
15771 {
15772 tem = Fsymbol_value (car);
15773 if (!NILP (tem))
15774 {
15775 elt = XCAR (elt);
15776 goto tail_recurse;
15777 }
15778 }
15779 /* Symbol's value is nil (or symbol is unbound)
15780 Get the cddr of the original list
15781 and if possible find the caddr and use that. */
15782 elt = XCDR (elt);
15783 if (NILP (elt))
15784 break;
15785 else if (!CONSP (elt))
15786 goto invalid;
15787 elt = XCAR (elt);
15788 goto tail_recurse;
15789 }
15790 else if (INTEGERP (car))
15791 {
15792 register int lim = XINT (car);
15793 elt = XCDR (elt);
15794 if (lim < 0)
15795 {
15796 /* Negative int means reduce maximum width. */
15797 if (precision <= 0)
15798 precision = -lim;
15799 else
15800 precision = min (precision, -lim);
15801 }
15802 else if (lim > 0)
15803 {
15804 /* Padding specified. Don't let it be more than
15805 current maximum. */
15806 if (precision > 0)
15807 lim = min (precision, lim);
15808
15809 /* If that's more padding than already wanted, queue it.
15810 But don't reduce padding already specified even if
15811 that is beyond the current truncation point. */
15812 field_width = max (lim, field_width);
15813 }
15814 goto tail_recurse;
15815 }
15816 else if (STRINGP (car) || CONSP (car))
15817 {
15818 register int limit = 50;
15819 /* Limit is to protect against circular lists. */
15820 while (CONSP (elt)
15821 && --limit > 0
15822 && (precision <= 0 || n < precision))
15823 {
15824 n += display_mode_element (it, depth, field_width - n,
15825 precision - n, XCAR (elt),
15826 props, risky);
15827 elt = XCDR (elt);
15828 }
15829 }
15830 }
15831 break;
15832
15833 default:
15834 invalid:
15835 elt = build_string ("*invalid*");
15836 goto tail_recurse;
15837 }
15838
15839 /* Pad to FIELD_WIDTH. */
15840 if (field_width > 0 && n < field_width)
15841 {
15842 if (frame_title_ptr)
15843 n += store_frame_title ("", field_width - n, 0);
15844 else if (!NILP (mode_line_string_list))
15845 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15846 else
15847 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15848 0, 0, 0);
15849 }
15850
15851 return n;
15852 }
15853
15854 /* Store a mode-line string element in mode_line_string_list.
15855
15856 If STRING is non-null, display that C string. Otherwise, the Lisp
15857 string LISP_STRING is displayed.
15858
15859 FIELD_WIDTH is the minimum number of output glyphs to produce.
15860 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15861 with spaces. FIELD_WIDTH <= 0 means don't pad.
15862
15863 PRECISION is the maximum number of characters to output from
15864 STRING. PRECISION <= 0 means don't truncate the string.
15865
15866 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15867 properties to the string.
15868
15869 PROPS are the properties to add to the string.
15870 The mode_line_string_face face property is always added to the string.
15871 */
15872
15873 static int
15874 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15875 char *string;
15876 Lisp_Object lisp_string;
15877 int copy_string;
15878 int field_width;
15879 int precision;
15880 Lisp_Object props;
15881 {
15882 int len;
15883 int n = 0;
15884
15885 if (string != NULL)
15886 {
15887 len = strlen (string);
15888 if (precision > 0 && len > precision)
15889 len = precision;
15890 lisp_string = make_string (string, len);
15891 if (NILP (props))
15892 props = mode_line_string_face_prop;
15893 else if (!NILP (mode_line_string_face))
15894 {
15895 Lisp_Object face = Fplist_get (props, Qface);
15896 props = Fcopy_sequence (props);
15897 if (NILP (face))
15898 face = mode_line_string_face;
15899 else
15900 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15901 props = Fplist_put (props, Qface, face);
15902 }
15903 Fadd_text_properties (make_number (0), make_number (len),
15904 props, lisp_string);
15905 }
15906 else
15907 {
15908 len = XFASTINT (Flength (lisp_string));
15909 if (precision > 0 && len > precision)
15910 {
15911 len = precision;
15912 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15913 precision = -1;
15914 }
15915 if (!NILP (mode_line_string_face))
15916 {
15917 Lisp_Object face;
15918 if (NILP (props))
15919 props = Ftext_properties_at (make_number (0), lisp_string);
15920 face = Fplist_get (props, Qface);
15921 if (NILP (face))
15922 face = mode_line_string_face;
15923 else
15924 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15925 props = Fcons (Qface, Fcons (face, Qnil));
15926 if (copy_string)
15927 lisp_string = Fcopy_sequence (lisp_string);
15928 }
15929 if (!NILP (props))
15930 Fadd_text_properties (make_number (0), make_number (len),
15931 props, lisp_string);
15932 }
15933
15934 if (len > 0)
15935 {
15936 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15937 n += len;
15938 }
15939
15940 if (field_width > len)
15941 {
15942 field_width -= len;
15943 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15944 if (!NILP (props))
15945 Fadd_text_properties (make_number (0), make_number (field_width),
15946 props, lisp_string);
15947 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15948 n += field_width;
15949 }
15950
15951 return n;
15952 }
15953
15954
15955 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15956 0, 4, 0,
15957 doc: /* Return the mode-line of selected window as a string.
15958 First optional arg FORMAT specifies a different format string (see
15959 `mode-line-format' for details) to use. If FORMAT is t, return
15960 the buffer's header-line. Second optional arg WINDOW specifies a
15961 different window to use as the context for the formatting.
15962 If third optional arg NO-PROPS is non-nil, string is not propertized.
15963 Fourth optional arg BUFFER specifies which buffer to use. */)
15964 (format, window, no_props, buffer)
15965 Lisp_Object format, window, no_props, buffer;
15966 {
15967 struct it it;
15968 int len;
15969 struct window *w;
15970 struct buffer *old_buffer = NULL;
15971 enum face_id face_id = DEFAULT_FACE_ID;
15972
15973 if (NILP (window))
15974 window = selected_window;
15975 CHECK_WINDOW (window);
15976 w = XWINDOW (window);
15977
15978 if (NILP (buffer))
15979 buffer = w->buffer;
15980
15981 CHECK_BUFFER (buffer);
15982
15983 if (XBUFFER (buffer) != current_buffer)
15984 {
15985 old_buffer = current_buffer;
15986 set_buffer_internal_1 (XBUFFER (buffer));
15987 }
15988
15989 if (NILP (format) || EQ (format, Qt))
15990 {
15991 face_id = (NILP (format)
15992 ? CURRENT_MODE_LINE_FACE_ID (w)
15993 : HEADER_LINE_FACE_ID);
15994 format = (NILP (format)
15995 ? current_buffer->mode_line_format
15996 : current_buffer->header_line_format);
15997 }
15998
15999 init_iterator (&it, w, -1, -1, NULL, face_id);
16000
16001 if (NILP (no_props))
16002 {
16003 mode_line_string_face
16004 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
16005 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
16006 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
16007
16008 mode_line_string_face_prop
16009 = (NILP (mode_line_string_face) ? Qnil
16010 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
16011
16012 /* We need a dummy last element in mode_line_string_list to
16013 indicate we are building the propertized mode-line string.
16014 Using mode_line_string_face_prop here GC protects it. */
16015 mode_line_string_list
16016 = Fcons (mode_line_string_face_prop, Qnil);
16017 frame_title_ptr = NULL;
16018 }
16019 else
16020 {
16021 mode_line_string_face_prop = Qnil;
16022 mode_line_string_list = Qnil;
16023 frame_title_ptr = frame_title_buf;
16024 }
16025
16026 push_frame_kboard (it.f);
16027 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16028 pop_frame_kboard ();
16029
16030 if (old_buffer)
16031 set_buffer_internal_1 (old_buffer);
16032
16033 if (NILP (no_props))
16034 {
16035 Lisp_Object str;
16036 mode_line_string_list = Fnreverse (mode_line_string_list);
16037 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
16038 make_string ("", 0));
16039 mode_line_string_face_prop = Qnil;
16040 mode_line_string_list = Qnil;
16041 return str;
16042 }
16043
16044 len = frame_title_ptr - frame_title_buf;
16045 if (len > 0 && frame_title_ptr[-1] == '-')
16046 {
16047 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16048 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
16049 ;
16050 frame_title_ptr += 3; /* restore last non-dash + two dashes */
16051 if (len > frame_title_ptr - frame_title_buf)
16052 len = frame_title_ptr - frame_title_buf;
16053 }
16054
16055 frame_title_ptr = NULL;
16056 return make_string (frame_title_buf, len);
16057 }
16058
16059 /* Write a null-terminated, right justified decimal representation of
16060 the positive integer D to BUF using a minimal field width WIDTH. */
16061
16062 static void
16063 pint2str (buf, width, d)
16064 register char *buf;
16065 register int width;
16066 register int d;
16067 {
16068 register char *p = buf;
16069
16070 if (d <= 0)
16071 *p++ = '0';
16072 else
16073 {
16074 while (d > 0)
16075 {
16076 *p++ = d % 10 + '0';
16077 d /= 10;
16078 }
16079 }
16080
16081 for (width -= (int) (p - buf); width > 0; --width)
16082 *p++ = ' ';
16083 *p-- = '\0';
16084 while (p > buf)
16085 {
16086 d = *buf;
16087 *buf++ = *p;
16088 *p-- = d;
16089 }
16090 }
16091
16092 /* Write a null-terminated, right justified decimal and "human
16093 readable" representation of the nonnegative integer D to BUF using
16094 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16095
16096 static const char power_letter[] =
16097 {
16098 0, /* not used */
16099 'k', /* kilo */
16100 'M', /* mega */
16101 'G', /* giga */
16102 'T', /* tera */
16103 'P', /* peta */
16104 'E', /* exa */
16105 'Z', /* zetta */
16106 'Y' /* yotta */
16107 };
16108
16109 static void
16110 pint2hrstr (buf, width, d)
16111 char *buf;
16112 int width;
16113 int d;
16114 {
16115 /* We aim to represent the nonnegative integer D as
16116 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16117 int quotient = d;
16118 int remainder = 0;
16119 /* -1 means: do not use TENTHS. */
16120 int tenths = -1;
16121 int exponent = 0;
16122
16123 /* Length of QUOTIENT.TENTHS as a string. */
16124 int length;
16125
16126 char * psuffix;
16127 char * p;
16128
16129 if (1000 <= quotient)
16130 {
16131 /* Scale to the appropriate EXPONENT. */
16132 do
16133 {
16134 remainder = quotient % 1000;
16135 quotient /= 1000;
16136 exponent++;
16137 }
16138 while (1000 <= quotient);
16139
16140 /* Round to nearest and decide whether to use TENTHS or not. */
16141 if (quotient <= 9)
16142 {
16143 tenths = remainder / 100;
16144 if (50 <= remainder % 100)
16145 if (tenths < 9)
16146 tenths++;
16147 else
16148 {
16149 quotient++;
16150 if (quotient == 10)
16151 tenths = -1;
16152 else
16153 tenths = 0;
16154 }
16155 }
16156 else
16157 if (500 <= remainder)
16158 if (quotient < 999)
16159 quotient++;
16160 else
16161 {
16162 quotient = 1;
16163 exponent++;
16164 tenths = 0;
16165 }
16166 }
16167
16168 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16169 if (tenths == -1 && quotient <= 99)
16170 if (quotient <= 9)
16171 length = 1;
16172 else
16173 length = 2;
16174 else
16175 length = 3;
16176 p = psuffix = buf + max (width, length);
16177
16178 /* Print EXPONENT. */
16179 if (exponent)
16180 *psuffix++ = power_letter[exponent];
16181 *psuffix = '\0';
16182
16183 /* Print TENTHS. */
16184 if (tenths >= 0)
16185 {
16186 *--p = '0' + tenths;
16187 *--p = '.';
16188 }
16189
16190 /* Print QUOTIENT. */
16191 do
16192 {
16193 int digit = quotient % 10;
16194 *--p = '0' + digit;
16195 }
16196 while ((quotient /= 10) != 0);
16197
16198 /* Print leading spaces. */
16199 while (buf < p)
16200 *--p = ' ';
16201 }
16202
16203 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16204 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16205 type of CODING_SYSTEM. Return updated pointer into BUF. */
16206
16207 static unsigned char invalid_eol_type[] = "(*invalid*)";
16208
16209 static char *
16210 decode_mode_spec_coding (coding_system, buf, eol_flag)
16211 Lisp_Object coding_system;
16212 register char *buf;
16213 int eol_flag;
16214 {
16215 Lisp_Object val;
16216 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16217 const unsigned char *eol_str;
16218 int eol_str_len;
16219 /* The EOL conversion we are using. */
16220 Lisp_Object eoltype;
16221
16222 val = CODING_SYSTEM_SPEC (coding_system);
16223 eoltype = Qnil;
16224
16225 if (!VECTORP (val)) /* Not yet decided. */
16226 {
16227 if (multibyte)
16228 *buf++ = '-';
16229 if (eol_flag)
16230 eoltype = eol_mnemonic_undecided;
16231 /* Don't mention EOL conversion if it isn't decided. */
16232 }
16233 else
16234 {
16235 Lisp_Object attrs;
16236 Lisp_Object eolvalue;
16237
16238 attrs = AREF (val, 0);
16239 eolvalue = AREF (val, 2);
16240
16241 if (multibyte)
16242 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
16243
16244 if (eol_flag)
16245 {
16246 /* The EOL conversion that is normal on this system. */
16247
16248 if (NILP (eolvalue)) /* Not yet decided. */
16249 eoltype = eol_mnemonic_undecided;
16250 else if (VECTORP (eolvalue)) /* Not yet decided. */
16251 eoltype = eol_mnemonic_undecided;
16252 else /* eolvalue is Qunix, Qdos, or Qmac. */
16253 eoltype = (EQ (eolvalue, Qunix)
16254 ? eol_mnemonic_unix
16255 : (EQ (eolvalue, Qdos) == 1
16256 ? eol_mnemonic_dos : eol_mnemonic_mac));
16257 }
16258 }
16259
16260 if (eol_flag)
16261 {
16262 /* Mention the EOL conversion if it is not the usual one. */
16263 if (STRINGP (eoltype))
16264 {
16265 eol_str = SDATA (eoltype);
16266 eol_str_len = SBYTES (eoltype);
16267 }
16268 else if (CHARACTERP (eoltype))
16269 {
16270 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16271 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16272 eol_str = tmp;
16273 }
16274 else
16275 {
16276 eol_str = invalid_eol_type;
16277 eol_str_len = sizeof (invalid_eol_type) - 1;
16278 }
16279 bcopy (eol_str, buf, eol_str_len);
16280 buf += eol_str_len;
16281 }
16282
16283 return buf;
16284 }
16285
16286 /* Return a string for the output of a mode line %-spec for window W,
16287 generated by character C. PRECISION >= 0 means don't return a
16288 string longer than that value. FIELD_WIDTH > 0 means pad the
16289 string returned with spaces to that value. Return 1 in *MULTIBYTE
16290 if the result is multibyte text.
16291
16292 Note we operate on the current buffer for most purposes,
16293 the exception being w->base_line_pos. */
16294
16295 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16296
16297 static char *
16298 decode_mode_spec (w, c, field_width, precision, multibyte)
16299 struct window *w;
16300 register int c;
16301 int field_width, precision;
16302 int *multibyte;
16303 {
16304 Lisp_Object obj;
16305 struct frame *f = XFRAME (WINDOW_FRAME (w));
16306 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16307 struct buffer *b = current_buffer;
16308
16309 obj = Qnil;
16310 *multibyte = 0;
16311
16312 switch (c)
16313 {
16314 case '*':
16315 if (!NILP (b->read_only))
16316 return "%";
16317 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16318 return "*";
16319 return "-";
16320
16321 case '+':
16322 /* This differs from %* only for a modified read-only buffer. */
16323 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16324 return "*";
16325 if (!NILP (b->read_only))
16326 return "%";
16327 return "-";
16328
16329 case '&':
16330 /* This differs from %* in ignoring read-only-ness. */
16331 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16332 return "*";
16333 return "-";
16334
16335 case '%':
16336 return "%";
16337
16338 case '[':
16339 {
16340 int i;
16341 char *p;
16342
16343 if (command_loop_level > 5)
16344 return "[[[... ";
16345 p = decode_mode_spec_buf;
16346 for (i = 0; i < command_loop_level; i++)
16347 *p++ = '[';
16348 *p = 0;
16349 return decode_mode_spec_buf;
16350 }
16351
16352 case ']':
16353 {
16354 int i;
16355 char *p;
16356
16357 if (command_loop_level > 5)
16358 return " ...]]]";
16359 p = decode_mode_spec_buf;
16360 for (i = 0; i < command_loop_level; i++)
16361 *p++ = ']';
16362 *p = 0;
16363 return decode_mode_spec_buf;
16364 }
16365
16366 case '-':
16367 {
16368 register int i;
16369
16370 /* Let lots_of_dashes be a string of infinite length. */
16371 if (!NILP (mode_line_string_list))
16372 return "--";
16373 if (field_width <= 0
16374 || field_width > sizeof (lots_of_dashes))
16375 {
16376 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16377 decode_mode_spec_buf[i] = '-';
16378 decode_mode_spec_buf[i] = '\0';
16379 return decode_mode_spec_buf;
16380 }
16381 else
16382 return lots_of_dashes;
16383 }
16384
16385 case 'b':
16386 obj = b->name;
16387 break;
16388
16389 case 'c':
16390 {
16391 int col = (int) current_column (); /* iftc */
16392 w->column_number_displayed = make_number (col);
16393 pint2str (decode_mode_spec_buf, field_width, col);
16394 return decode_mode_spec_buf;
16395 }
16396
16397 case 'F':
16398 /* %F displays the frame name. */
16399 if (!NILP (f->title))
16400 return (char *) SDATA (f->title);
16401 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16402 return (char *) SDATA (f->name);
16403 return "Emacs";
16404
16405 case 'f':
16406 obj = b->filename;
16407 break;
16408
16409 case 'i':
16410 {
16411 int size = ZV - BEGV;
16412 pint2str (decode_mode_spec_buf, field_width, size);
16413 return decode_mode_spec_buf;
16414 }
16415
16416 case 'I':
16417 {
16418 int size = ZV - BEGV;
16419 pint2hrstr (decode_mode_spec_buf, field_width, size);
16420 return decode_mode_spec_buf;
16421 }
16422
16423 case 'l':
16424 {
16425 int startpos = XMARKER (w->start)->charpos;
16426 int startpos_byte = marker_byte_position (w->start);
16427 int line, linepos, linepos_byte, topline;
16428 int nlines, junk;
16429 int height = WINDOW_TOTAL_LINES (w);
16430
16431 /* If we decided that this buffer isn't suitable for line numbers,
16432 don't forget that too fast. */
16433 if (EQ (w->base_line_pos, w->buffer))
16434 goto no_value;
16435 /* But do forget it, if the window shows a different buffer now. */
16436 else if (BUFFERP (w->base_line_pos))
16437 w->base_line_pos = Qnil;
16438
16439 /* If the buffer is very big, don't waste time. */
16440 if (INTEGERP (Vline_number_display_limit)
16441 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16442 {
16443 w->base_line_pos = Qnil;
16444 w->base_line_number = Qnil;
16445 goto no_value;
16446 }
16447
16448 if (!NILP (w->base_line_number)
16449 && !NILP (w->base_line_pos)
16450 && XFASTINT (w->base_line_pos) <= startpos)
16451 {
16452 line = XFASTINT (w->base_line_number);
16453 linepos = XFASTINT (w->base_line_pos);
16454 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16455 }
16456 else
16457 {
16458 line = 1;
16459 linepos = BUF_BEGV (b);
16460 linepos_byte = BUF_BEGV_BYTE (b);
16461 }
16462
16463 /* Count lines from base line to window start position. */
16464 nlines = display_count_lines (linepos, linepos_byte,
16465 startpos_byte,
16466 startpos, &junk);
16467
16468 topline = nlines + line;
16469
16470 /* Determine a new base line, if the old one is too close
16471 or too far away, or if we did not have one.
16472 "Too close" means it's plausible a scroll-down would
16473 go back past it. */
16474 if (startpos == BUF_BEGV (b))
16475 {
16476 w->base_line_number = make_number (topline);
16477 w->base_line_pos = make_number (BUF_BEGV (b));
16478 }
16479 else if (nlines < height + 25 || nlines > height * 3 + 50
16480 || linepos == BUF_BEGV (b))
16481 {
16482 int limit = BUF_BEGV (b);
16483 int limit_byte = BUF_BEGV_BYTE (b);
16484 int position;
16485 int distance = (height * 2 + 30) * line_number_display_limit_width;
16486
16487 if (startpos - distance > limit)
16488 {
16489 limit = startpos - distance;
16490 limit_byte = CHAR_TO_BYTE (limit);
16491 }
16492
16493 nlines = display_count_lines (startpos, startpos_byte,
16494 limit_byte,
16495 - (height * 2 + 30),
16496 &position);
16497 /* If we couldn't find the lines we wanted within
16498 line_number_display_limit_width chars per line,
16499 give up on line numbers for this window. */
16500 if (position == limit_byte && limit == startpos - distance)
16501 {
16502 w->base_line_pos = w->buffer;
16503 w->base_line_number = Qnil;
16504 goto no_value;
16505 }
16506
16507 w->base_line_number = make_number (topline - nlines);
16508 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16509 }
16510
16511 /* Now count lines from the start pos to point. */
16512 nlines = display_count_lines (startpos, startpos_byte,
16513 PT_BYTE, PT, &junk);
16514
16515 /* Record that we did display the line number. */
16516 line_number_displayed = 1;
16517
16518 /* Make the string to show. */
16519 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16520 return decode_mode_spec_buf;
16521 no_value:
16522 {
16523 char* p = decode_mode_spec_buf;
16524 int pad = field_width - 2;
16525 while (pad-- > 0)
16526 *p++ = ' ';
16527 *p++ = '?';
16528 *p++ = '?';
16529 *p = '\0';
16530 return decode_mode_spec_buf;
16531 }
16532 }
16533 break;
16534
16535 case 'm':
16536 obj = b->mode_name;
16537 break;
16538
16539 case 'n':
16540 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16541 return " Narrow";
16542 break;
16543
16544 case 'p':
16545 {
16546 int pos = marker_position (w->start);
16547 int total = BUF_ZV (b) - BUF_BEGV (b);
16548
16549 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16550 {
16551 if (pos <= BUF_BEGV (b))
16552 return "All";
16553 else
16554 return "Bottom";
16555 }
16556 else if (pos <= BUF_BEGV (b))
16557 return "Top";
16558 else
16559 {
16560 if (total > 1000000)
16561 /* Do it differently for a large value, to avoid overflow. */
16562 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16563 else
16564 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16565 /* We can't normally display a 3-digit number,
16566 so get us a 2-digit number that is close. */
16567 if (total == 100)
16568 total = 99;
16569 sprintf (decode_mode_spec_buf, "%2d%%", total);
16570 return decode_mode_spec_buf;
16571 }
16572 }
16573
16574 /* Display percentage of size above the bottom of the screen. */
16575 case 'P':
16576 {
16577 int toppos = marker_position (w->start);
16578 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16579 int total = BUF_ZV (b) - BUF_BEGV (b);
16580
16581 if (botpos >= BUF_ZV (b))
16582 {
16583 if (toppos <= BUF_BEGV (b))
16584 return "All";
16585 else
16586 return "Bottom";
16587 }
16588 else
16589 {
16590 if (total > 1000000)
16591 /* Do it differently for a large value, to avoid overflow. */
16592 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16593 else
16594 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16595 /* We can't normally display a 3-digit number,
16596 so get us a 2-digit number that is close. */
16597 if (total == 100)
16598 total = 99;
16599 if (toppos <= BUF_BEGV (b))
16600 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16601 else
16602 sprintf (decode_mode_spec_buf, "%2d%%", total);
16603 return decode_mode_spec_buf;
16604 }
16605 }
16606
16607 case 's':
16608 /* status of process */
16609 obj = Fget_buffer_process (Fcurrent_buffer ());
16610 if (NILP (obj))
16611 return "no process";
16612 #ifdef subprocesses
16613 obj = Fsymbol_name (Fprocess_status (obj));
16614 #endif
16615 break;
16616
16617 case 't': /* indicate TEXT or BINARY */
16618 #ifdef MODE_LINE_BINARY_TEXT
16619 return MODE_LINE_BINARY_TEXT (b);
16620 #else
16621 return "T";
16622 #endif
16623
16624 case 'z':
16625 /* coding-system (not including end-of-line format) */
16626 case 'Z':
16627 /* coding-system (including end-of-line type) */
16628 {
16629 int eol_flag = (c == 'Z');
16630 char *p = decode_mode_spec_buf;
16631
16632 if (! FRAME_WINDOW_P (f))
16633 {
16634 /* No need to mention EOL here--the terminal never needs
16635 to do EOL conversion. */
16636 p = decode_mode_spec_coding (CODING_ID_NAME (keyboard_coding.id),
16637 p, 0);
16638 p = decode_mode_spec_coding (CODING_ID_NAME (terminal_coding.id),
16639 p, 0);
16640 }
16641 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16642 p, eol_flag);
16643
16644 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16645 #ifdef subprocesses
16646 obj = Fget_buffer_process (Fcurrent_buffer ());
16647 if (PROCESSP (obj))
16648 {
16649 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16650 p, eol_flag);
16651 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16652 p, eol_flag);
16653 }
16654 #endif /* subprocesses */
16655 #endif /* 0 */
16656 *p = 0;
16657 return decode_mode_spec_buf;
16658 }
16659 }
16660
16661 if (STRINGP (obj))
16662 {
16663 *multibyte = STRING_MULTIBYTE (obj);
16664 return (char *) SDATA (obj);
16665 }
16666 else
16667 return "";
16668 }
16669
16670
16671 /* Count up to COUNT lines starting from START / START_BYTE.
16672 But don't go beyond LIMIT_BYTE.
16673 Return the number of lines thus found (always nonnegative).
16674
16675 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16676
16677 static int
16678 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16679 int start, start_byte, limit_byte, count;
16680 int *byte_pos_ptr;
16681 {
16682 register unsigned char *cursor;
16683 unsigned char *base;
16684
16685 register int ceiling;
16686 register unsigned char *ceiling_addr;
16687 int orig_count = count;
16688
16689 /* If we are not in selective display mode,
16690 check only for newlines. */
16691 int selective_display = (!NILP (current_buffer->selective_display)
16692 && !INTEGERP (current_buffer->selective_display));
16693
16694 if (count > 0)
16695 {
16696 while (start_byte < limit_byte)
16697 {
16698 ceiling = BUFFER_CEILING_OF (start_byte);
16699 ceiling = min (limit_byte - 1, ceiling);
16700 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16701 base = (cursor = BYTE_POS_ADDR (start_byte));
16702 while (1)
16703 {
16704 if (selective_display)
16705 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16706 ;
16707 else
16708 while (*cursor != '\n' && ++cursor != ceiling_addr)
16709 ;
16710
16711 if (cursor != ceiling_addr)
16712 {
16713 if (--count == 0)
16714 {
16715 start_byte += cursor - base + 1;
16716 *byte_pos_ptr = start_byte;
16717 return orig_count;
16718 }
16719 else
16720 if (++cursor == ceiling_addr)
16721 break;
16722 }
16723 else
16724 break;
16725 }
16726 start_byte += cursor - base;
16727 }
16728 }
16729 else
16730 {
16731 while (start_byte > limit_byte)
16732 {
16733 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16734 ceiling = max (limit_byte, ceiling);
16735 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16736 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16737 while (1)
16738 {
16739 if (selective_display)
16740 while (--cursor != ceiling_addr
16741 && *cursor != '\n' && *cursor != 015)
16742 ;
16743 else
16744 while (--cursor != ceiling_addr && *cursor != '\n')
16745 ;
16746
16747 if (cursor != ceiling_addr)
16748 {
16749 if (++count == 0)
16750 {
16751 start_byte += cursor - base + 1;
16752 *byte_pos_ptr = start_byte;
16753 /* When scanning backwards, we should
16754 not count the newline posterior to which we stop. */
16755 return - orig_count - 1;
16756 }
16757 }
16758 else
16759 break;
16760 }
16761 /* Here we add 1 to compensate for the last decrement
16762 of CURSOR, which took it past the valid range. */
16763 start_byte += cursor - base + 1;
16764 }
16765 }
16766
16767 *byte_pos_ptr = limit_byte;
16768
16769 if (count < 0)
16770 return - orig_count + count;
16771 return orig_count - count;
16772
16773 }
16774
16775
16776 \f
16777 /***********************************************************************
16778 Displaying strings
16779 ***********************************************************************/
16780
16781 /* Display a NUL-terminated string, starting with index START.
16782
16783 If STRING is non-null, display that C string. Otherwise, the Lisp
16784 string LISP_STRING is displayed.
16785
16786 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16787 FACE_STRING. Display STRING or LISP_STRING with the face at
16788 FACE_STRING_POS in FACE_STRING:
16789
16790 Display the string in the environment given by IT, but use the
16791 standard display table, temporarily.
16792
16793 FIELD_WIDTH is the minimum number of output glyphs to produce.
16794 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16795 with spaces. If STRING has more characters, more than FIELD_WIDTH
16796 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16797
16798 PRECISION is the maximum number of characters to output from
16799 STRING. PRECISION < 0 means don't truncate the string.
16800
16801 This is roughly equivalent to printf format specifiers:
16802
16803 FIELD_WIDTH PRECISION PRINTF
16804 ----------------------------------------
16805 -1 -1 %s
16806 -1 10 %.10s
16807 10 -1 %10s
16808 20 10 %20.10s
16809
16810 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16811 display them, and < 0 means obey the current buffer's value of
16812 enable_multibyte_characters.
16813
16814 Value is the number of glyphs produced. */
16815
16816 static int
16817 display_string (string, lisp_string, face_string, face_string_pos,
16818 start, it, field_width, precision, max_x, multibyte)
16819 unsigned char *string;
16820 Lisp_Object lisp_string;
16821 Lisp_Object face_string;
16822 int face_string_pos;
16823 int start;
16824 struct it *it;
16825 int field_width, precision, max_x;
16826 int multibyte;
16827 {
16828 int hpos_at_start = it->hpos;
16829 int saved_face_id = it->face_id;
16830 struct glyph_row *row = it->glyph_row;
16831
16832 /* Initialize the iterator IT for iteration over STRING beginning
16833 with index START. */
16834 reseat_to_string (it, string, lisp_string, start,
16835 precision, field_width, multibyte);
16836
16837 /* If displaying STRING, set up the face of the iterator
16838 from LISP_STRING, if that's given. */
16839 if (STRINGP (face_string))
16840 {
16841 int endptr;
16842 struct face *face;
16843
16844 it->face_id
16845 = face_at_string_position (it->w, face_string, face_string_pos,
16846 0, it->region_beg_charpos,
16847 it->region_end_charpos,
16848 &endptr, it->base_face_id, 0);
16849 face = FACE_FROM_ID (it->f, it->face_id);
16850 it->face_box_p = face->box != FACE_NO_BOX;
16851 }
16852
16853 /* Set max_x to the maximum allowed X position. Don't let it go
16854 beyond the right edge of the window. */
16855 if (max_x <= 0)
16856 max_x = it->last_visible_x;
16857 else
16858 max_x = min (max_x, it->last_visible_x);
16859
16860 /* Skip over display elements that are not visible. because IT->w is
16861 hscrolled. */
16862 if (it->current_x < it->first_visible_x)
16863 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16864 MOVE_TO_POS | MOVE_TO_X);
16865
16866 row->ascent = it->max_ascent;
16867 row->height = it->max_ascent + it->max_descent;
16868 row->phys_ascent = it->max_phys_ascent;
16869 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16870
16871 /* This condition is for the case that we are called with current_x
16872 past last_visible_x. */
16873 while (it->current_x < max_x)
16874 {
16875 int x_before, x, n_glyphs_before, i, nglyphs;
16876
16877 /* Get the next display element. */
16878 if (!get_next_display_element (it))
16879 break;
16880
16881 /* Produce glyphs. */
16882 x_before = it->current_x;
16883 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16884 PRODUCE_GLYPHS (it);
16885
16886 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16887 i = 0;
16888 x = x_before;
16889 while (i < nglyphs)
16890 {
16891 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16892
16893 if (!it->truncate_lines_p
16894 && x + glyph->pixel_width > max_x)
16895 {
16896 /* End of continued line or max_x reached. */
16897 if (CHAR_GLYPH_PADDING_P (*glyph))
16898 {
16899 /* A wide character is unbreakable. */
16900 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16901 it->current_x = x_before;
16902 }
16903 else
16904 {
16905 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16906 it->current_x = x;
16907 }
16908 break;
16909 }
16910 else if (x + glyph->pixel_width >= it->first_visible_x)
16911 {
16912 /* Glyph is at least partially visible. */
16913 ++it->hpos;
16914 if (x < it->first_visible_x)
16915 it->glyph_row->x = x - it->first_visible_x;
16916 }
16917 else
16918 {
16919 /* Glyph is off the left margin of the display area.
16920 Should not happen. */
16921 abort ();
16922 }
16923
16924 row->ascent = max (row->ascent, it->max_ascent);
16925 row->height = max (row->height, it->max_ascent + it->max_descent);
16926 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16927 row->phys_height = max (row->phys_height,
16928 it->max_phys_ascent + it->max_phys_descent);
16929 x += glyph->pixel_width;
16930 ++i;
16931 }
16932
16933 /* Stop if max_x reached. */
16934 if (i < nglyphs)
16935 break;
16936
16937 /* Stop at line ends. */
16938 if (ITERATOR_AT_END_OF_LINE_P (it))
16939 {
16940 it->continuation_lines_width = 0;
16941 break;
16942 }
16943
16944 set_iterator_to_next (it, 1);
16945
16946 /* Stop if truncating at the right edge. */
16947 if (it->truncate_lines_p
16948 && it->current_x >= it->last_visible_x)
16949 {
16950 /* Add truncation mark, but don't do it if the line is
16951 truncated at a padding space. */
16952 if (IT_CHARPOS (*it) < it->string_nchars)
16953 {
16954 if (!FRAME_WINDOW_P (it->f))
16955 {
16956 int i, n;
16957
16958 if (it->current_x > it->last_visible_x)
16959 {
16960 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16961 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16962 break;
16963 for (n = row->used[TEXT_AREA]; i < n; ++i)
16964 {
16965 row->used[TEXT_AREA] = i;
16966 produce_special_glyphs (it, IT_TRUNCATION);
16967 }
16968 }
16969 produce_special_glyphs (it, IT_TRUNCATION);
16970 }
16971 it->glyph_row->truncated_on_right_p = 1;
16972 }
16973 break;
16974 }
16975 }
16976
16977 /* Maybe insert a truncation at the left. */
16978 if (it->first_visible_x
16979 && IT_CHARPOS (*it) > 0)
16980 {
16981 if (!FRAME_WINDOW_P (it->f))
16982 insert_left_trunc_glyphs (it);
16983 it->glyph_row->truncated_on_left_p = 1;
16984 }
16985
16986 it->face_id = saved_face_id;
16987
16988 /* Value is number of columns displayed. */
16989 return it->hpos - hpos_at_start;
16990 }
16991
16992
16993 \f
16994 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16995 appears as an element of LIST or as the car of an element of LIST.
16996 If PROPVAL is a list, compare each element against LIST in that
16997 way, and return 1/2 if any element of PROPVAL is found in LIST.
16998 Otherwise return 0. This function cannot quit.
16999 The return value is 2 if the text is invisible but with an ellipsis
17000 and 1 if it's invisible and without an ellipsis. */
17001
17002 int
17003 invisible_p (propval, list)
17004 register Lisp_Object propval;
17005 Lisp_Object list;
17006 {
17007 register Lisp_Object tail, proptail;
17008
17009 for (tail = list; CONSP (tail); tail = XCDR (tail))
17010 {
17011 register Lisp_Object tem;
17012 tem = XCAR (tail);
17013 if (EQ (propval, tem))
17014 return 1;
17015 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17016 return NILP (XCDR (tem)) ? 1 : 2;
17017 }
17018
17019 if (CONSP (propval))
17020 {
17021 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17022 {
17023 Lisp_Object propelt;
17024 propelt = XCAR (proptail);
17025 for (tail = list; CONSP (tail); tail = XCDR (tail))
17026 {
17027 register Lisp_Object tem;
17028 tem = XCAR (tail);
17029 if (EQ (propelt, tem))
17030 return 1;
17031 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17032 return NILP (XCDR (tem)) ? 1 : 2;
17033 }
17034 }
17035 }
17036
17037 return 0;
17038 }
17039
17040 /* Calculate a width or height in pixels from a specification using
17041 the following elements:
17042
17043 SPEC ::=
17044 NUM - a (fractional) multiple of the default font width/height
17045 (NUM) - specifies exactly NUM pixels
17046 UNIT - a fixed number of pixels, see below.
17047 ELEMENT - size of a display element in pixels, see below.
17048 (NUM . SPEC) - equals NUM * SPEC
17049 (+ SPEC SPEC ...) - add pixel values
17050 (- SPEC SPEC ...) - subtract pixel values
17051 (- SPEC) - negate pixel value
17052
17053 NUM ::=
17054 INT or FLOAT - a number constant
17055 SYMBOL - use symbol's (buffer local) variable binding.
17056
17057 UNIT ::=
17058 in - pixels per inch *)
17059 mm - pixels per 1/1000 meter *)
17060 cm - pixels per 1/100 meter *)
17061 width - width of current font in pixels.
17062 height - height of current font in pixels.
17063
17064 *) using the ratio(s) defined in display-pixels-per-inch.
17065
17066 ELEMENT ::=
17067
17068 left-fringe - left fringe width in pixels
17069 right-fringe - right fringe width in pixels
17070
17071 left-margin - left margin width in pixels
17072 right-margin - right margin width in pixels
17073
17074 scroll-bar - scroll-bar area width in pixels
17075
17076 Examples:
17077
17078 Pixels corresponding to 5 inches:
17079 (5 . in)
17080
17081 Total width of non-text areas on left side of window (if scroll-bar is on left):
17082 '(space :width (+ left-fringe left-margin scroll-bar))
17083
17084 Align to first text column (in header line):
17085 '(space :align-to 0)
17086
17087 Align to middle of text area minus half the width of variable `my-image'
17088 containing a loaded image:
17089 '(space :align-to (0.5 . (- text my-image)))
17090
17091 Width of left margin minus width of 1 character in the default font:
17092 '(space :width (- left-margin 1))
17093
17094 Width of left margin minus width of 2 characters in the current font:
17095 '(space :width (- left-margin (2 . width)))
17096
17097 Center 1 character over left-margin (in header line):
17098 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17099
17100 Different ways to express width of left fringe plus left margin minus one pixel:
17101 '(space :width (- (+ left-fringe left-margin) (1)))
17102 '(space :width (+ left-fringe left-margin (- (1))))
17103 '(space :width (+ left-fringe left-margin (-1)))
17104
17105 */
17106
17107 #define NUMVAL(X) \
17108 ((INTEGERP (X) || FLOATP (X)) \
17109 ? XFLOATINT (X) \
17110 : - 1)
17111
17112 int
17113 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17114 double *res;
17115 struct it *it;
17116 Lisp_Object prop;
17117 void *font;
17118 int width_p, *align_to;
17119 {
17120 double pixels;
17121
17122 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17123 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17124
17125 if (NILP (prop))
17126 return OK_PIXELS (0);
17127
17128 if (SYMBOLP (prop))
17129 {
17130 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17131 {
17132 char *unit = SDATA (SYMBOL_NAME (prop));
17133
17134 if (unit[0] == 'i' && unit[1] == 'n')
17135 pixels = 1.0;
17136 else if (unit[0] == 'm' && unit[1] == 'm')
17137 pixels = 25.4;
17138 else if (unit[0] == 'c' && unit[1] == 'm')
17139 pixels = 2.54;
17140 else
17141 pixels = 0;
17142 if (pixels > 0)
17143 {
17144 double ppi;
17145 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17146 || (CONSP (Vdisplay_pixels_per_inch)
17147 && (ppi = (width_p
17148 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17149 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17150 ppi > 0)))
17151 return OK_PIXELS (ppi / pixels);
17152
17153 return 0;
17154 }
17155 }
17156
17157 #ifdef HAVE_WINDOW_SYSTEM
17158 if (EQ (prop, Qheight))
17159 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17160 if (EQ (prop, Qwidth))
17161 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17162 #else
17163 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17164 return OK_PIXELS (1);
17165 #endif
17166
17167 if (EQ (prop, Qtext))
17168 return OK_PIXELS (width_p
17169 ? window_box_width (it->w, TEXT_AREA)
17170 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17171
17172 if (align_to && *align_to < 0)
17173 {
17174 *res = 0;
17175 if (EQ (prop, Qleft))
17176 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17177 if (EQ (prop, Qright))
17178 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17179 if (EQ (prop, Qcenter))
17180 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17181 + window_box_width (it->w, TEXT_AREA) / 2);
17182 if (EQ (prop, Qleft_fringe))
17183 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17184 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17185 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17186 if (EQ (prop, Qright_fringe))
17187 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17188 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17189 : window_box_right_offset (it->w, TEXT_AREA));
17190 if (EQ (prop, Qleft_margin))
17191 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17192 if (EQ (prop, Qright_margin))
17193 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17194 if (EQ (prop, Qscroll_bar))
17195 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17196 ? 0
17197 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17198 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17199 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17200 : 0)));
17201 }
17202 else
17203 {
17204 if (EQ (prop, Qleft_fringe))
17205 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17206 if (EQ (prop, Qright_fringe))
17207 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17208 if (EQ (prop, Qleft_margin))
17209 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17210 if (EQ (prop, Qright_margin))
17211 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17212 if (EQ (prop, Qscroll_bar))
17213 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17214 }
17215
17216 prop = Fbuffer_local_value (prop, it->w->buffer);
17217 }
17218
17219 if (INTEGERP (prop) || FLOATP (prop))
17220 {
17221 int base_unit = (width_p
17222 ? FRAME_COLUMN_WIDTH (it->f)
17223 : FRAME_LINE_HEIGHT (it->f));
17224 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17225 }
17226
17227 if (CONSP (prop))
17228 {
17229 Lisp_Object car = XCAR (prop);
17230 Lisp_Object cdr = XCDR (prop);
17231
17232 if (SYMBOLP (car))
17233 {
17234 #ifdef HAVE_WINDOW_SYSTEM
17235 if (valid_image_p (prop))
17236 {
17237 int id = lookup_image (it->f, prop);
17238 struct image *img = IMAGE_FROM_ID (it->f, id);
17239
17240 return OK_PIXELS (width_p ? img->width : img->height);
17241 }
17242 #endif
17243 if (EQ (car, Qplus) || EQ (car, Qminus))
17244 {
17245 int first = 1;
17246 double px;
17247
17248 pixels = 0;
17249 while (CONSP (cdr))
17250 {
17251 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17252 font, width_p, align_to))
17253 return 0;
17254 if (first)
17255 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17256 else
17257 pixels += px;
17258 cdr = XCDR (cdr);
17259 }
17260 if (EQ (car, Qminus))
17261 pixels = -pixels;
17262 return OK_PIXELS (pixels);
17263 }
17264
17265 car = Fbuffer_local_value (car, it->w->buffer);
17266 }
17267
17268 if (INTEGERP (car) || FLOATP (car))
17269 {
17270 double fact;
17271 pixels = XFLOATINT (car);
17272 if (NILP (cdr))
17273 return OK_PIXELS (pixels);
17274 if (calc_pixel_width_or_height (&fact, it, cdr,
17275 font, width_p, align_to))
17276 return OK_PIXELS (pixels * fact);
17277 return 0;
17278 }
17279
17280 return 0;
17281 }
17282
17283 return 0;
17284 }
17285
17286 \f
17287 /***********************************************************************
17288 Glyph Display
17289 ***********************************************************************/
17290
17291 #ifdef HAVE_WINDOW_SYSTEM
17292
17293 #if GLYPH_DEBUG
17294
17295 void
17296 dump_glyph_string (s)
17297 struct glyph_string *s;
17298 {
17299 fprintf (stderr, "glyph string\n");
17300 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17301 s->x, s->y, s->width, s->height);
17302 fprintf (stderr, " ybase = %d\n", s->ybase);
17303 fprintf (stderr, " hl = %d\n", s->hl);
17304 fprintf (stderr, " left overhang = %d, right = %d\n",
17305 s->left_overhang, s->right_overhang);
17306 fprintf (stderr, " nchars = %d\n", s->nchars);
17307 fprintf (stderr, " extends to end of line = %d\n",
17308 s->extends_to_end_of_line_p);
17309 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17310 fprintf (stderr, " bg width = %d\n", s->background_width);
17311 }
17312
17313 #endif /* GLYPH_DEBUG */
17314
17315 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17316 of XChar2b structures for S; it can't be allocated in
17317 init_glyph_string because it must be allocated via `alloca'. W
17318 is the window on which S is drawn. ROW and AREA are the glyph row
17319 and area within the row from which S is constructed. START is the
17320 index of the first glyph structure covered by S. HL is a
17321 face-override for drawing S. */
17322
17323 #ifdef HAVE_NTGUI
17324 #define OPTIONAL_HDC(hdc) hdc,
17325 #define DECLARE_HDC(hdc) HDC hdc;
17326 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17327 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17328 #endif
17329
17330 #ifndef OPTIONAL_HDC
17331 #define OPTIONAL_HDC(hdc)
17332 #define DECLARE_HDC(hdc)
17333 #define ALLOCATE_HDC(hdc, f)
17334 #define RELEASE_HDC(hdc, f)
17335 #endif
17336
17337 static void
17338 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17339 struct glyph_string *s;
17340 DECLARE_HDC (hdc)
17341 XChar2b *char2b;
17342 struct window *w;
17343 struct glyph_row *row;
17344 enum glyph_row_area area;
17345 int start;
17346 enum draw_glyphs_face hl;
17347 {
17348 bzero (s, sizeof *s);
17349 s->w = w;
17350 s->f = XFRAME (w->frame);
17351 #ifdef HAVE_NTGUI
17352 s->hdc = hdc;
17353 #endif
17354 s->display = FRAME_X_DISPLAY (s->f);
17355 s->window = FRAME_X_WINDOW (s->f);
17356 s->char2b = char2b;
17357 s->hl = hl;
17358 s->row = row;
17359 s->area = area;
17360 s->first_glyph = row->glyphs[area] + start;
17361 s->height = row->height;
17362 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17363
17364 /* Display the internal border below the tool-bar window. */
17365 if (s->w == XWINDOW (s->f->tool_bar_window))
17366 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17367
17368 s->ybase = s->y + row->ascent;
17369 }
17370
17371
17372 /* Append the list of glyph strings with head H and tail T to the list
17373 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17374
17375 static INLINE void
17376 append_glyph_string_lists (head, tail, h, t)
17377 struct glyph_string **head, **tail;
17378 struct glyph_string *h, *t;
17379 {
17380 if (h)
17381 {
17382 if (*head)
17383 (*tail)->next = h;
17384 else
17385 *head = h;
17386 h->prev = *tail;
17387 *tail = t;
17388 }
17389 }
17390
17391
17392 /* Prepend the list of glyph strings with head H and tail T to the
17393 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17394 result. */
17395
17396 static INLINE void
17397 prepend_glyph_string_lists (head, tail, h, t)
17398 struct glyph_string **head, **tail;
17399 struct glyph_string *h, *t;
17400 {
17401 if (h)
17402 {
17403 if (*head)
17404 (*head)->prev = t;
17405 else
17406 *tail = t;
17407 t->next = *head;
17408 *head = h;
17409 }
17410 }
17411
17412
17413 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17414 Set *HEAD and *TAIL to the resulting list. */
17415
17416 static INLINE void
17417 append_glyph_string (head, tail, s)
17418 struct glyph_string **head, **tail;
17419 struct glyph_string *s;
17420 {
17421 s->next = s->prev = NULL;
17422 append_glyph_string_lists (head, tail, s, s);
17423 }
17424
17425
17426 /* Get face and two-byte form of character glyph GLYPH on frame F.
17427 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17428 a pointer to a realized face that is ready for display. */
17429
17430 static INLINE struct face *
17431 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17432 struct frame *f;
17433 struct glyph *glyph;
17434 XChar2b *char2b;
17435 int *two_byte_p;
17436 {
17437 struct face *face;
17438
17439 xassert (glyph->type == CHAR_GLYPH);
17440 face = FACE_FROM_ID (f, glyph->face_id);
17441
17442 if (two_byte_p)
17443 *two_byte_p = 0;
17444
17445 if (!glyph->multibyte_p)
17446 {
17447 /* Unibyte case. We don't have to encode, but we have to make
17448 sure to use a face suitable for unibyte. */
17449 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17450 }
17451 else if (glyph->u.ch < 128
17452 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17453 {
17454 /* Case of ASCII in a face known to fit ASCII. */
17455 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17456 }
17457 else
17458 {
17459 struct font_info *font_info
17460 = FONT_INFO_FROM_ID (f, face->font_info_id);
17461 if (font_info)
17462 {
17463 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
17464 unsigned code = ENCODE_CHAR (charset, glyph->u.ch);
17465
17466 if (CHARSET_DIMENSION (charset) == 1)
17467 STORE_XCHAR2B (char2b, 0, code);
17468 else
17469 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
17470
17471 /* Maybe encode the character in *CHAR2B. */
17472 if (CHARSET_ID (charset) != charset_ascii)
17473 {
17474 glyph->font_type
17475 = rif->encode_char (glyph->u.ch, char2b, font_info, charset,
17476 two_byte_p);
17477 }
17478 }
17479 }
17480
17481 /* Make sure X resources of the face are allocated. */
17482 xassert (face != NULL);
17483 PREPARE_FACE_FOR_DISPLAY (f, face);
17484 return face;
17485 }
17486
17487
17488 /* Fill glyph string S with composition components specified by S->cmp.
17489
17490 FACES is an array of faces for all components of this composition.
17491 S->gidx is the index of the first component for S.
17492 OVERLAPS_P non-zero means S should draw the foreground only, and
17493 use its physical height for clipping.
17494
17495 Value is the index of a component not in S. */
17496
17497 static int
17498 fill_composite_glyph_string (s, faces, overlaps_p)
17499 struct glyph_string *s;
17500 struct face **faces;
17501 int overlaps_p;
17502 {
17503 int i;
17504
17505 xassert (s);
17506
17507 s->for_overlaps_p = overlaps_p;
17508
17509 s->face = faces[s->gidx];
17510 s->font = s->face->font;
17511 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17512
17513 /* For all glyphs of this composition, starting at the offset
17514 S->gidx, until we reach the end of the definition or encounter a
17515 glyph that requires the different face, add it to S. */
17516 ++s->nchars;
17517 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17518 ++s->nchars;
17519
17520 /* All glyph strings for the same composition has the same width,
17521 i.e. the width set for the first component of the composition. */
17522
17523 s->width = s->first_glyph->pixel_width;
17524
17525 /* If the specified font could not be loaded, use the frame's
17526 default font, but record the fact that we couldn't load it in
17527 the glyph string so that we can draw rectangles for the
17528 characters of the glyph string. */
17529 if (s->font == NULL)
17530 {
17531 s->font_not_found_p = 1;
17532 s->font = FRAME_FONT (s->f);
17533 }
17534
17535 /* Adjust base line for subscript/superscript text. */
17536 s->ybase += s->first_glyph->voffset;
17537
17538 xassert (s->face && s->face->gc);
17539
17540 /* This glyph string must always be drawn with 16-bit functions. */
17541 s->two_byte_p = 1;
17542
17543 return s->gidx + s->nchars;
17544 }
17545
17546
17547 /* Fill glyph string S from a sequence of character glyphs.
17548
17549 FACE_ID is the face id of the string. START is the index of the
17550 first glyph to consider, END is the index of the last + 1.
17551 OVERLAPS_P non-zero means S should draw the foreground only, and
17552 use its physical height for clipping.
17553
17554 Value is the index of the first glyph not in S. */
17555
17556 static int
17557 fill_glyph_string (s, face_id, start, end, overlaps_p)
17558 struct glyph_string *s;
17559 int face_id;
17560 int start, end, overlaps_p;
17561 {
17562 struct glyph *glyph, *last;
17563 int voffset;
17564 int glyph_not_available_p;
17565
17566 xassert (s->f == XFRAME (s->w->frame));
17567 xassert (s->nchars == 0);
17568 xassert (start >= 0 && end > start);
17569
17570 s->for_overlaps_p = overlaps_p,
17571 glyph = s->row->glyphs[s->area] + start;
17572 last = s->row->glyphs[s->area] + end;
17573 voffset = glyph->voffset;
17574
17575 glyph_not_available_p = glyph->glyph_not_available_p;
17576
17577 while (glyph < last
17578 && glyph->type == CHAR_GLYPH
17579 && glyph->voffset == voffset
17580 /* Same face id implies same font, nowadays. */
17581 && glyph->face_id == face_id
17582 && glyph->glyph_not_available_p == glyph_not_available_p)
17583 {
17584 int two_byte_p;
17585
17586 s->face = get_glyph_face_and_encoding (s->f, glyph,
17587 s->char2b + s->nchars,
17588 &two_byte_p);
17589 s->two_byte_p = two_byte_p;
17590 ++s->nchars;
17591 xassert (s->nchars <= end - start);
17592 s->width += glyph->pixel_width;
17593 ++glyph;
17594 }
17595
17596 s->font = s->face->font;
17597 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17598
17599 /* If the specified font could not be loaded, use the frame's font,
17600 but record the fact that we couldn't load it in
17601 S->font_not_found_p so that we can draw rectangles for the
17602 characters of the glyph string. */
17603 if (s->font == NULL || glyph_not_available_p)
17604 {
17605 s->font_not_found_p = 1;
17606 s->font = FRAME_FONT (s->f);
17607 }
17608
17609 /* Adjust base line for subscript/superscript text. */
17610 s->ybase += voffset;
17611
17612 xassert (s->face && s->face->gc);
17613 return glyph - s->row->glyphs[s->area];
17614 }
17615
17616
17617 /* Fill glyph string S from image glyph S->first_glyph. */
17618
17619 static void
17620 fill_image_glyph_string (s)
17621 struct glyph_string *s;
17622 {
17623 xassert (s->first_glyph->type == IMAGE_GLYPH);
17624 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17625 xassert (s->img);
17626 s->slice = s->first_glyph->slice;
17627 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17628 s->font = s->face->font;
17629 s->width = s->first_glyph->pixel_width;
17630
17631 /* Adjust base line for subscript/superscript text. */
17632 s->ybase += s->first_glyph->voffset;
17633 }
17634
17635
17636 /* Fill glyph string S from a sequence of stretch glyphs.
17637
17638 ROW is the glyph row in which the glyphs are found, AREA is the
17639 area within the row. START is the index of the first glyph to
17640 consider, END is the index of the last + 1.
17641
17642 Value is the index of the first glyph not in S. */
17643
17644 static int
17645 fill_stretch_glyph_string (s, row, area, start, end)
17646 struct glyph_string *s;
17647 struct glyph_row *row;
17648 enum glyph_row_area area;
17649 int start, end;
17650 {
17651 struct glyph *glyph, *last;
17652 int voffset, face_id;
17653
17654 xassert (s->first_glyph->type == STRETCH_GLYPH);
17655
17656 glyph = s->row->glyphs[s->area] + start;
17657 last = s->row->glyphs[s->area] + end;
17658 face_id = glyph->face_id;
17659 s->face = FACE_FROM_ID (s->f, face_id);
17660 s->font = s->face->font;
17661 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17662 s->width = glyph->pixel_width;
17663 voffset = glyph->voffset;
17664
17665 for (++glyph;
17666 (glyph < last
17667 && glyph->type == STRETCH_GLYPH
17668 && glyph->voffset == voffset
17669 && glyph->face_id == face_id);
17670 ++glyph)
17671 s->width += glyph->pixel_width;
17672
17673 /* Adjust base line for subscript/superscript text. */
17674 s->ybase += voffset;
17675
17676 /* The case that face->gc == 0 is handled when drawing the glyph
17677 string by calling PREPARE_FACE_FOR_DISPLAY. */
17678 xassert (s->face);
17679 return glyph - s->row->glyphs[s->area];
17680 }
17681
17682
17683 /* EXPORT for RIF:
17684 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17685 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17686 assumed to be zero. */
17687
17688 void
17689 x_get_glyph_overhangs (glyph, f, left, right)
17690 struct glyph *glyph;
17691 struct frame *f;
17692 int *left, *right;
17693 {
17694 *left = *right = 0;
17695
17696 if (glyph->type == CHAR_GLYPH)
17697 {
17698 XFontStruct *font;
17699 struct face *face;
17700 struct font_info *font_info;
17701 XChar2b char2b;
17702 XCharStruct *pcm;
17703
17704 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17705 font = face->font;
17706 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17707 if (font /* ++KFS: Should this be font_info ? */
17708 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17709 {
17710 if (pcm->rbearing > pcm->width)
17711 *right = pcm->rbearing - pcm->width;
17712 if (pcm->lbearing < 0)
17713 *left = -pcm->lbearing;
17714 }
17715 }
17716 else if (glyph->type == COMPOSITE_GLYPH)
17717 {
17718 struct composition *cmp = composition_table[glyph->u.cmp_id];
17719
17720 *right = cmp->rbearing - cmp->pixel_width;
17721 *left = - cmp->lbearing;
17722 }
17723 }
17724
17725
17726 /* Return the index of the first glyph preceding glyph string S that
17727 is overwritten by S because of S's left overhang. Value is -1
17728 if no glyphs are overwritten. */
17729
17730 static int
17731 left_overwritten (s)
17732 struct glyph_string *s;
17733 {
17734 int k;
17735
17736 if (s->left_overhang)
17737 {
17738 int x = 0, i;
17739 struct glyph *glyphs = s->row->glyphs[s->area];
17740 int first = s->first_glyph - glyphs;
17741
17742 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17743 x -= glyphs[i].pixel_width;
17744
17745 k = i + 1;
17746 }
17747 else
17748 k = -1;
17749
17750 return k;
17751 }
17752
17753
17754 /* Return the index of the first glyph preceding glyph string S that
17755 is overwriting S because of its right overhang. Value is -1 if no
17756 glyph in front of S overwrites S. */
17757
17758 static int
17759 left_overwriting (s)
17760 struct glyph_string *s;
17761 {
17762 int i, k, x;
17763 struct glyph *glyphs = s->row->glyphs[s->area];
17764 int first = s->first_glyph - glyphs;
17765
17766 k = -1;
17767 x = 0;
17768 for (i = first - 1; i >= 0; --i)
17769 {
17770 int left, right;
17771 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17772 if (x + right > 0)
17773 k = i;
17774 x -= glyphs[i].pixel_width;
17775 }
17776
17777 return k;
17778 }
17779
17780
17781 /* Return the index of the last glyph following glyph string S that is
17782 not overwritten by S because of S's right overhang. Value is -1 if
17783 no such glyph is found. */
17784
17785 static int
17786 right_overwritten (s)
17787 struct glyph_string *s;
17788 {
17789 int k = -1;
17790
17791 if (s->right_overhang)
17792 {
17793 int x = 0, i;
17794 struct glyph *glyphs = s->row->glyphs[s->area];
17795 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17796 int end = s->row->used[s->area];
17797
17798 for (i = first; i < end && s->right_overhang > x; ++i)
17799 x += glyphs[i].pixel_width;
17800
17801 k = i;
17802 }
17803
17804 return k;
17805 }
17806
17807
17808 /* Return the index of the last glyph following glyph string S that
17809 overwrites S because of its left overhang. Value is negative
17810 if no such glyph is found. */
17811
17812 static int
17813 right_overwriting (s)
17814 struct glyph_string *s;
17815 {
17816 int i, k, x;
17817 int end = s->row->used[s->area];
17818 struct glyph *glyphs = s->row->glyphs[s->area];
17819 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17820
17821 k = -1;
17822 x = 0;
17823 for (i = first; i < end; ++i)
17824 {
17825 int left, right;
17826 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17827 if (x - left < 0)
17828 k = i;
17829 x += glyphs[i].pixel_width;
17830 }
17831
17832 return k;
17833 }
17834
17835
17836 /* Get face and two-byte form of character C in face FACE_ID on frame
17837 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17838 means we want to display multibyte text. DISPLAY_P non-zero means
17839 make sure that X resources for the face returned are allocated.
17840 Value is a pointer to a realized face that is ready for display if
17841 DISPLAY_P is non-zero. */
17842
17843 static INLINE struct face *
17844 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17845 struct frame *f;
17846 int c, face_id;
17847 XChar2b *char2b;
17848 int multibyte_p, display_p;
17849 {
17850 struct face *face = FACE_FROM_ID (f, face_id);
17851
17852 if (!multibyte_p)
17853 {
17854 /* Unibyte case. We don't have to encode, but we have to make
17855 sure to use a face suitable for unibyte. */
17856 STORE_XCHAR2B (char2b, 0, c);
17857 face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
17858 face = FACE_FROM_ID (f, face_id);
17859 }
17860 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17861 {
17862 /* Case of ASCII in a face known to fit ASCII. */
17863 STORE_XCHAR2B (char2b, 0, c);
17864 }
17865 else if (face->font != NULL)
17866 {
17867 struct font_info *font_info
17868 = FONT_INFO_FROM_ID (f, face->font_info_id);
17869 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
17870 unsigned code = ENCODE_CHAR (charset, c);
17871
17872 if (CHARSET_DIMENSION (charset) == 1)
17873 STORE_XCHAR2B (char2b, 0, code);
17874 else
17875 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
17876 /* Maybe encode the character in *CHAR2B. */
17877 rif->encode_char (c, char2b, font_info, charset, NULL);
17878 }
17879
17880 /* Make sure X resources of the face are allocated. */
17881 #ifdef HAVE_X_WINDOWS
17882 if (display_p)
17883 #endif
17884 {
17885 xassert (face != NULL);
17886 PREPARE_FACE_FOR_DISPLAY (f, face);
17887 }
17888
17889 return face;
17890 }
17891
17892
17893 /* Set background width of glyph string S. START is the index of the
17894 first glyph following S. LAST_X is the right-most x-position + 1
17895 in the drawing area. */
17896
17897 static INLINE void
17898 set_glyph_string_background_width (s, start, last_x)
17899 struct glyph_string *s;
17900 int start;
17901 int last_x;
17902 {
17903 /* If the face of this glyph string has to be drawn to the end of
17904 the drawing area, set S->extends_to_end_of_line_p. */
17905 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17906
17907 if (start == s->row->used[s->area]
17908 && s->area == TEXT_AREA
17909 && ((s->hl == DRAW_NORMAL_TEXT
17910 && (s->row->fill_line_p
17911 || s->face->background != default_face->background
17912 || s->face->stipple != default_face->stipple
17913 || s->row->mouse_face_p))
17914 || s->hl == DRAW_MOUSE_FACE
17915 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17916 && s->row->fill_line_p)))
17917 s->extends_to_end_of_line_p = 1;
17918
17919 /* If S extends its face to the end of the line, set its
17920 background_width to the distance to the right edge of the drawing
17921 area. */
17922 if (s->extends_to_end_of_line_p)
17923 s->background_width = last_x - s->x + 1;
17924 else
17925 s->background_width = s->width;
17926 }
17927
17928
17929 /* Compute overhangs and x-positions for glyph string S and its
17930 predecessors, or successors. X is the starting x-position for S.
17931 BACKWARD_P non-zero means process predecessors. */
17932
17933 static void
17934 compute_overhangs_and_x (s, x, backward_p)
17935 struct glyph_string *s;
17936 int x;
17937 int backward_p;
17938 {
17939 if (backward_p)
17940 {
17941 while (s)
17942 {
17943 if (rif->compute_glyph_string_overhangs)
17944 rif->compute_glyph_string_overhangs (s);
17945 x -= s->width;
17946 s->x = x;
17947 s = s->prev;
17948 }
17949 }
17950 else
17951 {
17952 while (s)
17953 {
17954 if (rif->compute_glyph_string_overhangs)
17955 rif->compute_glyph_string_overhangs (s);
17956 s->x = x;
17957 x += s->width;
17958 s = s->next;
17959 }
17960 }
17961 }
17962
17963
17964
17965 /* The following macros are only called from draw_glyphs below.
17966 They reference the following parameters of that function directly:
17967 `w', `row', `area', and `overlap_p'
17968 as well as the following local variables:
17969 `s', `f', and `hdc' (in W32) */
17970
17971 #ifdef HAVE_NTGUI
17972 /* On W32, silently add local `hdc' variable to argument list of
17973 init_glyph_string. */
17974 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17975 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17976 #else
17977 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17978 init_glyph_string (s, char2b, w, row, area, start, hl)
17979 #endif
17980
17981 /* Add a glyph string for a stretch glyph to the list of strings
17982 between HEAD and TAIL. START is the index of the stretch glyph in
17983 row area AREA of glyph row ROW. END is the index of the last glyph
17984 in that glyph row area. X is the current output position assigned
17985 to the new glyph string constructed. HL overrides that face of the
17986 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17987 is the right-most x-position of the drawing area. */
17988
17989 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17990 and below -- keep them on one line. */
17991 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17992 do \
17993 { \
17994 s = (struct glyph_string *) alloca (sizeof *s); \
17995 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17996 START = fill_stretch_glyph_string (s, row, area, START, END); \
17997 append_glyph_string (&HEAD, &TAIL, s); \
17998 s->x = (X); \
17999 } \
18000 while (0)
18001
18002
18003 /* Add a glyph string for an image glyph to the list of strings
18004 between HEAD and TAIL. START is the index of the image glyph in
18005 row area AREA of glyph row ROW. END is the index of the last glyph
18006 in that glyph row area. X is the current output position assigned
18007 to the new glyph string constructed. HL overrides that face of the
18008 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18009 is the right-most x-position of the drawing area. */
18010
18011 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18012 do \
18013 { \
18014 s = (struct glyph_string *) alloca (sizeof *s); \
18015 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18016 fill_image_glyph_string (s); \
18017 append_glyph_string (&HEAD, &TAIL, s); \
18018 ++START; \
18019 s->x = (X); \
18020 } \
18021 while (0)
18022
18023
18024 /* Add a glyph string for a sequence of character glyphs to the list
18025 of strings between HEAD and TAIL. START is the index of the first
18026 glyph in row area AREA of glyph row ROW that is part of the new
18027 glyph string. END is the index of the last glyph in that glyph row
18028 area. X is the current output position assigned to the new glyph
18029 string constructed. HL overrides that face of the glyph; e.g. it
18030 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18031 right-most x-position of the drawing area. */
18032
18033 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18034 do \
18035 { \
18036 int face_id; \
18037 XChar2b *char2b; \
18038 \
18039 face_id = (row)->glyphs[area][START].face_id; \
18040 \
18041 s = (struct glyph_string *) alloca (sizeof *s); \
18042 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18043 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18044 append_glyph_string (&HEAD, &TAIL, s); \
18045 s->x = (X); \
18046 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18047 } \
18048 while (0)
18049
18050
18051 /* Add a glyph string for a composite sequence to the list of strings
18052 between HEAD and TAIL. START is the index of the first glyph in
18053 row area AREA of glyph row ROW that is part of the new glyph
18054 string. END is the index of the last glyph in that glyph row area.
18055 X is the current output position assigned to the new glyph string
18056 constructed. HL overrides that face of the glyph; e.g. it is
18057 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18058 x-position of the drawing area. */
18059
18060 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18061 do { \
18062 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18063 int face_id = (row)->glyphs[area][START].face_id; \
18064 struct face *base_face = FACE_FROM_ID (f, face_id); \
18065 struct composition *cmp = composition_table[cmp_id]; \
18066 int glyph_len = cmp->glyph_len; \
18067 XChar2b *char2b; \
18068 struct face **faces; \
18069 struct glyph_string *first_s = NULL; \
18070 int n; \
18071 \
18072 base_face = base_face->ascii_face; \
18073 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18074 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18075 /* At first, fill in `char2b' and `faces'. */ \
18076 for (n = 0; n < glyph_len; n++) \
18077 { \
18078 int c = COMPOSITION_GLYPH (cmp, n); \
18079 int this_face_id = FACE_FOR_CHAR (f, base_face, c, -1, Qnil); \
18080 faces[n] = FACE_FROM_ID (f, this_face_id); \
18081 get_char_face_and_encoding (f, c, this_face_id, \
18082 char2b + n, 1, 1); \
18083 } \
18084 \
18085 /* Make glyph_strings for each glyph sequence that is drawable by \
18086 the same face, and append them to HEAD/TAIL. */ \
18087 for (n = 0; n < cmp->glyph_len;) \
18088 { \
18089 s = (struct glyph_string *) alloca (sizeof *s); \
18090 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18091 append_glyph_string (&(HEAD), &(TAIL), s); \
18092 s->cmp = cmp; \
18093 s->gidx = n; \
18094 s->x = (X); \
18095 \
18096 if (n == 0) \
18097 first_s = s; \
18098 \
18099 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18100 } \
18101 \
18102 ++START; \
18103 s = first_s; \
18104 } while (0)
18105
18106
18107 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18108 of AREA of glyph row ROW on window W between indices START and END.
18109 HL overrides the face for drawing glyph strings, e.g. it is
18110 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18111 x-positions of the drawing area.
18112
18113 This is an ugly monster macro construct because we must use alloca
18114 to allocate glyph strings (because draw_glyphs can be called
18115 asynchronously). */
18116
18117 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18118 do \
18119 { \
18120 HEAD = TAIL = NULL; \
18121 while (START < END) \
18122 { \
18123 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18124 switch (first_glyph->type) \
18125 { \
18126 case CHAR_GLYPH: \
18127 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18128 HL, X, LAST_X); \
18129 break; \
18130 \
18131 case COMPOSITE_GLYPH: \
18132 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18133 HL, X, LAST_X); \
18134 break; \
18135 \
18136 case STRETCH_GLYPH: \
18137 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18138 HL, X, LAST_X); \
18139 break; \
18140 \
18141 case IMAGE_GLYPH: \
18142 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18143 HL, X, LAST_X); \
18144 break; \
18145 \
18146 default: \
18147 abort (); \
18148 } \
18149 \
18150 if (s) \
18151 { \
18152 set_glyph_string_background_width (s, START, LAST_X); \
18153 (X) += s->width; \
18154 } \
18155 } \
18156 } \
18157 while (0)
18158
18159
18160 /* Draw glyphs between START and END in AREA of ROW on window W,
18161 starting at x-position X. X is relative to AREA in W. HL is a
18162 face-override with the following meaning:
18163
18164 DRAW_NORMAL_TEXT draw normally
18165 DRAW_CURSOR draw in cursor face
18166 DRAW_MOUSE_FACE draw in mouse face.
18167 DRAW_INVERSE_VIDEO draw in mode line face
18168 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18169 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18170
18171 If OVERLAPS_P is non-zero, draw only the foreground of characters
18172 and clip to the physical height of ROW.
18173
18174 Value is the x-position reached, relative to AREA of W. */
18175
18176 static int
18177 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18178 struct window *w;
18179 int x;
18180 struct glyph_row *row;
18181 enum glyph_row_area area;
18182 EMACS_INT start, end;
18183 enum draw_glyphs_face hl;
18184 int overlaps_p;
18185 {
18186 struct glyph_string *head, *tail;
18187 struct glyph_string *s;
18188 int last_x, area_width;
18189 int x_reached;
18190 int i, j;
18191 struct frame *f = XFRAME (WINDOW_FRAME (w));
18192 DECLARE_HDC (hdc);
18193
18194 ALLOCATE_HDC (hdc, f);
18195
18196 /* Let's rather be paranoid than getting a SEGV. */
18197 end = min (end, row->used[area]);
18198 start = max (0, start);
18199 start = min (end, start);
18200
18201 /* Translate X to frame coordinates. Set last_x to the right
18202 end of the drawing area. */
18203 if (row->full_width_p)
18204 {
18205 /* X is relative to the left edge of W, without scroll bars
18206 or fringes. */
18207 x += WINDOW_LEFT_EDGE_X (w);
18208 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18209 }
18210 else
18211 {
18212 int area_left = window_box_left (w, area);
18213 x += area_left;
18214 area_width = window_box_width (w, area);
18215 last_x = area_left + area_width;
18216 }
18217
18218 /* Build a doubly-linked list of glyph_string structures between
18219 head and tail from what we have to draw. Note that the macro
18220 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18221 the reason we use a separate variable `i'. */
18222 i = start;
18223 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18224 if (tail)
18225 x_reached = tail->x + tail->background_width;
18226 else
18227 x_reached = x;
18228
18229 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18230 the row, redraw some glyphs in front or following the glyph
18231 strings built above. */
18232 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18233 {
18234 int dummy_x = 0;
18235 struct glyph_string *h, *t;
18236
18237 /* Compute overhangs for all glyph strings. */
18238 if (rif->compute_glyph_string_overhangs)
18239 for (s = head; s; s = s->next)
18240 rif->compute_glyph_string_overhangs (s);
18241
18242 /* Prepend glyph strings for glyphs in front of the first glyph
18243 string that are overwritten because of the first glyph
18244 string's left overhang. The background of all strings
18245 prepended must be drawn because the first glyph string
18246 draws over it. */
18247 i = left_overwritten (head);
18248 if (i >= 0)
18249 {
18250 j = i;
18251 BUILD_GLYPH_STRINGS (j, start, h, t,
18252 DRAW_NORMAL_TEXT, dummy_x, last_x);
18253 start = i;
18254 compute_overhangs_and_x (t, head->x, 1);
18255 prepend_glyph_string_lists (&head, &tail, h, t);
18256 }
18257
18258 /* Prepend glyph strings for glyphs in front of the first glyph
18259 string that overwrite that glyph string because of their
18260 right overhang. For these strings, only the foreground must
18261 be drawn, because it draws over the glyph string at `head'.
18262 The background must not be drawn because this would overwrite
18263 right overhangs of preceding glyphs for which no glyph
18264 strings exist. */
18265 i = left_overwriting (head);
18266 if (i >= 0)
18267 {
18268 BUILD_GLYPH_STRINGS (i, start, h, t,
18269 DRAW_NORMAL_TEXT, dummy_x, last_x);
18270 for (s = h; s; s = s->next)
18271 s->background_filled_p = 1;
18272 compute_overhangs_and_x (t, head->x, 1);
18273 prepend_glyph_string_lists (&head, &tail, h, t);
18274 }
18275
18276 /* Append glyphs strings for glyphs following the last glyph
18277 string tail that are overwritten by tail. The background of
18278 these strings has to be drawn because tail's foreground draws
18279 over it. */
18280 i = right_overwritten (tail);
18281 if (i >= 0)
18282 {
18283 BUILD_GLYPH_STRINGS (end, i, h, t,
18284 DRAW_NORMAL_TEXT, x, last_x);
18285 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18286 append_glyph_string_lists (&head, &tail, h, t);
18287 }
18288
18289 /* Append glyph strings for glyphs following the last glyph
18290 string tail that overwrite tail. The foreground of such
18291 glyphs has to be drawn because it writes into the background
18292 of tail. The background must not be drawn because it could
18293 paint over the foreground of following glyphs. */
18294 i = right_overwriting (tail);
18295 if (i >= 0)
18296 {
18297 BUILD_GLYPH_STRINGS (end, i, h, t,
18298 DRAW_NORMAL_TEXT, x, last_x);
18299 for (s = h; s; s = s->next)
18300 s->background_filled_p = 1;
18301 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18302 append_glyph_string_lists (&head, &tail, h, t);
18303 }
18304 }
18305
18306 /* Draw all strings. */
18307 for (s = head; s; s = s->next)
18308 rif->draw_glyph_string (s);
18309
18310 if (area == TEXT_AREA
18311 && !row->full_width_p
18312 /* When drawing overlapping rows, only the glyph strings'
18313 foreground is drawn, which doesn't erase a cursor
18314 completely. */
18315 && !overlaps_p)
18316 {
18317 int x0 = head ? head->x : x;
18318 int x1 = tail ? tail->x + tail->background_width : x;
18319
18320 int text_left = window_box_left (w, TEXT_AREA);
18321 x0 -= text_left;
18322 x1 -= text_left;
18323
18324 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18325 row->y, MATRIX_ROW_BOTTOM_Y (row));
18326 }
18327
18328 /* Value is the x-position up to which drawn, relative to AREA of W.
18329 This doesn't include parts drawn because of overhangs. */
18330 if (row->full_width_p)
18331 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18332 else
18333 x_reached -= window_box_left (w, area);
18334
18335 RELEASE_HDC (hdc, f);
18336
18337 return x_reached;
18338 }
18339
18340
18341 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18342 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18343
18344 static INLINE void
18345 append_glyph (it)
18346 struct it *it;
18347 {
18348 struct glyph *glyph;
18349 enum glyph_row_area area = it->area;
18350
18351 xassert (it->glyph_row);
18352 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18353
18354 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18355 if (glyph < it->glyph_row->glyphs[area + 1])
18356 {
18357 glyph->charpos = CHARPOS (it->position);
18358 glyph->object = it->object;
18359 glyph->pixel_width = it->pixel_width;
18360 glyph->ascent = it->ascent;
18361 glyph->descent = it->descent;
18362 glyph->voffset = it->voffset;
18363 glyph->type = CHAR_GLYPH;
18364 glyph->multibyte_p = it->multibyte_p;
18365 glyph->left_box_line_p = it->start_of_box_run_p;
18366 glyph->right_box_line_p = it->end_of_box_run_p;
18367 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18368 || it->phys_descent > it->descent);
18369 glyph->padding_p = 0;
18370 glyph->glyph_not_available_p = it->glyph_not_available_p;
18371 glyph->face_id = it->face_id;
18372 glyph->u.ch = it->char_to_display;
18373 glyph->slice = null_glyph_slice;
18374 glyph->font_type = FONT_TYPE_UNKNOWN;
18375 ++it->glyph_row->used[area];
18376 }
18377 else if (!fonts_changed_p)
18378 {
18379 it->w->ncols_scale_factor++;
18380 fonts_changed_p = 1;
18381 }
18382 }
18383
18384 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18385 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18386
18387 static INLINE void
18388 append_composite_glyph (it)
18389 struct it *it;
18390 {
18391 struct glyph *glyph;
18392 enum glyph_row_area area = it->area;
18393
18394 xassert (it->glyph_row);
18395
18396 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18397 if (glyph < it->glyph_row->glyphs[area + 1])
18398 {
18399 glyph->charpos = CHARPOS (it->position);
18400 glyph->object = it->object;
18401 glyph->pixel_width = it->pixel_width;
18402 glyph->ascent = it->ascent;
18403 glyph->descent = it->descent;
18404 glyph->voffset = it->voffset;
18405 glyph->type = COMPOSITE_GLYPH;
18406 glyph->multibyte_p = it->multibyte_p;
18407 glyph->left_box_line_p = it->start_of_box_run_p;
18408 glyph->right_box_line_p = it->end_of_box_run_p;
18409 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18410 || it->phys_descent > it->descent);
18411 glyph->padding_p = 0;
18412 glyph->glyph_not_available_p = 0;
18413 glyph->face_id = it->face_id;
18414 glyph->u.cmp_id = it->cmp_id;
18415 glyph->slice = null_glyph_slice;
18416 glyph->font_type = FONT_TYPE_UNKNOWN;
18417 ++it->glyph_row->used[area];
18418 }
18419 else if (!fonts_changed_p)
18420 {
18421 it->w->ncols_scale_factor++;
18422 fonts_changed_p = 1;
18423 }
18424 }
18425
18426
18427 /* Change IT->ascent and IT->height according to the setting of
18428 IT->voffset. */
18429
18430 static INLINE void
18431 take_vertical_position_into_account (it)
18432 struct it *it;
18433 {
18434 if (it->voffset)
18435 {
18436 if (it->voffset < 0)
18437 /* Increase the ascent so that we can display the text higher
18438 in the line. */
18439 it->ascent -= it->voffset;
18440 else
18441 /* Increase the descent so that we can display the text lower
18442 in the line. */
18443 it->descent += it->voffset;
18444 }
18445 }
18446
18447
18448 /* Produce glyphs/get display metrics for the image IT is loaded with.
18449 See the description of struct display_iterator in dispextern.h for
18450 an overview of struct display_iterator. */
18451
18452 static void
18453 produce_image_glyph (it)
18454 struct it *it;
18455 {
18456 struct image *img;
18457 struct face *face;
18458 int face_ascent, glyph_ascent;
18459 struct glyph_slice slice;
18460
18461 xassert (it->what == IT_IMAGE);
18462
18463 face = FACE_FROM_ID (it->f, it->face_id);
18464 xassert (face);
18465 /* Make sure X resources of the face is loaded. */
18466 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18467
18468 if (it->image_id < 0)
18469 {
18470 /* Fringe bitmap. */
18471 it->ascent = it->phys_ascent = 0;
18472 it->descent = it->phys_descent = 0;
18473 it->pixel_width = 0;
18474 it->nglyphs = 0;
18475 return;
18476 }
18477
18478 img = IMAGE_FROM_ID (it->f, it->image_id);
18479 xassert (img);
18480 /* Make sure X resources of the image is loaded. */
18481 prepare_image_for_display (it->f, img);
18482
18483 slice.x = slice.y = 0;
18484 slice.width = img->width;
18485 slice.height = img->height;
18486
18487 if (INTEGERP (it->slice.x))
18488 slice.x = XINT (it->slice.x);
18489 else if (FLOATP (it->slice.x))
18490 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18491
18492 if (INTEGERP (it->slice.y))
18493 slice.y = XINT (it->slice.y);
18494 else if (FLOATP (it->slice.y))
18495 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18496
18497 if (INTEGERP (it->slice.width))
18498 slice.width = XINT (it->slice.width);
18499 else if (FLOATP (it->slice.width))
18500 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18501
18502 if (INTEGERP (it->slice.height))
18503 slice.height = XINT (it->slice.height);
18504 else if (FLOATP (it->slice.height))
18505 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18506
18507 if (slice.x >= img->width)
18508 slice.x = img->width;
18509 if (slice.y >= img->height)
18510 slice.y = img->height;
18511 if (slice.x + slice.width >= img->width)
18512 slice.width = img->width - slice.x;
18513 if (slice.y + slice.height > img->height)
18514 slice.height = img->height - slice.y;
18515
18516 if (slice.width == 0 || slice.height == 0)
18517 return;
18518
18519 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18520
18521 it->descent = slice.height - glyph_ascent;
18522 if (slice.y == 0)
18523 it->descent += img->vmargin;
18524 if (slice.y + slice.height == img->height)
18525 it->descent += img->vmargin;
18526 it->phys_descent = it->descent;
18527
18528 it->pixel_width = slice.width;
18529 if (slice.x == 0)
18530 it->pixel_width += img->hmargin;
18531 if (slice.x + slice.width == img->width)
18532 it->pixel_width += img->hmargin;
18533
18534 /* It's quite possible for images to have an ascent greater than
18535 their height, so don't get confused in that case. */
18536 if (it->descent < 0)
18537 it->descent = 0;
18538
18539 #if 0 /* this breaks image tiling */
18540 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18541 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18542 if (face_ascent > it->ascent)
18543 it->ascent = it->phys_ascent = face_ascent;
18544 #endif
18545
18546 it->nglyphs = 1;
18547
18548 if (face->box != FACE_NO_BOX)
18549 {
18550 if (face->box_line_width > 0)
18551 {
18552 if (slice.y == 0)
18553 it->ascent += face->box_line_width;
18554 if (slice.y + slice.height == img->height)
18555 it->descent += face->box_line_width;
18556 }
18557
18558 if (it->start_of_box_run_p && slice.x == 0)
18559 it->pixel_width += abs (face->box_line_width);
18560 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18561 it->pixel_width += abs (face->box_line_width);
18562 }
18563
18564 take_vertical_position_into_account (it);
18565
18566 if (it->glyph_row)
18567 {
18568 struct glyph *glyph;
18569 enum glyph_row_area area = it->area;
18570
18571 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18572 if (glyph < it->glyph_row->glyphs[area + 1])
18573 {
18574 glyph->charpos = CHARPOS (it->position);
18575 glyph->object = it->object;
18576 glyph->pixel_width = it->pixel_width;
18577 glyph->ascent = glyph_ascent;
18578 glyph->descent = it->descent;
18579 glyph->voffset = it->voffset;
18580 glyph->type = IMAGE_GLYPH;
18581 glyph->multibyte_p = it->multibyte_p;
18582 glyph->left_box_line_p = it->start_of_box_run_p;
18583 glyph->right_box_line_p = it->end_of_box_run_p;
18584 glyph->overlaps_vertically_p = 0;
18585 glyph->padding_p = 0;
18586 glyph->glyph_not_available_p = 0;
18587 glyph->face_id = it->face_id;
18588 glyph->u.img_id = img->id;
18589 glyph->slice = slice;
18590 glyph->font_type = FONT_TYPE_UNKNOWN;
18591 ++it->glyph_row->used[area];
18592 }
18593 else if (!fonts_changed_p)
18594 {
18595 it->w->ncols_scale_factor++;
18596 fonts_changed_p = 1;
18597 }
18598 }
18599 }
18600
18601
18602 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18603 of the glyph, WIDTH and HEIGHT are the width and height of the
18604 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18605
18606 static void
18607 append_stretch_glyph (it, object, width, height, ascent)
18608 struct it *it;
18609 Lisp_Object object;
18610 int width, height;
18611 int ascent;
18612 {
18613 struct glyph *glyph;
18614 enum glyph_row_area area = it->area;
18615
18616 xassert (ascent >= 0 && ascent <= height);
18617
18618 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18619 if (glyph < it->glyph_row->glyphs[area + 1])
18620 {
18621 glyph->charpos = CHARPOS (it->position);
18622 glyph->object = object;
18623 glyph->pixel_width = width;
18624 glyph->ascent = ascent;
18625 glyph->descent = height - ascent;
18626 glyph->voffset = it->voffset;
18627 glyph->type = STRETCH_GLYPH;
18628 glyph->multibyte_p = it->multibyte_p;
18629 glyph->left_box_line_p = it->start_of_box_run_p;
18630 glyph->right_box_line_p = it->end_of_box_run_p;
18631 glyph->overlaps_vertically_p = 0;
18632 glyph->padding_p = 0;
18633 glyph->glyph_not_available_p = 0;
18634 glyph->face_id = it->face_id;
18635 glyph->u.stretch.ascent = ascent;
18636 glyph->u.stretch.height = height;
18637 glyph->slice = null_glyph_slice;
18638 glyph->font_type = FONT_TYPE_UNKNOWN;
18639 ++it->glyph_row->used[area];
18640 }
18641 else if (!fonts_changed_p)
18642 {
18643 it->w->ncols_scale_factor++;
18644 fonts_changed_p = 1;
18645 }
18646 }
18647
18648
18649 /* Produce a stretch glyph for iterator IT. IT->object is the value
18650 of the glyph property displayed. The value must be a list
18651 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18652 being recognized:
18653
18654 1. `:width WIDTH' specifies that the space should be WIDTH *
18655 canonical char width wide. WIDTH may be an integer or floating
18656 point number.
18657
18658 2. `:relative-width FACTOR' specifies that the width of the stretch
18659 should be computed from the width of the first character having the
18660 `glyph' property, and should be FACTOR times that width.
18661
18662 3. `:align-to HPOS' specifies that the space should be wide enough
18663 to reach HPOS, a value in canonical character units.
18664
18665 Exactly one of the above pairs must be present.
18666
18667 4. `:height HEIGHT' specifies that the height of the stretch produced
18668 should be HEIGHT, measured in canonical character units.
18669
18670 5. `:relative-height FACTOR' specifies that the height of the
18671 stretch should be FACTOR times the height of the characters having
18672 the glyph property.
18673
18674 Either none or exactly one of 4 or 5 must be present.
18675
18676 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18677 of the stretch should be used for the ascent of the stretch.
18678 ASCENT must be in the range 0 <= ASCENT <= 100. */
18679
18680 static void
18681 produce_stretch_glyph (it)
18682 struct it *it;
18683 {
18684 /* (space :width WIDTH :height HEIGHT ...) */
18685 Lisp_Object prop, plist;
18686 int width = 0, height = 0, align_to = -1;
18687 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18688 int ascent = 0;
18689 double tem;
18690 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18691 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18692
18693 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18694
18695 /* List should start with `space'. */
18696 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18697 plist = XCDR (it->object);
18698
18699 /* Compute the width of the stretch. */
18700 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18701 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18702 {
18703 /* Absolute width `:width WIDTH' specified and valid. */
18704 zero_width_ok_p = 1;
18705 width = (int)tem;
18706 }
18707 else if (prop = Fplist_get (plist, QCrelative_width),
18708 NUMVAL (prop) > 0)
18709 {
18710 /* Relative width `:relative-width FACTOR' specified and valid.
18711 Compute the width of the characters having the `glyph'
18712 property. */
18713 struct it it2;
18714 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18715
18716 it2 = *it;
18717 if (it->multibyte_p)
18718 {
18719 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18720 - IT_BYTEPOS (*it));
18721 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18722 }
18723 else
18724 it2.c = *p, it2.len = 1;
18725
18726 it2.glyph_row = NULL;
18727 it2.what = IT_CHARACTER;
18728 x_produce_glyphs (&it2);
18729 width = NUMVAL (prop) * it2.pixel_width;
18730 }
18731 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18732 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18733 {
18734 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18735 align_to = (align_to < 0
18736 ? 0
18737 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18738 else if (align_to < 0)
18739 align_to = window_box_left_offset (it->w, TEXT_AREA);
18740 width = max (0, (int)tem + align_to - it->current_x);
18741 zero_width_ok_p = 1;
18742 }
18743 else
18744 /* Nothing specified -> width defaults to canonical char width. */
18745 width = FRAME_COLUMN_WIDTH (it->f);
18746
18747 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18748 width = 1;
18749
18750 /* Compute height. */
18751 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18752 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18753 {
18754 height = (int)tem;
18755 zero_height_ok_p = 1;
18756 }
18757 else if (prop = Fplist_get (plist, QCrelative_height),
18758 NUMVAL (prop) > 0)
18759 height = FONT_HEIGHT (font) * NUMVAL (prop);
18760 else
18761 height = FONT_HEIGHT (font);
18762
18763 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18764 height = 1;
18765
18766 /* Compute percentage of height used for ascent. If
18767 `:ascent ASCENT' is present and valid, use that. Otherwise,
18768 derive the ascent from the font in use. */
18769 if (prop = Fplist_get (plist, QCascent),
18770 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18771 ascent = height * NUMVAL (prop) / 100.0;
18772 else if (!NILP (prop)
18773 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18774 ascent = min (max (0, (int)tem), height);
18775 else
18776 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18777
18778 if (width > 0 && height > 0 && it->glyph_row)
18779 {
18780 Lisp_Object object = it->stack[it->sp - 1].string;
18781 if (!STRINGP (object))
18782 object = it->w->buffer;
18783 append_stretch_glyph (it, object, width, height, ascent);
18784 }
18785
18786 it->pixel_width = width;
18787 it->ascent = it->phys_ascent = ascent;
18788 it->descent = it->phys_descent = height - it->ascent;
18789 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18790
18791 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18792 {
18793 if (face->box_line_width > 0)
18794 {
18795 it->ascent += face->box_line_width;
18796 it->descent += face->box_line_width;
18797 }
18798
18799 if (it->start_of_box_run_p)
18800 it->pixel_width += abs (face->box_line_width);
18801 if (it->end_of_box_run_p)
18802 it->pixel_width += abs (face->box_line_width);
18803 }
18804
18805 take_vertical_position_into_account (it);
18806 }
18807
18808 /* Calculate line-height and line-spacing properties.
18809 An integer value specifies explicit pixel value.
18810 A float value specifies relative value to current face height.
18811 A cons (float . face-name) specifies relative value to
18812 height of specified face font.
18813
18814 Returns height in pixels, or nil. */
18815
18816 static Lisp_Object
18817 calc_line_height_property (it, prop, font, boff, total)
18818 struct it *it;
18819 Lisp_Object prop;
18820 XFontStruct *font;
18821 int boff, *total;
18822 {
18823 Lisp_Object position, val;
18824 Lisp_Object face_name = Qnil;
18825 int ascent, descent, height, override;
18826
18827 if (STRINGP (it->object))
18828 position = make_number (IT_STRING_CHARPOS (*it));
18829 else if (BUFFERP (it->object))
18830 position = make_number (IT_CHARPOS (*it));
18831 else
18832 return Qnil;
18833
18834 val = Fget_char_property (position, prop, it->object);
18835
18836 if (NILP (val))
18837 return val;
18838
18839 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18840 {
18841 *total = 1;
18842 val = XCDR (val);
18843 }
18844
18845 if (INTEGERP (val))
18846 return val;
18847
18848 if (CONSP (val))
18849 {
18850 face_name = XCDR (val);
18851 val = XCAR (val);
18852 }
18853 else if (SYMBOLP (val))
18854 {
18855 face_name = val;
18856 val = Qnil;
18857 }
18858
18859 override = EQ (prop, Qline_height);
18860
18861 if (NILP (face_name))
18862 {
18863 font = FRAME_FONT (it->f);
18864 boff = FRAME_BASELINE_OFFSET (it->f);
18865 }
18866 else if (EQ (face_name, Qt))
18867 {
18868 override = 0;
18869 }
18870 else
18871 {
18872 int face_id;
18873 struct face *face;
18874 struct font_info *font_info;
18875
18876 face_id = lookup_named_face (it->f, face_name);
18877 if (face_id < 0)
18878 return make_number (-1);
18879
18880 face = FACE_FROM_ID (it->f, face_id);
18881 font = face->font;
18882 if (font == NULL)
18883 return make_number (-1);
18884
18885 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18886 boff = font_info->baseline_offset;
18887 if (font_info->vertical_centering)
18888 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18889 }
18890
18891 ascent = FONT_BASE (font) + boff;
18892 descent = FONT_DESCENT (font) - boff;
18893
18894 if (override)
18895 {
18896 it->override_ascent = ascent;
18897 it->override_descent = descent;
18898 it->override_boff = boff;
18899 }
18900
18901 height = ascent + descent;
18902 if (FLOATP (val))
18903 height = (int)(XFLOAT_DATA (val) * height);
18904 else if (INTEGERP (val))
18905 height *= XINT (val);
18906
18907 return make_number (height);
18908 }
18909
18910
18911 /* RIF:
18912 Produce glyphs/get display metrics for the display element IT is
18913 loaded with. See the description of struct display_iterator in
18914 dispextern.h for an overview of struct display_iterator. */
18915
18916 void
18917 x_produce_glyphs (it)
18918 struct it *it;
18919 {
18920 int extra_line_spacing = it->extra_line_spacing;
18921
18922 it->glyph_not_available_p = 0;
18923
18924 if (it->what == IT_CHARACTER)
18925 {
18926 XChar2b char2b;
18927 XFontStruct *font;
18928 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18929 XCharStruct *pcm;
18930 int font_not_found_p;
18931 struct font_info *font_info;
18932 int boff; /* baseline offset */
18933 /* We may change it->multibyte_p upon unibyte<->multibyte
18934 conversion. So, save the current value now and restore it
18935 later.
18936
18937 Note: It seems that we don't have to record multibyte_p in
18938 struct glyph because the character code itself tells if or
18939 not the character is multibyte. Thus, in the future, we must
18940 consider eliminating the field `multibyte_p' in the struct
18941 glyph. */
18942 int saved_multibyte_p = it->multibyte_p;
18943
18944 /* Maybe translate single-byte characters to multibyte, or the
18945 other way. */
18946 it->char_to_display = it->c;
18947 if (!ASCII_BYTE_P (it->c)
18948 && ! it->multibyte_p)
18949 {
18950 if (SINGLE_BYTE_CHAR_P (it->c)
18951 && unibyte_display_via_language_environment)
18952 it->char_to_display = unibyte_char_to_multibyte (it->c);
18953 if (! SINGLE_BYTE_CHAR_P (it->c))
18954 {
18955 it->multibyte_p = 1;
18956 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
18957 -1, Qnil);
18958 face = FACE_FROM_ID (it->f, it->face_id);
18959 }
18960 }
18961
18962 /* Get font to use. Encode IT->char_to_display. */
18963 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18964 &char2b, it->multibyte_p, 0);
18965 font = face->font;
18966
18967 /* When no suitable font found, use the default font. */
18968 font_not_found_p = font == NULL;
18969 if (font_not_found_p)
18970 {
18971 font = FRAME_FONT (it->f);
18972 boff = FRAME_BASELINE_OFFSET (it->f);
18973 font_info = NULL;
18974 }
18975 else
18976 {
18977 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18978 boff = font_info->baseline_offset;
18979 if (font_info->vertical_centering)
18980 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18981 }
18982
18983 if (it->char_to_display >= ' '
18984 && (!it->multibyte_p || it->char_to_display < 128))
18985 {
18986 /* Either unibyte or ASCII. */
18987 int stretched_p;
18988
18989 it->nglyphs = 1;
18990
18991 pcm = rif->per_char_metric (font, &char2b,
18992 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18993
18994 if (it->override_ascent >= 0)
18995 {
18996 it->ascent = it->override_ascent;
18997 it->descent = it->override_descent;
18998 boff = it->override_boff;
18999 }
19000 else
19001 {
19002 it->ascent = FONT_BASE (font) + boff;
19003 it->descent = FONT_DESCENT (font) - boff;
19004 }
19005
19006 if (pcm)
19007 {
19008 it->phys_ascent = pcm->ascent + boff;
19009 it->phys_descent = pcm->descent - boff;
19010 it->pixel_width = pcm->width;
19011 }
19012 else
19013 {
19014 it->glyph_not_available_p = 1;
19015 it->phys_ascent = it->ascent;
19016 it->phys_descent = it->descent;
19017 it->pixel_width = FONT_WIDTH (font);
19018 }
19019
19020 if (it->constrain_row_ascent_descent_p)
19021 {
19022 if (it->descent > it->max_descent)
19023 {
19024 it->ascent += it->descent - it->max_descent;
19025 it->descent = it->max_descent;
19026 }
19027 if (it->ascent > it->max_ascent)
19028 {
19029 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19030 it->ascent = it->max_ascent;
19031 }
19032 it->phys_ascent = min (it->phys_ascent, it->ascent);
19033 it->phys_descent = min (it->phys_descent, it->descent);
19034 extra_line_spacing = 0;
19035 }
19036
19037 /* If this is a space inside a region of text with
19038 `space-width' property, change its width. */
19039 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19040 if (stretched_p)
19041 it->pixel_width *= XFLOATINT (it->space_width);
19042
19043 /* If face has a box, add the box thickness to the character
19044 height. If character has a box line to the left and/or
19045 right, add the box line width to the character's width. */
19046 if (face->box != FACE_NO_BOX)
19047 {
19048 int thick = face->box_line_width;
19049
19050 if (thick > 0)
19051 {
19052 it->ascent += thick;
19053 it->descent += thick;
19054 }
19055 else
19056 thick = -thick;
19057
19058 if (it->start_of_box_run_p)
19059 it->pixel_width += thick;
19060 if (it->end_of_box_run_p)
19061 it->pixel_width += thick;
19062 }
19063
19064 /* If face has an overline, add the height of the overline
19065 (1 pixel) and a 1 pixel margin to the character height. */
19066 if (face->overline_p)
19067 it->ascent += 2;
19068
19069 if (it->constrain_row_ascent_descent_p)
19070 {
19071 if (it->ascent > it->max_ascent)
19072 it->ascent = it->max_ascent;
19073 if (it->descent > it->max_descent)
19074 it->descent = it->max_descent;
19075 }
19076
19077 take_vertical_position_into_account (it);
19078
19079 /* If we have to actually produce glyphs, do it. */
19080 if (it->glyph_row)
19081 {
19082 if (stretched_p)
19083 {
19084 /* Translate a space with a `space-width' property
19085 into a stretch glyph. */
19086 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19087 / FONT_HEIGHT (font));
19088 append_stretch_glyph (it, it->object, it->pixel_width,
19089 it->ascent + it->descent, ascent);
19090 }
19091 else
19092 append_glyph (it);
19093
19094 /* If characters with lbearing or rbearing are displayed
19095 in this line, record that fact in a flag of the
19096 glyph row. This is used to optimize X output code. */
19097 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19098 it->glyph_row->contains_overlapping_glyphs_p = 1;
19099 }
19100 }
19101 else if (it->char_to_display == '\n')
19102 {
19103 /* A newline has no width but we need the height of the line.
19104 But if previous part of the line set a height, don't
19105 increase that height */
19106
19107 Lisp_Object height;
19108
19109 it->override_ascent = -1;
19110 it->pixel_width = 0;
19111 it->nglyphs = 0;
19112
19113 height = calc_line_height_property(it, Qline_height, font, boff, 0);
19114
19115 if (it->override_ascent >= 0)
19116 {
19117 it->ascent = it->override_ascent;
19118 it->descent = it->override_descent;
19119 boff = it->override_boff;
19120 }
19121 else
19122 {
19123 it->ascent = FONT_BASE (font) + boff;
19124 it->descent = FONT_DESCENT (font) - boff;
19125 }
19126
19127 if (EQ (height, make_number(0)))
19128 {
19129 if (it->descent > it->max_descent)
19130 {
19131 it->ascent += it->descent - it->max_descent;
19132 it->descent = it->max_descent;
19133 }
19134 if (it->ascent > it->max_ascent)
19135 {
19136 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19137 it->ascent = it->max_ascent;
19138 }
19139 it->phys_ascent = min (it->phys_ascent, it->ascent);
19140 it->phys_descent = min (it->phys_descent, it->descent);
19141 it->constrain_row_ascent_descent_p = 1;
19142 extra_line_spacing = 0;
19143 }
19144 else
19145 {
19146 Lisp_Object spacing;
19147 int total = 0;
19148
19149 it->phys_ascent = it->ascent;
19150 it->phys_descent = it->descent;
19151
19152 if ((it->max_ascent > 0 || it->max_descent > 0)
19153 && face->box != FACE_NO_BOX
19154 && face->box_line_width > 0)
19155 {
19156 it->ascent += face->box_line_width;
19157 it->descent += face->box_line_width;
19158 }
19159 if (!NILP (height)
19160 && XINT (height) > it->ascent + it->descent)
19161 it->ascent = XINT (height) - it->descent;
19162
19163 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
19164 if (INTEGERP (spacing))
19165 {
19166 extra_line_spacing = XINT (spacing);
19167 if (total)
19168 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19169 }
19170 }
19171 }
19172 else if (it->char_to_display == '\t')
19173 {
19174 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19175 int x = it->current_x + it->continuation_lines_width;
19176 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19177
19178 /* If the distance from the current position to the next tab
19179 stop is less than a canonical character width, use the
19180 tab stop after that. */
19181 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19182 next_tab_x += tab_width;
19183
19184 it->pixel_width = next_tab_x - x;
19185 it->nglyphs = 1;
19186 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19187 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19188
19189 if (it->glyph_row)
19190 {
19191 append_stretch_glyph (it, it->object, it->pixel_width,
19192 it->ascent + it->descent, it->ascent);
19193 }
19194 }
19195 else
19196 {
19197 /* A multi-byte character. Assume that the display width of the
19198 character is the width of the character multiplied by the
19199 width of the font. */
19200
19201 /* If we found a font, this font should give us the right
19202 metrics. If we didn't find a font, use the frame's
19203 default font and calculate the width of the character by
19204 multiplying the width of font by the width of the
19205 character. */
19206
19207 pcm = rif->per_char_metric (font, &char2b,
19208 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19209
19210 if (font_not_found_p || !pcm)
19211 {
19212 it->glyph_not_available_p = 1;
19213 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19214 * CHAR_WIDTH (it->char_to_display));
19215 it->phys_ascent = FONT_BASE (font) + boff;
19216 it->phys_descent = FONT_DESCENT (font) - boff;
19217 }
19218 else
19219 {
19220 it->pixel_width = pcm->width;
19221 it->phys_ascent = pcm->ascent + boff;
19222 it->phys_descent = pcm->descent - boff;
19223 if (it->glyph_row
19224 && (pcm->lbearing < 0
19225 || pcm->rbearing > pcm->width))
19226 it->glyph_row->contains_overlapping_glyphs_p = 1;
19227 }
19228 it->nglyphs = 1;
19229 it->ascent = FONT_BASE (font) + boff;
19230 it->descent = FONT_DESCENT (font) - boff;
19231 if (face->box != FACE_NO_BOX)
19232 {
19233 int thick = face->box_line_width;
19234
19235 if (thick > 0)
19236 {
19237 it->ascent += thick;
19238 it->descent += thick;
19239 }
19240 else
19241 thick = - thick;
19242
19243 if (it->start_of_box_run_p)
19244 it->pixel_width += thick;
19245 if (it->end_of_box_run_p)
19246 it->pixel_width += thick;
19247 }
19248
19249 /* If face has an overline, add the height of the overline
19250 (1 pixel) and a 1 pixel margin to the character height. */
19251 if (face->overline_p)
19252 it->ascent += 2;
19253
19254 take_vertical_position_into_account (it);
19255
19256 if (it->glyph_row)
19257 append_glyph (it);
19258 }
19259 it->multibyte_p = saved_multibyte_p;
19260 }
19261 else if (it->what == IT_COMPOSITION)
19262 {
19263 /* Note: A composition is represented as one glyph in the
19264 glyph matrix. There are no padding glyphs. */
19265 XChar2b char2b;
19266 XFontStruct *font;
19267 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19268 XCharStruct *pcm;
19269 int font_not_found_p;
19270 struct font_info *font_info;
19271 int boff; /* baseline offset */
19272 struct composition *cmp = composition_table[it->cmp_id];
19273 int pos;
19274
19275 /* Maybe translate single-byte characters to multibyte. */
19276 it->char_to_display = it->c;
19277 if (unibyte_display_via_language_environment
19278 && it->c >= 0200)
19279 {
19280 it->char_to_display = unibyte_char_to_multibyte (it->c);
19281 }
19282
19283 /* Get face and font to use. Encode IT->char_to_display. */
19284 pos = STRINGP (it->string) ? IT_STRING_CHARPOS (*it) : IT_CHARPOS (*it);
19285 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
19286 pos, it->string);
19287 face = FACE_FROM_ID (it->f, it->face_id);
19288 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19289 &char2b, it->multibyte_p, 0);
19290 font = face->font;
19291
19292 /* When no suitable font found, use the default font. */
19293 font_not_found_p = font == NULL;
19294 if (font_not_found_p)
19295 {
19296 font = FRAME_FONT (it->f);
19297 boff = FRAME_BASELINE_OFFSET (it->f);
19298 font_info = NULL;
19299 }
19300 else
19301 {
19302 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19303 boff = font_info->baseline_offset;
19304 if (font_info->vertical_centering)
19305 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19306 }
19307
19308 /* There are no padding glyphs, so there is only one glyph to
19309 produce for the composition. Important is that pixel_width,
19310 ascent and descent are the values of what is drawn by
19311 draw_glyphs (i.e. the values of the overall glyphs composed). */
19312 it->nglyphs = 1;
19313
19314 /* If we have not yet calculated pixel size data of glyphs of
19315 the composition for the current face font, calculate them
19316 now. Theoretically, we have to check all fonts for the
19317 glyphs, but that requires much time and memory space. So,
19318 here we check only the font of the first glyph. This leads
19319 to incorrect display, but it's very rare, and C-l (recenter)
19320 can correct the display anyway. */
19321 if (cmp->glyph_len == 0)
19322 {
19323 cmp->lbearing = cmp->rbearing = 0;
19324 cmp->pixel_width = cmp->ascent = cmp->descent = 0;
19325 }
19326 else if (cmp->font != (void *) font)
19327 {
19328 /* Ascent and descent of the font of the first character of
19329 this composition (adjusted by baseline offset). Ascent
19330 and descent of overall glyphs should not be less than
19331 them respectively. */
19332 int font_ascent = FONT_BASE (font) + boff;
19333 int font_descent = FONT_DESCENT (font) - boff;
19334 int font_height = FONT_HEIGHT (font);
19335 /* Bounding box of the overall glyphs. */
19336 int leftmost, rightmost, lowest, highest;
19337 int lbearing, rbearing;
19338 int i, width, ascent, descent;
19339
19340 cmp->font = (void *) font;
19341
19342 /* Initialize the bounding box. */
19343 if (font_info
19344 && (pcm = rif->per_char_metric (font, &char2b,
19345 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19346 {
19347 width = pcm->width;
19348 ascent = pcm->ascent;
19349 descent = pcm->descent;
19350 lbearing = pcm->lbearing;
19351 if (lbearing > 0)
19352 lbearing = 0;
19353 rbearing = pcm->rbearing;
19354 if (rbearing < width)
19355 rbearing = width;
19356 }
19357 else
19358 {
19359 width = FONT_WIDTH (font);
19360 ascent = FONT_BASE (font);
19361 descent = FONT_DESCENT (font);
19362 lbearing = 0;
19363 rbearing = width;
19364 }
19365
19366 rightmost = width;
19367 lowest = - descent + boff;
19368 highest = ascent + boff;
19369 leftmost = 0;
19370
19371 if (font_info
19372 && font_info->default_ascent
19373 && CHAR_TABLE_P (Vuse_default_ascent)
19374 && !NILP (Faref (Vuse_default_ascent,
19375 make_number (it->char_to_display))))
19376 highest = font_info->default_ascent + boff;
19377
19378 /* Draw the first glyph at the normal position. It may be
19379 shifted to right later if some other glyphs are drawn at
19380 the left. */
19381 cmp->offsets[0] = 0;
19382 cmp->offsets[1] = boff;
19383 cmp->lbearing = lbearing;
19384 cmp->rbearing = rbearing;
19385
19386 /* Set cmp->offsets for the remaining glyphs. */
19387 for (i = 1; i < cmp->glyph_len; i++)
19388 {
19389 int left, right, btm, top;
19390 int ch = COMPOSITION_GLYPH (cmp, i);
19391 int face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
19392
19393 face = FACE_FROM_ID (it->f, face_id);
19394 get_char_face_and_encoding (it->f, ch, face->id,
19395 &char2b, it->multibyte_p, 0);
19396 font = face->font;
19397 if (font == NULL)
19398 {
19399 font = FRAME_FONT (it->f);
19400 boff = FRAME_BASELINE_OFFSET (it->f);
19401 font_info = NULL;
19402 }
19403 else
19404 {
19405 font_info
19406 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19407 boff = font_info->baseline_offset;
19408 if (font_info->vertical_centering)
19409 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19410 }
19411
19412 if (font_info
19413 && (pcm = rif->per_char_metric (font, &char2b,
19414 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19415 {
19416 width = pcm->width;
19417 ascent = pcm->ascent;
19418 descent = pcm->descent;
19419 lbearing = pcm->lbearing;
19420 if (lbearing > 0)
19421 lbearing = 0;
19422 rbearing = pcm->rbearing;
19423 if (rbearing < width)
19424 rbearing = width;
19425 }
19426 else
19427 {
19428 width = FONT_WIDTH (font);
19429 ascent = 1;
19430 descent = 0;
19431 lbearing = 0;
19432 rbearing = width;
19433 }
19434
19435 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19436 {
19437 /* Relative composition with or without
19438 alternate chars. */
19439 left = (leftmost + rightmost - width) / 2;
19440 btm = - descent + boff;
19441 if (font_info && font_info->relative_compose
19442 && (! CHAR_TABLE_P (Vignore_relative_composition)
19443 || NILP (Faref (Vignore_relative_composition,
19444 make_number (ch)))))
19445 {
19446
19447 if (- descent >= font_info->relative_compose)
19448 /* One extra pixel between two glyphs. */
19449 btm = highest + 1;
19450 else if (ascent <= 0)
19451 /* One extra pixel between two glyphs. */
19452 btm = lowest - 1 - ascent - descent;
19453 }
19454 }
19455 else
19456 {
19457 /* A composition rule is specified by an integer
19458 value that encodes global and new reference
19459 points (GREF and NREF). GREF and NREF are
19460 specified by numbers as below:
19461
19462 0---1---2 -- ascent
19463 | |
19464 | |
19465 | |
19466 9--10--11 -- center
19467 | |
19468 ---3---4---5--- baseline
19469 | |
19470 6---7---8 -- descent
19471 */
19472 int rule = COMPOSITION_RULE (cmp, i);
19473 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
19474
19475 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
19476 grefx = gref % 3, nrefx = nref % 3;
19477 grefy = gref / 3, nrefy = nref / 3;
19478 if (xoff)
19479 xoff = font_height * (xoff - 128) / 256;
19480 if (yoff)
19481 yoff = font_height * (yoff - 128) / 256;
19482
19483 left = (leftmost
19484 + grefx * (rightmost - leftmost) / 2
19485 - nrefx * width / 2
19486 + xoff);
19487
19488 btm = ((grefy == 0 ? highest
19489 : grefy == 1 ? 0
19490 : grefy == 2 ? lowest
19491 : (highest + lowest) / 2)
19492 - (nrefy == 0 ? ascent + descent
19493 : nrefy == 1 ? descent - boff
19494 : nrefy == 2 ? 0
19495 : (ascent + descent) / 2)
19496 + yoff);
19497 }
19498
19499 cmp->offsets[i * 2] = left;
19500 cmp->offsets[i * 2 + 1] = btm + descent;
19501
19502 /* Update the bounding box of the overall glyphs. */
19503 if (width > 0)
19504 {
19505 right = left + width;
19506 if (left < leftmost)
19507 leftmost = left;
19508 if (right > rightmost)
19509 rightmost = right;
19510 }
19511 top = btm + descent + ascent;
19512 if (top > highest)
19513 highest = top;
19514 if (btm < lowest)
19515 lowest = btm;
19516
19517 if (cmp->lbearing > left + lbearing)
19518 cmp->lbearing = left + lbearing;
19519 if (cmp->rbearing < left + rbearing)
19520 cmp->rbearing = left + rbearing;
19521 }
19522
19523 /* If there are glyphs whose x-offsets are negative,
19524 shift all glyphs to the right and make all x-offsets
19525 non-negative. */
19526 if (leftmost < 0)
19527 {
19528 for (i = 0; i < cmp->glyph_len; i++)
19529 cmp->offsets[i * 2] -= leftmost;
19530 rightmost -= leftmost;
19531 cmp->lbearing -= leftmost;
19532 cmp->rbearing -= leftmost;
19533 }
19534
19535 cmp->pixel_width = rightmost;
19536 cmp->ascent = highest;
19537 cmp->descent = - lowest;
19538 if (cmp->ascent < font_ascent)
19539 cmp->ascent = font_ascent;
19540 if (cmp->descent < font_descent)
19541 cmp->descent = font_descent;
19542 }
19543
19544 if (it->glyph_row
19545 && (cmp->lbearing < 0
19546 || cmp->rbearing > cmp->pixel_width))
19547 it->glyph_row->contains_overlapping_glyphs_p = 1;
19548
19549 it->pixel_width = cmp->pixel_width;
19550 it->ascent = it->phys_ascent = cmp->ascent;
19551 it->descent = it->phys_descent = cmp->descent;
19552
19553 if (face->box != FACE_NO_BOX)
19554 {
19555 int thick = face->box_line_width;
19556
19557 if (thick > 0)
19558 {
19559 it->ascent += thick;
19560 it->descent += thick;
19561 }
19562 else
19563 thick = - thick;
19564
19565 if (it->start_of_box_run_p)
19566 it->pixel_width += thick;
19567 if (it->end_of_box_run_p)
19568 it->pixel_width += thick;
19569 }
19570
19571 /* If face has an overline, add the height of the overline
19572 (1 pixel) and a 1 pixel margin to the character height. */
19573 if (face->overline_p)
19574 it->ascent += 2;
19575
19576 take_vertical_position_into_account (it);
19577
19578 if (it->glyph_row)
19579 append_composite_glyph (it);
19580 }
19581 else if (it->what == IT_IMAGE)
19582 produce_image_glyph (it);
19583 else if (it->what == IT_STRETCH)
19584 produce_stretch_glyph (it);
19585
19586 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19587 because this isn't true for images with `:ascent 100'. */
19588 xassert (it->ascent >= 0 && it->descent >= 0);
19589 if (it->area == TEXT_AREA)
19590 it->current_x += it->pixel_width;
19591
19592 if (extra_line_spacing > 0)
19593 it->descent += extra_line_spacing;
19594
19595 it->max_ascent = max (it->max_ascent, it->ascent);
19596 it->max_descent = max (it->max_descent, it->descent);
19597 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19598 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19599 }
19600
19601 /* EXPORT for RIF:
19602 Output LEN glyphs starting at START at the nominal cursor position.
19603 Advance the nominal cursor over the text. The global variable
19604 updated_window contains the window being updated, updated_row is
19605 the glyph row being updated, and updated_area is the area of that
19606 row being updated. */
19607
19608 void
19609 x_write_glyphs (start, len)
19610 struct glyph *start;
19611 int len;
19612 {
19613 int x, hpos;
19614
19615 xassert (updated_window && updated_row);
19616 BLOCK_INPUT;
19617
19618 /* Write glyphs. */
19619
19620 hpos = start - updated_row->glyphs[updated_area];
19621 x = draw_glyphs (updated_window, output_cursor.x,
19622 updated_row, updated_area,
19623 hpos, hpos + len,
19624 DRAW_NORMAL_TEXT, 0);
19625
19626 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19627 if (updated_area == TEXT_AREA
19628 && updated_window->phys_cursor_on_p
19629 && updated_window->phys_cursor.vpos == output_cursor.vpos
19630 && updated_window->phys_cursor.hpos >= hpos
19631 && updated_window->phys_cursor.hpos < hpos + len)
19632 updated_window->phys_cursor_on_p = 0;
19633
19634 UNBLOCK_INPUT;
19635
19636 /* Advance the output cursor. */
19637 output_cursor.hpos += len;
19638 output_cursor.x = x;
19639 }
19640
19641
19642 /* EXPORT for RIF:
19643 Insert LEN glyphs from START at the nominal cursor position. */
19644
19645 void
19646 x_insert_glyphs (start, len)
19647 struct glyph *start;
19648 int len;
19649 {
19650 struct frame *f;
19651 struct window *w;
19652 int line_height, shift_by_width, shifted_region_width;
19653 struct glyph_row *row;
19654 struct glyph *glyph;
19655 int frame_x, frame_y;
19656 EMACS_INT hpos;
19657
19658 xassert (updated_window && updated_row);
19659 BLOCK_INPUT;
19660 w = updated_window;
19661 f = XFRAME (WINDOW_FRAME (w));
19662
19663 /* Get the height of the line we are in. */
19664 row = updated_row;
19665 line_height = row->height;
19666
19667 /* Get the width of the glyphs to insert. */
19668 shift_by_width = 0;
19669 for (glyph = start; glyph < start + len; ++glyph)
19670 shift_by_width += glyph->pixel_width;
19671
19672 /* Get the width of the region to shift right. */
19673 shifted_region_width = (window_box_width (w, updated_area)
19674 - output_cursor.x
19675 - shift_by_width);
19676
19677 /* Shift right. */
19678 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19679 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19680
19681 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19682 line_height, shift_by_width);
19683
19684 /* Write the glyphs. */
19685 hpos = start - row->glyphs[updated_area];
19686 draw_glyphs (w, output_cursor.x, row, updated_area,
19687 hpos, hpos + len,
19688 DRAW_NORMAL_TEXT, 0);
19689
19690 /* Advance the output cursor. */
19691 output_cursor.hpos += len;
19692 output_cursor.x += shift_by_width;
19693 UNBLOCK_INPUT;
19694 }
19695
19696
19697 /* EXPORT for RIF:
19698 Erase the current text line from the nominal cursor position
19699 (inclusive) to pixel column TO_X (exclusive). The idea is that
19700 everything from TO_X onward is already erased.
19701
19702 TO_X is a pixel position relative to updated_area of
19703 updated_window. TO_X == -1 means clear to the end of this area. */
19704
19705 void
19706 x_clear_end_of_line (to_x)
19707 int to_x;
19708 {
19709 struct frame *f;
19710 struct window *w = updated_window;
19711 int max_x, min_y, max_y;
19712 int from_x, from_y, to_y;
19713
19714 xassert (updated_window && updated_row);
19715 f = XFRAME (w->frame);
19716
19717 if (updated_row->full_width_p)
19718 max_x = WINDOW_TOTAL_WIDTH (w);
19719 else
19720 max_x = window_box_width (w, updated_area);
19721 max_y = window_text_bottom_y (w);
19722
19723 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19724 of window. For TO_X > 0, truncate to end of drawing area. */
19725 if (to_x == 0)
19726 return;
19727 else if (to_x < 0)
19728 to_x = max_x;
19729 else
19730 to_x = min (to_x, max_x);
19731
19732 to_y = min (max_y, output_cursor.y + updated_row->height);
19733
19734 /* Notice if the cursor will be cleared by this operation. */
19735 if (!updated_row->full_width_p)
19736 notice_overwritten_cursor (w, updated_area,
19737 output_cursor.x, -1,
19738 updated_row->y,
19739 MATRIX_ROW_BOTTOM_Y (updated_row));
19740
19741 from_x = output_cursor.x;
19742
19743 /* Translate to frame coordinates. */
19744 if (updated_row->full_width_p)
19745 {
19746 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19747 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19748 }
19749 else
19750 {
19751 int area_left = window_box_left (w, updated_area);
19752 from_x += area_left;
19753 to_x += area_left;
19754 }
19755
19756 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19757 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19758 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19759
19760 /* Prevent inadvertently clearing to end of the X window. */
19761 if (to_x > from_x && to_y > from_y)
19762 {
19763 BLOCK_INPUT;
19764 rif->clear_frame_area (f, from_x, from_y,
19765 to_x - from_x, to_y - from_y);
19766 UNBLOCK_INPUT;
19767 }
19768 }
19769
19770 #endif /* HAVE_WINDOW_SYSTEM */
19771
19772
19773 \f
19774 /***********************************************************************
19775 Cursor types
19776 ***********************************************************************/
19777
19778 /* Value is the internal representation of the specified cursor type
19779 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19780 of the bar cursor. */
19781
19782 static enum text_cursor_kinds
19783 get_specified_cursor_type (arg, width)
19784 Lisp_Object arg;
19785 int *width;
19786 {
19787 enum text_cursor_kinds type;
19788
19789 if (NILP (arg))
19790 return NO_CURSOR;
19791
19792 if (EQ (arg, Qbox))
19793 return FILLED_BOX_CURSOR;
19794
19795 if (EQ (arg, Qhollow))
19796 return HOLLOW_BOX_CURSOR;
19797
19798 if (EQ (arg, Qbar))
19799 {
19800 *width = 2;
19801 return BAR_CURSOR;
19802 }
19803
19804 if (CONSP (arg)
19805 && EQ (XCAR (arg), Qbar)
19806 && INTEGERP (XCDR (arg))
19807 && XINT (XCDR (arg)) >= 0)
19808 {
19809 *width = XINT (XCDR (arg));
19810 return BAR_CURSOR;
19811 }
19812
19813 if (EQ (arg, Qhbar))
19814 {
19815 *width = 2;
19816 return HBAR_CURSOR;
19817 }
19818
19819 if (CONSP (arg)
19820 && EQ (XCAR (arg), Qhbar)
19821 && INTEGERP (XCDR (arg))
19822 && XINT (XCDR (arg)) >= 0)
19823 {
19824 *width = XINT (XCDR (arg));
19825 return HBAR_CURSOR;
19826 }
19827
19828 /* Treat anything unknown as "hollow box cursor".
19829 It was bad to signal an error; people have trouble fixing
19830 .Xdefaults with Emacs, when it has something bad in it. */
19831 type = HOLLOW_BOX_CURSOR;
19832
19833 return type;
19834 }
19835
19836 /* Set the default cursor types for specified frame. */
19837 void
19838 set_frame_cursor_types (f, arg)
19839 struct frame *f;
19840 Lisp_Object arg;
19841 {
19842 int width;
19843 Lisp_Object tem;
19844
19845 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19846 FRAME_CURSOR_WIDTH (f) = width;
19847
19848 /* By default, set up the blink-off state depending on the on-state. */
19849
19850 tem = Fassoc (arg, Vblink_cursor_alist);
19851 if (!NILP (tem))
19852 {
19853 FRAME_BLINK_OFF_CURSOR (f)
19854 = get_specified_cursor_type (XCDR (tem), &width);
19855 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19856 }
19857 else
19858 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19859 }
19860
19861
19862 /* Return the cursor we want to be displayed in window W. Return
19863 width of bar/hbar cursor through WIDTH arg. Return with
19864 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19865 (i.e. if the `system caret' should track this cursor).
19866
19867 In a mini-buffer window, we want the cursor only to appear if we
19868 are reading input from this window. For the selected window, we
19869 want the cursor type given by the frame parameter or buffer local
19870 setting of cursor-type. If explicitly marked off, draw no cursor.
19871 In all other cases, we want a hollow box cursor. */
19872
19873 static enum text_cursor_kinds
19874 get_window_cursor_type (w, glyph, width, active_cursor)
19875 struct window *w;
19876 struct glyph *glyph;
19877 int *width;
19878 int *active_cursor;
19879 {
19880 struct frame *f = XFRAME (w->frame);
19881 struct buffer *b = XBUFFER (w->buffer);
19882 int cursor_type = DEFAULT_CURSOR;
19883 Lisp_Object alt_cursor;
19884 int non_selected = 0;
19885
19886 *active_cursor = 1;
19887
19888 /* Echo area */
19889 if (cursor_in_echo_area
19890 && FRAME_HAS_MINIBUF_P (f)
19891 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19892 {
19893 if (w == XWINDOW (echo_area_window))
19894 {
19895 *width = FRAME_CURSOR_WIDTH (f);
19896 return FRAME_DESIRED_CURSOR (f);
19897 }
19898
19899 *active_cursor = 0;
19900 non_selected = 1;
19901 }
19902
19903 /* Nonselected window or nonselected frame. */
19904 else if (w != XWINDOW (f->selected_window)
19905 #ifdef HAVE_WINDOW_SYSTEM
19906 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19907 #endif
19908 )
19909 {
19910 *active_cursor = 0;
19911
19912 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19913 return NO_CURSOR;
19914
19915 non_selected = 1;
19916 }
19917
19918 /* Never display a cursor in a window in which cursor-type is nil. */
19919 if (NILP (b->cursor_type))
19920 return NO_CURSOR;
19921
19922 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19923 if (non_selected)
19924 {
19925 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19926 return get_specified_cursor_type (alt_cursor, width);
19927 }
19928
19929 /* Get the normal cursor type for this window. */
19930 if (EQ (b->cursor_type, Qt))
19931 {
19932 cursor_type = FRAME_DESIRED_CURSOR (f);
19933 *width = FRAME_CURSOR_WIDTH (f);
19934 }
19935 else
19936 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19937
19938 /* Use normal cursor if not blinked off. */
19939 if (!w->cursor_off_p)
19940 {
19941 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19942 if (cursor_type == FILLED_BOX_CURSOR)
19943 cursor_type = HOLLOW_BOX_CURSOR;
19944 }
19945 return cursor_type;
19946 }
19947
19948 /* Cursor is blinked off, so determine how to "toggle" it. */
19949
19950 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19951 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19952 return get_specified_cursor_type (XCDR (alt_cursor), width);
19953
19954 /* Then see if frame has specified a specific blink off cursor type. */
19955 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19956 {
19957 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19958 return FRAME_BLINK_OFF_CURSOR (f);
19959 }
19960
19961 #if 0
19962 /* Some people liked having a permanently visible blinking cursor,
19963 while others had very strong opinions against it. So it was
19964 decided to remove it. KFS 2003-09-03 */
19965
19966 /* Finally perform built-in cursor blinking:
19967 filled box <-> hollow box
19968 wide [h]bar <-> narrow [h]bar
19969 narrow [h]bar <-> no cursor
19970 other type <-> no cursor */
19971
19972 if (cursor_type == FILLED_BOX_CURSOR)
19973 return HOLLOW_BOX_CURSOR;
19974
19975 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19976 {
19977 *width = 1;
19978 return cursor_type;
19979 }
19980 #endif
19981
19982 return NO_CURSOR;
19983 }
19984
19985
19986 #ifdef HAVE_WINDOW_SYSTEM
19987
19988 /* Notice when the text cursor of window W has been completely
19989 overwritten by a drawing operation that outputs glyphs in AREA
19990 starting at X0 and ending at X1 in the line starting at Y0 and
19991 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19992 the rest of the line after X0 has been written. Y coordinates
19993 are window-relative. */
19994
19995 static void
19996 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19997 struct window *w;
19998 enum glyph_row_area area;
19999 int x0, y0, x1, y1;
20000 {
20001 int cx0, cx1, cy0, cy1;
20002 struct glyph_row *row;
20003
20004 if (!w->phys_cursor_on_p)
20005 return;
20006 if (area != TEXT_AREA)
20007 return;
20008
20009 row = w->current_matrix->rows + w->phys_cursor.vpos;
20010 if (!row->displays_text_p)
20011 return;
20012
20013 if (row->cursor_in_fringe_p)
20014 {
20015 row->cursor_in_fringe_p = 0;
20016 draw_fringe_bitmap (w, row, 0);
20017 w->phys_cursor_on_p = 0;
20018 return;
20019 }
20020
20021 cx0 = w->phys_cursor.x;
20022 cx1 = cx0 + w->phys_cursor_width;
20023 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20024 return;
20025
20026 /* The cursor image will be completely removed from the
20027 screen if the output area intersects the cursor area in
20028 y-direction. When we draw in [y0 y1[, and some part of
20029 the cursor is at y < y0, that part must have been drawn
20030 before. When scrolling, the cursor is erased before
20031 actually scrolling, so we don't come here. When not
20032 scrolling, the rows above the old cursor row must have
20033 changed, and in this case these rows must have written
20034 over the cursor image.
20035
20036 Likewise if part of the cursor is below y1, with the
20037 exception of the cursor being in the first blank row at
20038 the buffer and window end because update_text_area
20039 doesn't draw that row. (Except when it does, but
20040 that's handled in update_text_area.) */
20041
20042 cy0 = w->phys_cursor.y;
20043 cy1 = cy0 + w->phys_cursor_height;
20044 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20045 return;
20046
20047 w->phys_cursor_on_p = 0;
20048 }
20049
20050 #endif /* HAVE_WINDOW_SYSTEM */
20051
20052 \f
20053 /************************************************************************
20054 Mouse Face
20055 ************************************************************************/
20056
20057 #ifdef HAVE_WINDOW_SYSTEM
20058
20059 /* EXPORT for RIF:
20060 Fix the display of area AREA of overlapping row ROW in window W. */
20061
20062 void
20063 x_fix_overlapping_area (w, row, area)
20064 struct window *w;
20065 struct glyph_row *row;
20066 enum glyph_row_area area;
20067 {
20068 int i, x;
20069
20070 BLOCK_INPUT;
20071
20072 x = 0;
20073 for (i = 0; i < row->used[area];)
20074 {
20075 if (row->glyphs[area][i].overlaps_vertically_p)
20076 {
20077 int start = i, start_x = x;
20078
20079 do
20080 {
20081 x += row->glyphs[area][i].pixel_width;
20082 ++i;
20083 }
20084 while (i < row->used[area]
20085 && row->glyphs[area][i].overlaps_vertically_p);
20086
20087 draw_glyphs (w, start_x, row, area,
20088 start, i,
20089 DRAW_NORMAL_TEXT, 1);
20090 }
20091 else
20092 {
20093 x += row->glyphs[area][i].pixel_width;
20094 ++i;
20095 }
20096 }
20097
20098 UNBLOCK_INPUT;
20099 }
20100
20101
20102 /* EXPORT:
20103 Draw the cursor glyph of window W in glyph row ROW. See the
20104 comment of draw_glyphs for the meaning of HL. */
20105
20106 void
20107 draw_phys_cursor_glyph (w, row, hl)
20108 struct window *w;
20109 struct glyph_row *row;
20110 enum draw_glyphs_face hl;
20111 {
20112 /* If cursor hpos is out of bounds, don't draw garbage. This can
20113 happen in mini-buffer windows when switching between echo area
20114 glyphs and mini-buffer. */
20115 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20116 {
20117 int on_p = w->phys_cursor_on_p;
20118 int x1;
20119 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20120 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20121 hl, 0);
20122 w->phys_cursor_on_p = on_p;
20123
20124 if (hl == DRAW_CURSOR)
20125 w->phys_cursor_width = x1 - w->phys_cursor.x;
20126 /* When we erase the cursor, and ROW is overlapped by other
20127 rows, make sure that these overlapping parts of other rows
20128 are redrawn. */
20129 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20130 {
20131 if (row > w->current_matrix->rows
20132 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20133 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20134
20135 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20136 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20137 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20138 }
20139 }
20140 }
20141
20142
20143 /* EXPORT:
20144 Erase the image of a cursor of window W from the screen. */
20145
20146 void
20147 erase_phys_cursor (w)
20148 struct window *w;
20149 {
20150 struct frame *f = XFRAME (w->frame);
20151 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20152 int hpos = w->phys_cursor.hpos;
20153 int vpos = w->phys_cursor.vpos;
20154 int mouse_face_here_p = 0;
20155 struct glyph_matrix *active_glyphs = w->current_matrix;
20156 struct glyph_row *cursor_row;
20157 struct glyph *cursor_glyph;
20158 enum draw_glyphs_face hl;
20159
20160 /* No cursor displayed or row invalidated => nothing to do on the
20161 screen. */
20162 if (w->phys_cursor_type == NO_CURSOR)
20163 goto mark_cursor_off;
20164
20165 /* VPOS >= active_glyphs->nrows means that window has been resized.
20166 Don't bother to erase the cursor. */
20167 if (vpos >= active_glyphs->nrows)
20168 goto mark_cursor_off;
20169
20170 /* If row containing cursor is marked invalid, there is nothing we
20171 can do. */
20172 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20173 if (!cursor_row->enabled_p)
20174 goto mark_cursor_off;
20175
20176 /* If row is completely invisible, don't attempt to delete a cursor which
20177 isn't there. This can happen if cursor is at top of a window, and
20178 we switch to a buffer with a header line in that window. */
20179 if (cursor_row->visible_height <= 0)
20180 goto mark_cursor_off;
20181
20182 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20183 if (cursor_row->cursor_in_fringe_p)
20184 {
20185 cursor_row->cursor_in_fringe_p = 0;
20186 draw_fringe_bitmap (w, cursor_row, 0);
20187 goto mark_cursor_off;
20188 }
20189
20190 /* This can happen when the new row is shorter than the old one.
20191 In this case, either draw_glyphs or clear_end_of_line
20192 should have cleared the cursor. Note that we wouldn't be
20193 able to erase the cursor in this case because we don't have a
20194 cursor glyph at hand. */
20195 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20196 goto mark_cursor_off;
20197
20198 /* If the cursor is in the mouse face area, redisplay that when
20199 we clear the cursor. */
20200 if (! NILP (dpyinfo->mouse_face_window)
20201 && w == XWINDOW (dpyinfo->mouse_face_window)
20202 && (vpos > dpyinfo->mouse_face_beg_row
20203 || (vpos == dpyinfo->mouse_face_beg_row
20204 && hpos >= dpyinfo->mouse_face_beg_col))
20205 && (vpos < dpyinfo->mouse_face_end_row
20206 || (vpos == dpyinfo->mouse_face_end_row
20207 && hpos < dpyinfo->mouse_face_end_col))
20208 /* Don't redraw the cursor's spot in mouse face if it is at the
20209 end of a line (on a newline). The cursor appears there, but
20210 mouse highlighting does not. */
20211 && cursor_row->used[TEXT_AREA] > hpos)
20212 mouse_face_here_p = 1;
20213
20214 /* Maybe clear the display under the cursor. */
20215 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20216 {
20217 int x, y;
20218 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20219
20220 cursor_glyph = get_phys_cursor_glyph (w);
20221 if (cursor_glyph == NULL)
20222 goto mark_cursor_off;
20223
20224 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20225 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20226
20227 rif->clear_frame_area (f, x, y,
20228 cursor_glyph->pixel_width, cursor_row->visible_height);
20229 }
20230
20231 /* Erase the cursor by redrawing the character underneath it. */
20232 if (mouse_face_here_p)
20233 hl = DRAW_MOUSE_FACE;
20234 else
20235 hl = DRAW_NORMAL_TEXT;
20236 draw_phys_cursor_glyph (w, cursor_row, hl);
20237
20238 mark_cursor_off:
20239 w->phys_cursor_on_p = 0;
20240 w->phys_cursor_type = NO_CURSOR;
20241 }
20242
20243
20244 /* EXPORT:
20245 Display or clear cursor of window W. If ON is zero, clear the
20246 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20247 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20248
20249 void
20250 display_and_set_cursor (w, on, hpos, vpos, x, y)
20251 struct window *w;
20252 int on, hpos, vpos, x, y;
20253 {
20254 struct frame *f = XFRAME (w->frame);
20255 int new_cursor_type;
20256 int new_cursor_width;
20257 int active_cursor;
20258 struct glyph_row *glyph_row;
20259 struct glyph *glyph;
20260
20261 /* This is pointless on invisible frames, and dangerous on garbaged
20262 windows and frames; in the latter case, the frame or window may
20263 be in the midst of changing its size, and x and y may be off the
20264 window. */
20265 if (! FRAME_VISIBLE_P (f)
20266 || FRAME_GARBAGED_P (f)
20267 || vpos >= w->current_matrix->nrows
20268 || hpos >= w->current_matrix->matrix_w)
20269 return;
20270
20271 /* If cursor is off and we want it off, return quickly. */
20272 if (!on && !w->phys_cursor_on_p)
20273 return;
20274
20275 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20276 /* If cursor row is not enabled, we don't really know where to
20277 display the cursor. */
20278 if (!glyph_row->enabled_p)
20279 {
20280 w->phys_cursor_on_p = 0;
20281 return;
20282 }
20283
20284 glyph = NULL;
20285 if (!glyph_row->exact_window_width_line_p
20286 || hpos < glyph_row->used[TEXT_AREA])
20287 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20288
20289 xassert (interrupt_input_blocked);
20290
20291 /* Set new_cursor_type to the cursor we want to be displayed. */
20292 new_cursor_type = get_window_cursor_type (w, glyph,
20293 &new_cursor_width, &active_cursor);
20294
20295 /* If cursor is currently being shown and we don't want it to be or
20296 it is in the wrong place, or the cursor type is not what we want,
20297 erase it. */
20298 if (w->phys_cursor_on_p
20299 && (!on
20300 || w->phys_cursor.x != x
20301 || w->phys_cursor.y != y
20302 || new_cursor_type != w->phys_cursor_type
20303 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20304 && new_cursor_width != w->phys_cursor_width)))
20305 erase_phys_cursor (w);
20306
20307 /* Don't check phys_cursor_on_p here because that flag is only set
20308 to zero in some cases where we know that the cursor has been
20309 completely erased, to avoid the extra work of erasing the cursor
20310 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20311 still not be visible, or it has only been partly erased. */
20312 if (on)
20313 {
20314 w->phys_cursor_ascent = glyph_row->ascent;
20315 w->phys_cursor_height = glyph_row->height;
20316
20317 /* Set phys_cursor_.* before x_draw_.* is called because some
20318 of them may need the information. */
20319 w->phys_cursor.x = x;
20320 w->phys_cursor.y = glyph_row->y;
20321 w->phys_cursor.hpos = hpos;
20322 w->phys_cursor.vpos = vpos;
20323 }
20324
20325 rif->draw_window_cursor (w, glyph_row, x, y,
20326 new_cursor_type, new_cursor_width,
20327 on, active_cursor);
20328 }
20329
20330
20331 /* Switch the display of W's cursor on or off, according to the value
20332 of ON. */
20333
20334 static void
20335 update_window_cursor (w, on)
20336 struct window *w;
20337 int on;
20338 {
20339 /* Don't update cursor in windows whose frame is in the process
20340 of being deleted. */
20341 if (w->current_matrix)
20342 {
20343 BLOCK_INPUT;
20344 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20345 w->phys_cursor.x, w->phys_cursor.y);
20346 UNBLOCK_INPUT;
20347 }
20348 }
20349
20350
20351 /* Call update_window_cursor with parameter ON_P on all leaf windows
20352 in the window tree rooted at W. */
20353
20354 static void
20355 update_cursor_in_window_tree (w, on_p)
20356 struct window *w;
20357 int on_p;
20358 {
20359 while (w)
20360 {
20361 if (!NILP (w->hchild))
20362 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20363 else if (!NILP (w->vchild))
20364 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20365 else
20366 update_window_cursor (w, on_p);
20367
20368 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20369 }
20370 }
20371
20372
20373 /* EXPORT:
20374 Display the cursor on window W, or clear it, according to ON_P.
20375 Don't change the cursor's position. */
20376
20377 void
20378 x_update_cursor (f, on_p)
20379 struct frame *f;
20380 int on_p;
20381 {
20382 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20383 }
20384
20385
20386 /* EXPORT:
20387 Clear the cursor of window W to background color, and mark the
20388 cursor as not shown. This is used when the text where the cursor
20389 is is about to be rewritten. */
20390
20391 void
20392 x_clear_cursor (w)
20393 struct window *w;
20394 {
20395 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20396 update_window_cursor (w, 0);
20397 }
20398
20399
20400 /* EXPORT:
20401 Display the active region described by mouse_face_* according to DRAW. */
20402
20403 void
20404 show_mouse_face (dpyinfo, draw)
20405 Display_Info *dpyinfo;
20406 enum draw_glyphs_face draw;
20407 {
20408 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20409 struct frame *f = XFRAME (WINDOW_FRAME (w));
20410
20411 if (/* If window is in the process of being destroyed, don't bother
20412 to do anything. */
20413 w->current_matrix != NULL
20414 /* Don't update mouse highlight if hidden */
20415 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20416 /* Recognize when we are called to operate on rows that don't exist
20417 anymore. This can happen when a window is split. */
20418 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20419 {
20420 int phys_cursor_on_p = w->phys_cursor_on_p;
20421 struct glyph_row *row, *first, *last;
20422
20423 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20424 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20425
20426 for (row = first; row <= last && row->enabled_p; ++row)
20427 {
20428 int start_hpos, end_hpos, start_x;
20429
20430 /* For all but the first row, the highlight starts at column 0. */
20431 if (row == first)
20432 {
20433 start_hpos = dpyinfo->mouse_face_beg_col;
20434 start_x = dpyinfo->mouse_face_beg_x;
20435 }
20436 else
20437 {
20438 start_hpos = 0;
20439 start_x = 0;
20440 }
20441
20442 if (row == last)
20443 end_hpos = dpyinfo->mouse_face_end_col;
20444 else
20445 end_hpos = row->used[TEXT_AREA];
20446
20447 if (end_hpos > start_hpos)
20448 {
20449 draw_glyphs (w, start_x, row, TEXT_AREA,
20450 start_hpos, end_hpos,
20451 draw, 0);
20452
20453 row->mouse_face_p
20454 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20455 }
20456 }
20457
20458 /* When we've written over the cursor, arrange for it to
20459 be displayed again. */
20460 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20461 {
20462 BLOCK_INPUT;
20463 display_and_set_cursor (w, 1,
20464 w->phys_cursor.hpos, w->phys_cursor.vpos,
20465 w->phys_cursor.x, w->phys_cursor.y);
20466 UNBLOCK_INPUT;
20467 }
20468 }
20469
20470 /* Change the mouse cursor. */
20471 if (draw == DRAW_NORMAL_TEXT)
20472 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20473 else if (draw == DRAW_MOUSE_FACE)
20474 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20475 else
20476 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20477 }
20478
20479 /* EXPORT:
20480 Clear out the mouse-highlighted active region.
20481 Redraw it un-highlighted first. Value is non-zero if mouse
20482 face was actually drawn unhighlighted. */
20483
20484 int
20485 clear_mouse_face (dpyinfo)
20486 Display_Info *dpyinfo;
20487 {
20488 int cleared = 0;
20489
20490 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20491 {
20492 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20493 cleared = 1;
20494 }
20495
20496 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20497 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20498 dpyinfo->mouse_face_window = Qnil;
20499 dpyinfo->mouse_face_overlay = Qnil;
20500 return cleared;
20501 }
20502
20503
20504 /* EXPORT:
20505 Non-zero if physical cursor of window W is within mouse face. */
20506
20507 int
20508 cursor_in_mouse_face_p (w)
20509 struct window *w;
20510 {
20511 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20512 int in_mouse_face = 0;
20513
20514 if (WINDOWP (dpyinfo->mouse_face_window)
20515 && XWINDOW (dpyinfo->mouse_face_window) == w)
20516 {
20517 int hpos = w->phys_cursor.hpos;
20518 int vpos = w->phys_cursor.vpos;
20519
20520 if (vpos >= dpyinfo->mouse_face_beg_row
20521 && vpos <= dpyinfo->mouse_face_end_row
20522 && (vpos > dpyinfo->mouse_face_beg_row
20523 || hpos >= dpyinfo->mouse_face_beg_col)
20524 && (vpos < dpyinfo->mouse_face_end_row
20525 || hpos < dpyinfo->mouse_face_end_col
20526 || dpyinfo->mouse_face_past_end))
20527 in_mouse_face = 1;
20528 }
20529
20530 return in_mouse_face;
20531 }
20532
20533
20534
20535 \f
20536 /* Find the glyph matrix position of buffer position CHARPOS in window
20537 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20538 current glyphs must be up to date. If CHARPOS is above window
20539 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20540 of last line in W. In the row containing CHARPOS, stop before glyphs
20541 having STOP as object. */
20542
20543 #if 1 /* This is a version of fast_find_position that's more correct
20544 in the presence of hscrolling, for example. I didn't install
20545 it right away because the problem fixed is minor, it failed
20546 in 20.x as well, and I think it's too risky to install
20547 so near the release of 21.1. 2001-09-25 gerd. */
20548
20549 static int
20550 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20551 struct window *w;
20552 EMACS_INT charpos;
20553 int *hpos, *vpos, *x, *y;
20554 Lisp_Object stop;
20555 {
20556 struct glyph_row *row, *first;
20557 struct glyph *glyph, *end;
20558 int past_end = 0;
20559
20560 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20561 row = row_containing_pos (w, charpos, first, NULL, 0);
20562 if (row == NULL)
20563 {
20564 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20565 {
20566 *x = *y = *hpos = *vpos = 0;
20567 return 1;
20568 }
20569 else
20570 {
20571 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20572 past_end = 1;
20573 }
20574 }
20575
20576 *x = row->x;
20577 *y = row->y;
20578 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20579
20580 glyph = row->glyphs[TEXT_AREA];
20581 end = glyph + row->used[TEXT_AREA];
20582
20583 /* Skip over glyphs not having an object at the start of the row.
20584 These are special glyphs like truncation marks on terminal
20585 frames. */
20586 if (row->displays_text_p)
20587 while (glyph < end
20588 && INTEGERP (glyph->object)
20589 && !EQ (stop, glyph->object)
20590 && glyph->charpos < 0)
20591 {
20592 *x += glyph->pixel_width;
20593 ++glyph;
20594 }
20595
20596 while (glyph < end
20597 && !INTEGERP (glyph->object)
20598 && !EQ (stop, glyph->object)
20599 && (!BUFFERP (glyph->object)
20600 || glyph->charpos < charpos))
20601 {
20602 *x += glyph->pixel_width;
20603 ++glyph;
20604 }
20605
20606 *hpos = glyph - row->glyphs[TEXT_AREA];
20607 return !past_end;
20608 }
20609
20610 #else /* not 1 */
20611
20612 static int
20613 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20614 struct window *w;
20615 EMACS_INT pos;
20616 int *hpos, *vpos, *x, *y;
20617 Lisp_Object stop;
20618 {
20619 int i;
20620 int lastcol;
20621 int maybe_next_line_p = 0;
20622 int line_start_position;
20623 int yb = window_text_bottom_y (w);
20624 struct glyph_row *row, *best_row;
20625 int row_vpos, best_row_vpos;
20626 int current_x;
20627
20628 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20629 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20630
20631 while (row->y < yb)
20632 {
20633 if (row->used[TEXT_AREA])
20634 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20635 else
20636 line_start_position = 0;
20637
20638 if (line_start_position > pos)
20639 break;
20640 /* If the position sought is the end of the buffer,
20641 don't include the blank lines at the bottom of the window. */
20642 else if (line_start_position == pos
20643 && pos == BUF_ZV (XBUFFER (w->buffer)))
20644 {
20645 maybe_next_line_p = 1;
20646 break;
20647 }
20648 else if (line_start_position > 0)
20649 {
20650 best_row = row;
20651 best_row_vpos = row_vpos;
20652 }
20653
20654 if (row->y + row->height >= yb)
20655 break;
20656
20657 ++row;
20658 ++row_vpos;
20659 }
20660
20661 /* Find the right column within BEST_ROW. */
20662 lastcol = 0;
20663 current_x = best_row->x;
20664 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20665 {
20666 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20667 int charpos = glyph->charpos;
20668
20669 if (BUFFERP (glyph->object))
20670 {
20671 if (charpos == pos)
20672 {
20673 *hpos = i;
20674 *vpos = best_row_vpos;
20675 *x = current_x;
20676 *y = best_row->y;
20677 return 1;
20678 }
20679 else if (charpos > pos)
20680 break;
20681 }
20682 else if (EQ (glyph->object, stop))
20683 break;
20684
20685 if (charpos > 0)
20686 lastcol = i;
20687 current_x += glyph->pixel_width;
20688 }
20689
20690 /* If we're looking for the end of the buffer,
20691 and we didn't find it in the line we scanned,
20692 use the start of the following line. */
20693 if (maybe_next_line_p)
20694 {
20695 ++best_row;
20696 ++best_row_vpos;
20697 lastcol = 0;
20698 current_x = best_row->x;
20699 }
20700
20701 *vpos = best_row_vpos;
20702 *hpos = lastcol + 1;
20703 *x = current_x;
20704 *y = best_row->y;
20705 return 0;
20706 }
20707
20708 #endif /* not 1 */
20709
20710
20711 /* Find the position of the glyph for position POS in OBJECT in
20712 window W's current matrix, and return in *X, *Y the pixel
20713 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20714
20715 RIGHT_P non-zero means return the position of the right edge of the
20716 glyph, RIGHT_P zero means return the left edge position.
20717
20718 If no glyph for POS exists in the matrix, return the position of
20719 the glyph with the next smaller position that is in the matrix, if
20720 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20721 exists in the matrix, return the position of the glyph with the
20722 next larger position in OBJECT.
20723
20724 Value is non-zero if a glyph was found. */
20725
20726 static int
20727 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20728 struct window *w;
20729 EMACS_INT pos;
20730 Lisp_Object object;
20731 int *hpos, *vpos, *x, *y;
20732 int right_p;
20733 {
20734 int yb = window_text_bottom_y (w);
20735 struct glyph_row *r;
20736 struct glyph *best_glyph = NULL;
20737 struct glyph_row *best_row = NULL;
20738 int best_x = 0;
20739
20740 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20741 r->enabled_p && r->y < yb;
20742 ++r)
20743 {
20744 struct glyph *g = r->glyphs[TEXT_AREA];
20745 struct glyph *e = g + r->used[TEXT_AREA];
20746 int gx;
20747
20748 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20749 if (EQ (g->object, object))
20750 {
20751 if (g->charpos == pos)
20752 {
20753 best_glyph = g;
20754 best_x = gx;
20755 best_row = r;
20756 goto found;
20757 }
20758 else if (best_glyph == NULL
20759 || ((abs (g->charpos - pos)
20760 < abs (best_glyph->charpos - pos))
20761 && (right_p
20762 ? g->charpos < pos
20763 : g->charpos > pos)))
20764 {
20765 best_glyph = g;
20766 best_x = gx;
20767 best_row = r;
20768 }
20769 }
20770 }
20771
20772 found:
20773
20774 if (best_glyph)
20775 {
20776 *x = best_x;
20777 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20778
20779 if (right_p)
20780 {
20781 *x += best_glyph->pixel_width;
20782 ++*hpos;
20783 }
20784
20785 *y = best_row->y;
20786 *vpos = best_row - w->current_matrix->rows;
20787 }
20788
20789 return best_glyph != NULL;
20790 }
20791
20792
20793 /* See if position X, Y is within a hot-spot of an image. */
20794
20795 static int
20796 on_hot_spot_p (hot_spot, x, y)
20797 Lisp_Object hot_spot;
20798 int x, y;
20799 {
20800 if (!CONSP (hot_spot))
20801 return 0;
20802
20803 if (EQ (XCAR (hot_spot), Qrect))
20804 {
20805 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20806 Lisp_Object rect = XCDR (hot_spot);
20807 Lisp_Object tem;
20808 if (!CONSP (rect))
20809 return 0;
20810 if (!CONSP (XCAR (rect)))
20811 return 0;
20812 if (!CONSP (XCDR (rect)))
20813 return 0;
20814 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20815 return 0;
20816 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20817 return 0;
20818 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20819 return 0;
20820 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20821 return 0;
20822 return 1;
20823 }
20824 else if (EQ (XCAR (hot_spot), Qcircle))
20825 {
20826 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20827 Lisp_Object circ = XCDR (hot_spot);
20828 Lisp_Object lr, lx0, ly0;
20829 if (CONSP (circ)
20830 && CONSP (XCAR (circ))
20831 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20832 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20833 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20834 {
20835 double r = XFLOATINT (lr);
20836 double dx = XINT (lx0) - x;
20837 double dy = XINT (ly0) - y;
20838 return (dx * dx + dy * dy <= r * r);
20839 }
20840 }
20841 else if (EQ (XCAR (hot_spot), Qpoly))
20842 {
20843 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20844 if (VECTORP (XCDR (hot_spot)))
20845 {
20846 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20847 Lisp_Object *poly = v->contents;
20848 int n = v->size;
20849 int i;
20850 int inside = 0;
20851 Lisp_Object lx, ly;
20852 int x0, y0;
20853
20854 /* Need an even number of coordinates, and at least 3 edges. */
20855 if (n < 6 || n & 1)
20856 return 0;
20857
20858 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20859 If count is odd, we are inside polygon. Pixels on edges
20860 may or may not be included depending on actual geometry of the
20861 polygon. */
20862 if ((lx = poly[n-2], !INTEGERP (lx))
20863 || (ly = poly[n-1], !INTEGERP (lx)))
20864 return 0;
20865 x0 = XINT (lx), y0 = XINT (ly);
20866 for (i = 0; i < n; i += 2)
20867 {
20868 int x1 = x0, y1 = y0;
20869 if ((lx = poly[i], !INTEGERP (lx))
20870 || (ly = poly[i+1], !INTEGERP (ly)))
20871 return 0;
20872 x0 = XINT (lx), y0 = XINT (ly);
20873
20874 /* Does this segment cross the X line? */
20875 if (x0 >= x)
20876 {
20877 if (x1 >= x)
20878 continue;
20879 }
20880 else if (x1 < x)
20881 continue;
20882 if (y > y0 && y > y1)
20883 continue;
20884 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20885 inside = !inside;
20886 }
20887 return inside;
20888 }
20889 }
20890 /* If we don't understand the format, pretend we're not in the hot-spot. */
20891 return 0;
20892 }
20893
20894 Lisp_Object
20895 find_hot_spot (map, x, y)
20896 Lisp_Object map;
20897 int x, y;
20898 {
20899 while (CONSP (map))
20900 {
20901 if (CONSP (XCAR (map))
20902 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20903 return XCAR (map);
20904 map = XCDR (map);
20905 }
20906
20907 return Qnil;
20908 }
20909
20910 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20911 3, 3, 0,
20912 doc: /* Lookup in image map MAP coordinates X and Y.
20913 An image map is an alist where each element has the format (AREA ID PLIST).
20914 An AREA is specified as either a rectangle, a circle, or a polygon:
20915 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20916 pixel coordinates of the upper left and bottom right corners.
20917 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20918 and the radius of the circle; r may be a float or integer.
20919 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20920 vector describes one corner in the polygon.
20921 Returns the alist element for the first matching AREA in MAP. */)
20922 (map, x, y)
20923 Lisp_Object map;
20924 Lisp_Object x, y;
20925 {
20926 if (NILP (map))
20927 return Qnil;
20928
20929 CHECK_NUMBER (x);
20930 CHECK_NUMBER (y);
20931
20932 return find_hot_spot (map, XINT (x), XINT (y));
20933 }
20934
20935
20936 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20937 static void
20938 define_frame_cursor1 (f, cursor, pointer)
20939 struct frame *f;
20940 Cursor cursor;
20941 Lisp_Object pointer;
20942 {
20943 /* Do not change cursor shape while dragging mouse. */
20944 if (!NILP (do_mouse_tracking))
20945 return;
20946
20947 if (!NILP (pointer))
20948 {
20949 if (EQ (pointer, Qarrow))
20950 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20951 else if (EQ (pointer, Qhand))
20952 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20953 else if (EQ (pointer, Qtext))
20954 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20955 else if (EQ (pointer, intern ("hdrag")))
20956 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20957 #ifdef HAVE_X_WINDOWS
20958 else if (EQ (pointer, intern ("vdrag")))
20959 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20960 #endif
20961 else if (EQ (pointer, intern ("hourglass")))
20962 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20963 else if (EQ (pointer, Qmodeline))
20964 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20965 else
20966 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20967 }
20968
20969 if (cursor != No_Cursor)
20970 rif->define_frame_cursor (f, cursor);
20971 }
20972
20973 /* Take proper action when mouse has moved to the mode or header line
20974 or marginal area AREA of window W, x-position X and y-position Y.
20975 X is relative to the start of the text display area of W, so the
20976 width of bitmap areas and scroll bars must be subtracted to get a
20977 position relative to the start of the mode line. */
20978
20979 static void
20980 note_mode_line_or_margin_highlight (w, x, y, area)
20981 struct window *w;
20982 int x, y;
20983 enum window_part area;
20984 {
20985 struct frame *f = XFRAME (w->frame);
20986 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20987 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20988 Lisp_Object pointer = Qnil;
20989 int charpos, dx, dy, width, height;
20990 Lisp_Object string, object = Qnil;
20991 Lisp_Object pos, help;
20992
20993 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20994 string = mode_line_string (w, area, &x, &y, &charpos,
20995 &object, &dx, &dy, &width, &height);
20996 else
20997 {
20998 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20999 string = marginal_area_string (w, area, &x, &y, &charpos,
21000 &object, &dx, &dy, &width, &height);
21001 }
21002
21003 help = Qnil;
21004
21005 if (IMAGEP (object))
21006 {
21007 Lisp_Object image_map, hotspot;
21008 if ((image_map = Fplist_get (XCDR (object), QCmap),
21009 !NILP (image_map))
21010 && (hotspot = find_hot_spot (image_map, dx, dy),
21011 CONSP (hotspot))
21012 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21013 {
21014 Lisp_Object area_id, plist;
21015
21016 area_id = XCAR (hotspot);
21017 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21018 If so, we could look for mouse-enter, mouse-leave
21019 properties in PLIST (and do something...). */
21020 if ((plist = XCDR (hotspot), CONSP (plist)))
21021 {
21022 pointer = Fplist_get (plist, Qpointer);
21023 if (NILP (pointer))
21024 pointer = Qhand;
21025 help = Fplist_get (plist, Qhelp_echo);
21026 if (!NILP (help))
21027 {
21028 help_echo_string = help;
21029 /* Is this correct? ++kfs */
21030 XSETWINDOW (help_echo_window, w);
21031 help_echo_object = w->buffer;
21032 help_echo_pos = charpos;
21033 }
21034 }
21035 if (NILP (pointer))
21036 pointer = Fplist_get (XCDR (object), QCpointer);
21037 }
21038 }
21039
21040 if (STRINGP (string))
21041 {
21042 pos = make_number (charpos);
21043 /* If we're on a string with `help-echo' text property, arrange
21044 for the help to be displayed. This is done by setting the
21045 global variable help_echo_string to the help string. */
21046 help = Fget_text_property (pos, Qhelp_echo, string);
21047 if (!NILP (help))
21048 {
21049 help_echo_string = help;
21050 XSETWINDOW (help_echo_window, w);
21051 help_echo_object = string;
21052 help_echo_pos = charpos;
21053 }
21054
21055 if (NILP (pointer))
21056 pointer = Fget_text_property (pos, Qpointer, string);
21057
21058 /* Change the mouse pointer according to what is under X/Y. */
21059 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21060 {
21061 Lisp_Object map;
21062 map = Fget_text_property (pos, Qlocal_map, string);
21063 if (!KEYMAPP (map))
21064 map = Fget_text_property (pos, Qkeymap, string);
21065 if (!KEYMAPP (map))
21066 cursor = dpyinfo->vertical_scroll_bar_cursor;
21067 }
21068 }
21069
21070 define_frame_cursor1 (f, cursor, pointer);
21071 }
21072
21073
21074 /* EXPORT:
21075 Take proper action when the mouse has moved to position X, Y on
21076 frame F as regards highlighting characters that have mouse-face
21077 properties. Also de-highlighting chars where the mouse was before.
21078 X and Y can be negative or out of range. */
21079
21080 void
21081 note_mouse_highlight (f, x, y)
21082 struct frame *f;
21083 int x, y;
21084 {
21085 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21086 enum window_part part;
21087 Lisp_Object window;
21088 struct window *w;
21089 Cursor cursor = No_Cursor;
21090 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21091 struct buffer *b;
21092
21093 /* When a menu is active, don't highlight because this looks odd. */
21094 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21095 if (popup_activated ())
21096 return;
21097 #endif
21098
21099 if (NILP (Vmouse_highlight)
21100 || !f->glyphs_initialized_p)
21101 return;
21102
21103 dpyinfo->mouse_face_mouse_x = x;
21104 dpyinfo->mouse_face_mouse_y = y;
21105 dpyinfo->mouse_face_mouse_frame = f;
21106
21107 if (dpyinfo->mouse_face_defer)
21108 return;
21109
21110 if (gc_in_progress)
21111 {
21112 dpyinfo->mouse_face_deferred_gc = 1;
21113 return;
21114 }
21115
21116 /* Which window is that in? */
21117 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21118
21119 /* If we were displaying active text in another window, clear that. */
21120 if (! EQ (window, dpyinfo->mouse_face_window))
21121 clear_mouse_face (dpyinfo);
21122
21123 /* Not on a window -> return. */
21124 if (!WINDOWP (window))
21125 return;
21126
21127 /* Reset help_echo_string. It will get recomputed below. */
21128 help_echo_string = Qnil;
21129
21130 /* Convert to window-relative pixel coordinates. */
21131 w = XWINDOW (window);
21132 frame_to_window_pixel_xy (w, &x, &y);
21133
21134 /* Handle tool-bar window differently since it doesn't display a
21135 buffer. */
21136 if (EQ (window, f->tool_bar_window))
21137 {
21138 note_tool_bar_highlight (f, x, y);
21139 return;
21140 }
21141
21142 /* Mouse is on the mode, header line or margin? */
21143 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21144 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21145 {
21146 note_mode_line_or_margin_highlight (w, x, y, part);
21147 return;
21148 }
21149
21150 if (part == ON_VERTICAL_BORDER)
21151 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21152 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21153 || part == ON_SCROLL_BAR)
21154 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21155 else
21156 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21157
21158 /* Are we in a window whose display is up to date?
21159 And verify the buffer's text has not changed. */
21160 b = XBUFFER (w->buffer);
21161 if (part == ON_TEXT
21162 && EQ (w->window_end_valid, w->buffer)
21163 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21164 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21165 {
21166 int hpos, vpos, pos, i, dx, dy, area;
21167 struct glyph *glyph;
21168 Lisp_Object object;
21169 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21170 Lisp_Object *overlay_vec = NULL;
21171 int noverlays;
21172 struct buffer *obuf;
21173 int obegv, ozv, same_region;
21174
21175 /* Find the glyph under X/Y. */
21176 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21177
21178 /* Look for :pointer property on image. */
21179 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21180 {
21181 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21182 if (img != NULL && IMAGEP (img->spec))
21183 {
21184 Lisp_Object image_map, hotspot;
21185 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21186 !NILP (image_map))
21187 && (hotspot = find_hot_spot (image_map,
21188 glyph->slice.x + dx,
21189 glyph->slice.y + dy),
21190 CONSP (hotspot))
21191 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21192 {
21193 Lisp_Object area_id, plist;
21194
21195 area_id = XCAR (hotspot);
21196 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21197 If so, we could look for mouse-enter, mouse-leave
21198 properties in PLIST (and do something...). */
21199 if ((plist = XCDR (hotspot), CONSP (plist)))
21200 {
21201 pointer = Fplist_get (plist, Qpointer);
21202 if (NILP (pointer))
21203 pointer = Qhand;
21204 help_echo_string = Fplist_get (plist, Qhelp_echo);
21205 if (!NILP (help_echo_string))
21206 {
21207 help_echo_window = window;
21208 help_echo_object = glyph->object;
21209 help_echo_pos = glyph->charpos;
21210 }
21211 }
21212 }
21213 if (NILP (pointer))
21214 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21215 }
21216 }
21217
21218 /* Clear mouse face if X/Y not over text. */
21219 if (glyph == NULL
21220 || area != TEXT_AREA
21221 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21222 {
21223 if (clear_mouse_face (dpyinfo))
21224 cursor = No_Cursor;
21225 if (NILP (pointer))
21226 {
21227 if (area != TEXT_AREA)
21228 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21229 else
21230 pointer = Vvoid_text_area_pointer;
21231 }
21232 goto set_cursor;
21233 }
21234
21235 pos = glyph->charpos;
21236 object = glyph->object;
21237 if (!STRINGP (object) && !BUFFERP (object))
21238 goto set_cursor;
21239
21240 /* If we get an out-of-range value, return now; avoid an error. */
21241 if (BUFFERP (object) && pos > BUF_Z (b))
21242 goto set_cursor;
21243
21244 /* Make the window's buffer temporarily current for
21245 overlays_at and compute_char_face. */
21246 obuf = current_buffer;
21247 current_buffer = b;
21248 obegv = BEGV;
21249 ozv = ZV;
21250 BEGV = BEG;
21251 ZV = Z;
21252
21253 /* Is this char mouse-active or does it have help-echo? */
21254 position = make_number (pos);
21255
21256 if (BUFFERP (object))
21257 {
21258 /* Put all the overlays we want in a vector in overlay_vec. */
21259 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21260 /* Sort overlays into increasing priority order. */
21261 noverlays = sort_overlays (overlay_vec, noverlays, w);
21262 }
21263 else
21264 noverlays = 0;
21265
21266 same_region = (EQ (window, dpyinfo->mouse_face_window)
21267 && vpos >= dpyinfo->mouse_face_beg_row
21268 && vpos <= dpyinfo->mouse_face_end_row
21269 && (vpos > dpyinfo->mouse_face_beg_row
21270 || hpos >= dpyinfo->mouse_face_beg_col)
21271 && (vpos < dpyinfo->mouse_face_end_row
21272 || hpos < dpyinfo->mouse_face_end_col
21273 || dpyinfo->mouse_face_past_end));
21274
21275 if (same_region)
21276 cursor = No_Cursor;
21277
21278 /* Check mouse-face highlighting. */
21279 if (! same_region
21280 /* If there exists an overlay with mouse-face overlapping
21281 the one we are currently highlighting, we have to
21282 check if we enter the overlapping overlay, and then
21283 highlight only that. */
21284 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21285 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21286 {
21287 /* Find the highest priority overlay that has a mouse-face
21288 property. */
21289 overlay = Qnil;
21290 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21291 {
21292 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21293 if (!NILP (mouse_face))
21294 overlay = overlay_vec[i];
21295 }
21296
21297 /* If we're actually highlighting the same overlay as
21298 before, there's no need to do that again. */
21299 if (!NILP (overlay)
21300 && EQ (overlay, dpyinfo->mouse_face_overlay))
21301 goto check_help_echo;
21302
21303 dpyinfo->mouse_face_overlay = overlay;
21304
21305 /* Clear the display of the old active region, if any. */
21306 if (clear_mouse_face (dpyinfo))
21307 cursor = No_Cursor;
21308
21309 /* If no overlay applies, get a text property. */
21310 if (NILP (overlay))
21311 mouse_face = Fget_text_property (position, Qmouse_face, object);
21312
21313 /* Handle the overlay case. */
21314 if (!NILP (overlay))
21315 {
21316 /* Find the range of text around this char that
21317 should be active. */
21318 Lisp_Object before, after;
21319 int ignore;
21320
21321 before = Foverlay_start (overlay);
21322 after = Foverlay_end (overlay);
21323 /* Record this as the current active region. */
21324 fast_find_position (w, XFASTINT (before),
21325 &dpyinfo->mouse_face_beg_col,
21326 &dpyinfo->mouse_face_beg_row,
21327 &dpyinfo->mouse_face_beg_x,
21328 &dpyinfo->mouse_face_beg_y, Qnil);
21329
21330 dpyinfo->mouse_face_past_end
21331 = !fast_find_position (w, XFASTINT (after),
21332 &dpyinfo->mouse_face_end_col,
21333 &dpyinfo->mouse_face_end_row,
21334 &dpyinfo->mouse_face_end_x,
21335 &dpyinfo->mouse_face_end_y, Qnil);
21336 dpyinfo->mouse_face_window = window;
21337
21338 dpyinfo->mouse_face_face_id
21339 = face_at_buffer_position (w, pos, 0, 0,
21340 &ignore, pos + 1,
21341 !dpyinfo->mouse_face_hidden);
21342
21343 /* Display it as active. */
21344 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21345 cursor = No_Cursor;
21346 }
21347 /* Handle the text property case. */
21348 else if (!NILP (mouse_face) && BUFFERP (object))
21349 {
21350 /* Find the range of text around this char that
21351 should be active. */
21352 Lisp_Object before, after, beginning, end;
21353 int ignore;
21354
21355 beginning = Fmarker_position (w->start);
21356 end = make_number (BUF_Z (XBUFFER (object))
21357 - XFASTINT (w->window_end_pos));
21358 before
21359 = Fprevious_single_property_change (make_number (pos + 1),
21360 Qmouse_face,
21361 object, beginning);
21362 after
21363 = Fnext_single_property_change (position, Qmouse_face,
21364 object, end);
21365
21366 /* Record this as the current active region. */
21367 fast_find_position (w, XFASTINT (before),
21368 &dpyinfo->mouse_face_beg_col,
21369 &dpyinfo->mouse_face_beg_row,
21370 &dpyinfo->mouse_face_beg_x,
21371 &dpyinfo->mouse_face_beg_y, Qnil);
21372 dpyinfo->mouse_face_past_end
21373 = !fast_find_position (w, XFASTINT (after),
21374 &dpyinfo->mouse_face_end_col,
21375 &dpyinfo->mouse_face_end_row,
21376 &dpyinfo->mouse_face_end_x,
21377 &dpyinfo->mouse_face_end_y, Qnil);
21378 dpyinfo->mouse_face_window = window;
21379
21380 if (BUFFERP (object))
21381 dpyinfo->mouse_face_face_id
21382 = face_at_buffer_position (w, pos, 0, 0,
21383 &ignore, pos + 1,
21384 !dpyinfo->mouse_face_hidden);
21385
21386 /* Display it as active. */
21387 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21388 cursor = No_Cursor;
21389 }
21390 else if (!NILP (mouse_face) && STRINGP (object))
21391 {
21392 Lisp_Object b, e;
21393 int ignore;
21394
21395 b = Fprevious_single_property_change (make_number (pos + 1),
21396 Qmouse_face,
21397 object, Qnil);
21398 e = Fnext_single_property_change (position, Qmouse_face,
21399 object, Qnil);
21400 if (NILP (b))
21401 b = make_number (0);
21402 if (NILP (e))
21403 e = make_number (SCHARS (object) - 1);
21404 fast_find_string_pos (w, XINT (b), object,
21405 &dpyinfo->mouse_face_beg_col,
21406 &dpyinfo->mouse_face_beg_row,
21407 &dpyinfo->mouse_face_beg_x,
21408 &dpyinfo->mouse_face_beg_y, 0);
21409 fast_find_string_pos (w, XINT (e), object,
21410 &dpyinfo->mouse_face_end_col,
21411 &dpyinfo->mouse_face_end_row,
21412 &dpyinfo->mouse_face_end_x,
21413 &dpyinfo->mouse_face_end_y, 1);
21414 dpyinfo->mouse_face_past_end = 0;
21415 dpyinfo->mouse_face_window = window;
21416 dpyinfo->mouse_face_face_id
21417 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21418 glyph->face_id, 1);
21419 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21420 cursor = No_Cursor;
21421 }
21422 else if (STRINGP (object) && NILP (mouse_face))
21423 {
21424 /* A string which doesn't have mouse-face, but
21425 the text ``under'' it might have. */
21426 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21427 int start = MATRIX_ROW_START_CHARPOS (r);
21428
21429 pos = string_buffer_position (w, object, start);
21430 if (pos > 0)
21431 mouse_face = get_char_property_and_overlay (make_number (pos),
21432 Qmouse_face,
21433 w->buffer,
21434 &overlay);
21435 if (!NILP (mouse_face) && !NILP (overlay))
21436 {
21437 Lisp_Object before = Foverlay_start (overlay);
21438 Lisp_Object after = Foverlay_end (overlay);
21439 int ignore;
21440
21441 /* Note that we might not be able to find position
21442 BEFORE in the glyph matrix if the overlay is
21443 entirely covered by a `display' property. In
21444 this case, we overshoot. So let's stop in
21445 the glyph matrix before glyphs for OBJECT. */
21446 fast_find_position (w, XFASTINT (before),
21447 &dpyinfo->mouse_face_beg_col,
21448 &dpyinfo->mouse_face_beg_row,
21449 &dpyinfo->mouse_face_beg_x,
21450 &dpyinfo->mouse_face_beg_y,
21451 object);
21452
21453 dpyinfo->mouse_face_past_end
21454 = !fast_find_position (w, XFASTINT (after),
21455 &dpyinfo->mouse_face_end_col,
21456 &dpyinfo->mouse_face_end_row,
21457 &dpyinfo->mouse_face_end_x,
21458 &dpyinfo->mouse_face_end_y,
21459 Qnil);
21460 dpyinfo->mouse_face_window = window;
21461 dpyinfo->mouse_face_face_id
21462 = face_at_buffer_position (w, pos, 0, 0,
21463 &ignore, pos + 1,
21464 !dpyinfo->mouse_face_hidden);
21465
21466 /* Display it as active. */
21467 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21468 cursor = No_Cursor;
21469 }
21470 }
21471 }
21472
21473 check_help_echo:
21474
21475 /* Look for a `help-echo' property. */
21476 if (NILP (help_echo_string)) {
21477 Lisp_Object help, overlay;
21478
21479 /* Check overlays first. */
21480 help = overlay = Qnil;
21481 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21482 {
21483 overlay = overlay_vec[i];
21484 help = Foverlay_get (overlay, Qhelp_echo);
21485 }
21486
21487 if (!NILP (help))
21488 {
21489 help_echo_string = help;
21490 help_echo_window = window;
21491 help_echo_object = overlay;
21492 help_echo_pos = pos;
21493 }
21494 else
21495 {
21496 Lisp_Object object = glyph->object;
21497 int charpos = glyph->charpos;
21498
21499 /* Try text properties. */
21500 if (STRINGP (object)
21501 && charpos >= 0
21502 && charpos < SCHARS (object))
21503 {
21504 help = Fget_text_property (make_number (charpos),
21505 Qhelp_echo, object);
21506 if (NILP (help))
21507 {
21508 /* If the string itself doesn't specify a help-echo,
21509 see if the buffer text ``under'' it does. */
21510 struct glyph_row *r
21511 = MATRIX_ROW (w->current_matrix, vpos);
21512 int start = MATRIX_ROW_START_CHARPOS (r);
21513 int pos = string_buffer_position (w, object, start);
21514 if (pos > 0)
21515 {
21516 help = Fget_char_property (make_number (pos),
21517 Qhelp_echo, w->buffer);
21518 if (!NILP (help))
21519 {
21520 charpos = pos;
21521 object = w->buffer;
21522 }
21523 }
21524 }
21525 }
21526 else if (BUFFERP (object)
21527 && charpos >= BEGV
21528 && charpos < ZV)
21529 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21530 object);
21531
21532 if (!NILP (help))
21533 {
21534 help_echo_string = help;
21535 help_echo_window = window;
21536 help_echo_object = object;
21537 help_echo_pos = charpos;
21538 }
21539 }
21540 }
21541
21542 /* Look for a `pointer' property. */
21543 if (NILP (pointer))
21544 {
21545 /* Check overlays first. */
21546 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21547 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21548
21549 if (NILP (pointer))
21550 {
21551 Lisp_Object object = glyph->object;
21552 int charpos = glyph->charpos;
21553
21554 /* Try text properties. */
21555 if (STRINGP (object)
21556 && charpos >= 0
21557 && charpos < SCHARS (object))
21558 {
21559 pointer = Fget_text_property (make_number (charpos),
21560 Qpointer, object);
21561 if (NILP (pointer))
21562 {
21563 /* If the string itself doesn't specify a pointer,
21564 see if the buffer text ``under'' it does. */
21565 struct glyph_row *r
21566 = MATRIX_ROW (w->current_matrix, vpos);
21567 int start = MATRIX_ROW_START_CHARPOS (r);
21568 int pos = string_buffer_position (w, object, start);
21569 if (pos > 0)
21570 pointer = Fget_char_property (make_number (pos),
21571 Qpointer, w->buffer);
21572 }
21573 }
21574 else if (BUFFERP (object)
21575 && charpos >= BEGV
21576 && charpos < ZV)
21577 pointer = Fget_text_property (make_number (charpos),
21578 Qpointer, object);
21579 }
21580 }
21581
21582 BEGV = obegv;
21583 ZV = ozv;
21584 current_buffer = obuf;
21585 }
21586
21587 set_cursor:
21588
21589 define_frame_cursor1 (f, cursor, pointer);
21590 }
21591
21592
21593 /* EXPORT for RIF:
21594 Clear any mouse-face on window W. This function is part of the
21595 redisplay interface, and is called from try_window_id and similar
21596 functions to ensure the mouse-highlight is off. */
21597
21598 void
21599 x_clear_window_mouse_face (w)
21600 struct window *w;
21601 {
21602 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21603 Lisp_Object window;
21604
21605 BLOCK_INPUT;
21606 XSETWINDOW (window, w);
21607 if (EQ (window, dpyinfo->mouse_face_window))
21608 clear_mouse_face (dpyinfo);
21609 UNBLOCK_INPUT;
21610 }
21611
21612
21613 /* EXPORT:
21614 Just discard the mouse face information for frame F, if any.
21615 This is used when the size of F is changed. */
21616
21617 void
21618 cancel_mouse_face (f)
21619 struct frame *f;
21620 {
21621 Lisp_Object window;
21622 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21623
21624 window = dpyinfo->mouse_face_window;
21625 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21626 {
21627 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21628 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21629 dpyinfo->mouse_face_window = Qnil;
21630 }
21631 }
21632
21633
21634 #endif /* HAVE_WINDOW_SYSTEM */
21635
21636 \f
21637 /***********************************************************************
21638 Exposure Events
21639 ***********************************************************************/
21640
21641 #ifdef HAVE_WINDOW_SYSTEM
21642
21643 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21644 which intersects rectangle R. R is in window-relative coordinates. */
21645
21646 static void
21647 expose_area (w, row, r, area)
21648 struct window *w;
21649 struct glyph_row *row;
21650 XRectangle *r;
21651 enum glyph_row_area area;
21652 {
21653 struct glyph *first = row->glyphs[area];
21654 struct glyph *end = row->glyphs[area] + row->used[area];
21655 struct glyph *last;
21656 int first_x, start_x, x;
21657
21658 if (area == TEXT_AREA && row->fill_line_p)
21659 /* If row extends face to end of line write the whole line. */
21660 draw_glyphs (w, 0, row, area,
21661 0, row->used[area],
21662 DRAW_NORMAL_TEXT, 0);
21663 else
21664 {
21665 /* Set START_X to the window-relative start position for drawing glyphs of
21666 AREA. The first glyph of the text area can be partially visible.
21667 The first glyphs of other areas cannot. */
21668 start_x = window_box_left_offset (w, area);
21669 x = start_x;
21670 if (area == TEXT_AREA)
21671 x += row->x;
21672
21673 /* Find the first glyph that must be redrawn. */
21674 while (first < end
21675 && x + first->pixel_width < r->x)
21676 {
21677 x += first->pixel_width;
21678 ++first;
21679 }
21680
21681 /* Find the last one. */
21682 last = first;
21683 first_x = x;
21684 while (last < end
21685 && x < r->x + r->width)
21686 {
21687 x += last->pixel_width;
21688 ++last;
21689 }
21690
21691 /* Repaint. */
21692 if (last > first)
21693 draw_glyphs (w, first_x - start_x, row, area,
21694 first - row->glyphs[area], last - row->glyphs[area],
21695 DRAW_NORMAL_TEXT, 0);
21696 }
21697 }
21698
21699
21700 /* Redraw the parts of the glyph row ROW on window W intersecting
21701 rectangle R. R is in window-relative coordinates. Value is
21702 non-zero if mouse-face was overwritten. */
21703
21704 static int
21705 expose_line (w, row, r)
21706 struct window *w;
21707 struct glyph_row *row;
21708 XRectangle *r;
21709 {
21710 xassert (row->enabled_p);
21711
21712 if (row->mode_line_p || w->pseudo_window_p)
21713 draw_glyphs (w, 0, row, TEXT_AREA,
21714 0, row->used[TEXT_AREA],
21715 DRAW_NORMAL_TEXT, 0);
21716 else
21717 {
21718 if (row->used[LEFT_MARGIN_AREA])
21719 expose_area (w, row, r, LEFT_MARGIN_AREA);
21720 if (row->used[TEXT_AREA])
21721 expose_area (w, row, r, TEXT_AREA);
21722 if (row->used[RIGHT_MARGIN_AREA])
21723 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21724 draw_row_fringe_bitmaps (w, row);
21725 }
21726
21727 return row->mouse_face_p;
21728 }
21729
21730
21731 /* Redraw those parts of glyphs rows during expose event handling that
21732 overlap other rows. Redrawing of an exposed line writes over parts
21733 of lines overlapping that exposed line; this function fixes that.
21734
21735 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21736 row in W's current matrix that is exposed and overlaps other rows.
21737 LAST_OVERLAPPING_ROW is the last such row. */
21738
21739 static void
21740 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21741 struct window *w;
21742 struct glyph_row *first_overlapping_row;
21743 struct glyph_row *last_overlapping_row;
21744 {
21745 struct glyph_row *row;
21746
21747 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21748 if (row->overlapping_p)
21749 {
21750 xassert (row->enabled_p && !row->mode_line_p);
21751
21752 if (row->used[LEFT_MARGIN_AREA])
21753 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21754
21755 if (row->used[TEXT_AREA])
21756 x_fix_overlapping_area (w, row, TEXT_AREA);
21757
21758 if (row->used[RIGHT_MARGIN_AREA])
21759 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21760 }
21761 }
21762
21763
21764 /* Return non-zero if W's cursor intersects rectangle R. */
21765
21766 static int
21767 phys_cursor_in_rect_p (w, r)
21768 struct window *w;
21769 XRectangle *r;
21770 {
21771 XRectangle cr, result;
21772 struct glyph *cursor_glyph;
21773
21774 cursor_glyph = get_phys_cursor_glyph (w);
21775 if (cursor_glyph)
21776 {
21777 /* r is relative to W's box, but w->phys_cursor.x is relative
21778 to left edge of W's TEXT area. Adjust it. */
21779 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21780 cr.y = w->phys_cursor.y;
21781 cr.width = cursor_glyph->pixel_width;
21782 cr.height = w->phys_cursor_height;
21783 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21784 I assume the effect is the same -- and this is portable. */
21785 return x_intersect_rectangles (&cr, r, &result);
21786 }
21787 else
21788 return 0;
21789 }
21790
21791
21792 /* EXPORT:
21793 Draw a vertical window border to the right of window W if W doesn't
21794 have vertical scroll bars. */
21795
21796 void
21797 x_draw_vertical_border (w)
21798 struct window *w;
21799 {
21800 /* We could do better, if we knew what type of scroll-bar the adjacent
21801 windows (on either side) have... But we don't :-(
21802 However, I think this works ok. ++KFS 2003-04-25 */
21803
21804 /* Redraw borders between horizontally adjacent windows. Don't
21805 do it for frames with vertical scroll bars because either the
21806 right scroll bar of a window, or the left scroll bar of its
21807 neighbor will suffice as a border. */
21808 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
21809 return;
21810
21811 if (!WINDOW_RIGHTMOST_P (w)
21812 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21813 {
21814 int x0, x1, y0, y1;
21815
21816 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21817 y1 -= 1;
21818
21819 rif->draw_vertical_window_border (w, x1, y0, y1);
21820 }
21821 else if (!WINDOW_LEFTMOST_P (w)
21822 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21823 {
21824 int x0, x1, y0, y1;
21825
21826 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21827 y1 -= 1;
21828
21829 rif->draw_vertical_window_border (w, x0, y0, y1);
21830 }
21831 }
21832
21833
21834 /* Redraw the part of window W intersection rectangle FR. Pixel
21835 coordinates in FR are frame-relative. Call this function with
21836 input blocked. Value is non-zero if the exposure overwrites
21837 mouse-face. */
21838
21839 static int
21840 expose_window (w, fr)
21841 struct window *w;
21842 XRectangle *fr;
21843 {
21844 struct frame *f = XFRAME (w->frame);
21845 XRectangle wr, r;
21846 int mouse_face_overwritten_p = 0;
21847
21848 /* If window is not yet fully initialized, do nothing. This can
21849 happen when toolkit scroll bars are used and a window is split.
21850 Reconfiguring the scroll bar will generate an expose for a newly
21851 created window. */
21852 if (w->current_matrix == NULL)
21853 return 0;
21854
21855 /* When we're currently updating the window, display and current
21856 matrix usually don't agree. Arrange for a thorough display
21857 later. */
21858 if (w == updated_window)
21859 {
21860 SET_FRAME_GARBAGED (f);
21861 return 0;
21862 }
21863
21864 /* Frame-relative pixel rectangle of W. */
21865 wr.x = WINDOW_LEFT_EDGE_X (w);
21866 wr.y = WINDOW_TOP_EDGE_Y (w);
21867 wr.width = WINDOW_TOTAL_WIDTH (w);
21868 wr.height = WINDOW_TOTAL_HEIGHT (w);
21869
21870 if (x_intersect_rectangles (fr, &wr, &r))
21871 {
21872 int yb = window_text_bottom_y (w);
21873 struct glyph_row *row;
21874 int cursor_cleared_p;
21875 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21876
21877 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21878 r.x, r.y, r.width, r.height));
21879
21880 /* Convert to window coordinates. */
21881 r.x -= WINDOW_LEFT_EDGE_X (w);
21882 r.y -= WINDOW_TOP_EDGE_Y (w);
21883
21884 /* Turn off the cursor. */
21885 if (!w->pseudo_window_p
21886 && phys_cursor_in_rect_p (w, &r))
21887 {
21888 x_clear_cursor (w);
21889 cursor_cleared_p = 1;
21890 }
21891 else
21892 cursor_cleared_p = 0;
21893
21894 /* Update lines intersecting rectangle R. */
21895 first_overlapping_row = last_overlapping_row = NULL;
21896 for (row = w->current_matrix->rows;
21897 row->enabled_p;
21898 ++row)
21899 {
21900 int y0 = row->y;
21901 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21902
21903 if ((y0 >= r.y && y0 < r.y + r.height)
21904 || (y1 > r.y && y1 < r.y + r.height)
21905 || (r.y >= y0 && r.y < y1)
21906 || (r.y + r.height > y0 && r.y + r.height < y1))
21907 {
21908 if (row->overlapping_p)
21909 {
21910 if (first_overlapping_row == NULL)
21911 first_overlapping_row = row;
21912 last_overlapping_row = row;
21913 }
21914
21915 if (expose_line (w, row, &r))
21916 mouse_face_overwritten_p = 1;
21917 }
21918
21919 if (y1 >= yb)
21920 break;
21921 }
21922
21923 /* Display the mode line if there is one. */
21924 if (WINDOW_WANTS_MODELINE_P (w)
21925 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21926 row->enabled_p)
21927 && row->y < r.y + r.height)
21928 {
21929 if (expose_line (w, row, &r))
21930 mouse_face_overwritten_p = 1;
21931 }
21932
21933 if (!w->pseudo_window_p)
21934 {
21935 /* Fix the display of overlapping rows. */
21936 if (first_overlapping_row)
21937 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21938
21939 /* Draw border between windows. */
21940 x_draw_vertical_border (w);
21941
21942 /* Turn the cursor on again. */
21943 if (cursor_cleared_p)
21944 update_window_cursor (w, 1);
21945 }
21946 }
21947
21948 #ifdef HAVE_CARBON
21949 /* Display scroll bar for this window. */
21950 if (!NILP (w->vertical_scroll_bar))
21951 {
21952 /* ++KFS:
21953 If this doesn't work here (maybe some header files are missing),
21954 make a function in macterm.c and call it to do the job! */
21955 ControlHandle ch
21956 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21957
21958 Draw1Control (ch);
21959 }
21960 #endif
21961
21962 return mouse_face_overwritten_p;
21963 }
21964
21965
21966
21967 /* Redraw (parts) of all windows in the window tree rooted at W that
21968 intersect R. R contains frame pixel coordinates. Value is
21969 non-zero if the exposure overwrites mouse-face. */
21970
21971 static int
21972 expose_window_tree (w, r)
21973 struct window *w;
21974 XRectangle *r;
21975 {
21976 struct frame *f = XFRAME (w->frame);
21977 int mouse_face_overwritten_p = 0;
21978
21979 while (w && !FRAME_GARBAGED_P (f))
21980 {
21981 if (!NILP (w->hchild))
21982 mouse_face_overwritten_p
21983 |= expose_window_tree (XWINDOW (w->hchild), r);
21984 else if (!NILP (w->vchild))
21985 mouse_face_overwritten_p
21986 |= expose_window_tree (XWINDOW (w->vchild), r);
21987 else
21988 mouse_face_overwritten_p |= expose_window (w, r);
21989
21990 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21991 }
21992
21993 return mouse_face_overwritten_p;
21994 }
21995
21996
21997 /* EXPORT:
21998 Redisplay an exposed area of frame F. X and Y are the upper-left
21999 corner of the exposed rectangle. W and H are width and height of
22000 the exposed area. All are pixel values. W or H zero means redraw
22001 the entire frame. */
22002
22003 void
22004 expose_frame (f, x, y, w, h)
22005 struct frame *f;
22006 int x, y, w, h;
22007 {
22008 XRectangle r;
22009 int mouse_face_overwritten_p = 0;
22010
22011 TRACE ((stderr, "expose_frame "));
22012
22013 /* No need to redraw if frame will be redrawn soon. */
22014 if (FRAME_GARBAGED_P (f))
22015 {
22016 TRACE ((stderr, " garbaged\n"));
22017 return;
22018 }
22019
22020 #ifdef HAVE_CARBON
22021 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
22022 or deactivated here, for unknown reasons, activated scroll bars
22023 are shown in deactivated frames in some instances. */
22024 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
22025 activate_scroll_bars (f);
22026 else
22027 deactivate_scroll_bars (f);
22028 #endif
22029
22030 /* If basic faces haven't been realized yet, there is no point in
22031 trying to redraw anything. This can happen when we get an expose
22032 event while Emacs is starting, e.g. by moving another window. */
22033 if (FRAME_FACE_CACHE (f) == NULL
22034 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22035 {
22036 TRACE ((stderr, " no faces\n"));
22037 return;
22038 }
22039
22040 if (w == 0 || h == 0)
22041 {
22042 r.x = r.y = 0;
22043 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22044 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22045 }
22046 else
22047 {
22048 r.x = x;
22049 r.y = y;
22050 r.width = w;
22051 r.height = h;
22052 }
22053
22054 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22055 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22056
22057 if (WINDOWP (f->tool_bar_window))
22058 mouse_face_overwritten_p
22059 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22060
22061 #ifdef HAVE_X_WINDOWS
22062 #ifndef MSDOS
22063 #ifndef USE_X_TOOLKIT
22064 if (WINDOWP (f->menu_bar_window))
22065 mouse_face_overwritten_p
22066 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22067 #endif /* not USE_X_TOOLKIT */
22068 #endif
22069 #endif
22070
22071 /* Some window managers support a focus-follows-mouse style with
22072 delayed raising of frames. Imagine a partially obscured frame,
22073 and moving the mouse into partially obscured mouse-face on that
22074 frame. The visible part of the mouse-face will be highlighted,
22075 then the WM raises the obscured frame. With at least one WM, KDE
22076 2.1, Emacs is not getting any event for the raising of the frame
22077 (even tried with SubstructureRedirectMask), only Expose events.
22078 These expose events will draw text normally, i.e. not
22079 highlighted. Which means we must redo the highlight here.
22080 Subsume it under ``we love X''. --gerd 2001-08-15 */
22081 /* Included in Windows version because Windows most likely does not
22082 do the right thing if any third party tool offers
22083 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22084 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22085 {
22086 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22087 if (f == dpyinfo->mouse_face_mouse_frame)
22088 {
22089 int x = dpyinfo->mouse_face_mouse_x;
22090 int y = dpyinfo->mouse_face_mouse_y;
22091 clear_mouse_face (dpyinfo);
22092 note_mouse_highlight (f, x, y);
22093 }
22094 }
22095 }
22096
22097
22098 /* EXPORT:
22099 Determine the intersection of two rectangles R1 and R2. Return
22100 the intersection in *RESULT. Value is non-zero if RESULT is not
22101 empty. */
22102
22103 int
22104 x_intersect_rectangles (r1, r2, result)
22105 XRectangle *r1, *r2, *result;
22106 {
22107 XRectangle *left, *right;
22108 XRectangle *upper, *lower;
22109 int intersection_p = 0;
22110
22111 /* Rearrange so that R1 is the left-most rectangle. */
22112 if (r1->x < r2->x)
22113 left = r1, right = r2;
22114 else
22115 left = r2, right = r1;
22116
22117 /* X0 of the intersection is right.x0, if this is inside R1,
22118 otherwise there is no intersection. */
22119 if (right->x <= left->x + left->width)
22120 {
22121 result->x = right->x;
22122
22123 /* The right end of the intersection is the minimum of the
22124 the right ends of left and right. */
22125 result->width = (min (left->x + left->width, right->x + right->width)
22126 - result->x);
22127
22128 /* Same game for Y. */
22129 if (r1->y < r2->y)
22130 upper = r1, lower = r2;
22131 else
22132 upper = r2, lower = r1;
22133
22134 /* The upper end of the intersection is lower.y0, if this is inside
22135 of upper. Otherwise, there is no intersection. */
22136 if (lower->y <= upper->y + upper->height)
22137 {
22138 result->y = lower->y;
22139
22140 /* The lower end of the intersection is the minimum of the lower
22141 ends of upper and lower. */
22142 result->height = (min (lower->y + lower->height,
22143 upper->y + upper->height)
22144 - result->y);
22145 intersection_p = 1;
22146 }
22147 }
22148
22149 return intersection_p;
22150 }
22151
22152 #endif /* HAVE_WINDOW_SYSTEM */
22153
22154 \f
22155 /***********************************************************************
22156 Initialization
22157 ***********************************************************************/
22158
22159 void
22160 syms_of_xdisp ()
22161 {
22162 Vwith_echo_area_save_vector = Qnil;
22163 staticpro (&Vwith_echo_area_save_vector);
22164
22165 Vmessage_stack = Qnil;
22166 staticpro (&Vmessage_stack);
22167
22168 Qinhibit_redisplay = intern ("inhibit-redisplay");
22169 staticpro (&Qinhibit_redisplay);
22170
22171 message_dolog_marker1 = Fmake_marker ();
22172 staticpro (&message_dolog_marker1);
22173 message_dolog_marker2 = Fmake_marker ();
22174 staticpro (&message_dolog_marker2);
22175 message_dolog_marker3 = Fmake_marker ();
22176 staticpro (&message_dolog_marker3);
22177
22178 #if GLYPH_DEBUG
22179 defsubr (&Sdump_frame_glyph_matrix);
22180 defsubr (&Sdump_glyph_matrix);
22181 defsubr (&Sdump_glyph_row);
22182 defsubr (&Sdump_tool_bar_row);
22183 defsubr (&Strace_redisplay);
22184 defsubr (&Strace_to_stderr);
22185 #endif
22186 #ifdef HAVE_WINDOW_SYSTEM
22187 defsubr (&Stool_bar_lines_needed);
22188 defsubr (&Slookup_image_map);
22189 #endif
22190 defsubr (&Sformat_mode_line);
22191
22192 staticpro (&Qmenu_bar_update_hook);
22193 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22194
22195 staticpro (&Qoverriding_terminal_local_map);
22196 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22197
22198 staticpro (&Qoverriding_local_map);
22199 Qoverriding_local_map = intern ("overriding-local-map");
22200
22201 staticpro (&Qwindow_scroll_functions);
22202 Qwindow_scroll_functions = intern ("window-scroll-functions");
22203
22204 staticpro (&Qredisplay_end_trigger_functions);
22205 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22206
22207 staticpro (&Qinhibit_point_motion_hooks);
22208 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22209
22210 QCdata = intern (":data");
22211 staticpro (&QCdata);
22212 Qdisplay = intern ("display");
22213 staticpro (&Qdisplay);
22214 Qspace_width = intern ("space-width");
22215 staticpro (&Qspace_width);
22216 Qraise = intern ("raise");
22217 staticpro (&Qraise);
22218 Qslice = intern ("slice");
22219 staticpro (&Qslice);
22220 Qspace = intern ("space");
22221 staticpro (&Qspace);
22222 Qmargin = intern ("margin");
22223 staticpro (&Qmargin);
22224 Qpointer = intern ("pointer");
22225 staticpro (&Qpointer);
22226 Qleft_margin = intern ("left-margin");
22227 staticpro (&Qleft_margin);
22228 Qright_margin = intern ("right-margin");
22229 staticpro (&Qright_margin);
22230 Qcenter = intern ("center");
22231 staticpro (&Qcenter);
22232 Qline_height = intern ("line-height");
22233 staticpro (&Qline_height);
22234 Qtotal = intern ("total");
22235 staticpro (&Qtotal);
22236 QCalign_to = intern (":align-to");
22237 staticpro (&QCalign_to);
22238 QCrelative_width = intern (":relative-width");
22239 staticpro (&QCrelative_width);
22240 QCrelative_height = intern (":relative-height");
22241 staticpro (&QCrelative_height);
22242 QCeval = intern (":eval");
22243 staticpro (&QCeval);
22244 QCpropertize = intern (":propertize");
22245 staticpro (&QCpropertize);
22246 QCfile = intern (":file");
22247 staticpro (&QCfile);
22248 Qfontified = intern ("fontified");
22249 staticpro (&Qfontified);
22250 Qfontification_functions = intern ("fontification-functions");
22251 staticpro (&Qfontification_functions);
22252 Qtrailing_whitespace = intern ("trailing-whitespace");
22253 staticpro (&Qtrailing_whitespace);
22254 Qimage = intern ("image");
22255 staticpro (&Qimage);
22256 QCmap = intern (":map");
22257 staticpro (&QCmap);
22258 QCpointer = intern (":pointer");
22259 staticpro (&QCpointer);
22260 Qrect = intern ("rect");
22261 staticpro (&Qrect);
22262 Qcircle = intern ("circle");
22263 staticpro (&Qcircle);
22264 Qpoly = intern ("poly");
22265 staticpro (&Qpoly);
22266 Qmessage_truncate_lines = intern ("message-truncate-lines");
22267 staticpro (&Qmessage_truncate_lines);
22268 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22269 staticpro (&Qcursor_in_non_selected_windows);
22270 Qgrow_only = intern ("grow-only");
22271 staticpro (&Qgrow_only);
22272 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22273 staticpro (&Qinhibit_menubar_update);
22274 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22275 staticpro (&Qinhibit_eval_during_redisplay);
22276 Qposition = intern ("position");
22277 staticpro (&Qposition);
22278 Qbuffer_position = intern ("buffer-position");
22279 staticpro (&Qbuffer_position);
22280 Qobject = intern ("object");
22281 staticpro (&Qobject);
22282 Qbar = intern ("bar");
22283 staticpro (&Qbar);
22284 Qhbar = intern ("hbar");
22285 staticpro (&Qhbar);
22286 Qbox = intern ("box");
22287 staticpro (&Qbox);
22288 Qhollow = intern ("hollow");
22289 staticpro (&Qhollow);
22290 Qhand = intern ("hand");
22291 staticpro (&Qhand);
22292 Qarrow = intern ("arrow");
22293 staticpro (&Qarrow);
22294 Qtext = intern ("text");
22295 staticpro (&Qtext);
22296 Qrisky_local_variable = intern ("risky-local-variable");
22297 staticpro (&Qrisky_local_variable);
22298 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22299 staticpro (&Qinhibit_free_realized_faces);
22300
22301 list_of_error = Fcons (Fcons (intern ("error"),
22302 Fcons (intern ("void-variable"), Qnil)),
22303 Qnil);
22304 staticpro (&list_of_error);
22305
22306 Qlast_arrow_position = intern ("last-arrow-position");
22307 staticpro (&Qlast_arrow_position);
22308 Qlast_arrow_string = intern ("last-arrow-string");
22309 staticpro (&Qlast_arrow_string);
22310
22311 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22312 staticpro (&Qoverlay_arrow_string);
22313 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22314 staticpro (&Qoverlay_arrow_bitmap);
22315
22316 echo_buffer[0] = echo_buffer[1] = Qnil;
22317 staticpro (&echo_buffer[0]);
22318 staticpro (&echo_buffer[1]);
22319
22320 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22321 staticpro (&echo_area_buffer[0]);
22322 staticpro (&echo_area_buffer[1]);
22323
22324 Vmessages_buffer_name = build_string ("*Messages*");
22325 staticpro (&Vmessages_buffer_name);
22326
22327 mode_line_proptrans_alist = Qnil;
22328 staticpro (&mode_line_proptrans_alist);
22329
22330 mode_line_string_list = Qnil;
22331 staticpro (&mode_line_string_list);
22332
22333 help_echo_string = Qnil;
22334 staticpro (&help_echo_string);
22335 help_echo_object = Qnil;
22336 staticpro (&help_echo_object);
22337 help_echo_window = Qnil;
22338 staticpro (&help_echo_window);
22339 previous_help_echo_string = Qnil;
22340 staticpro (&previous_help_echo_string);
22341 help_echo_pos = -1;
22342
22343 #ifdef HAVE_WINDOW_SYSTEM
22344 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22345 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22346 For example, if a block cursor is over a tab, it will be drawn as
22347 wide as that tab on the display. */);
22348 x_stretch_cursor_p = 0;
22349 #endif
22350
22351 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22352 doc: /* *Non-nil means highlight trailing whitespace.
22353 The face used for trailing whitespace is `trailing-whitespace'. */);
22354 Vshow_trailing_whitespace = Qnil;
22355
22356 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22357 doc: /* *The pointer shape to show in void text areas.
22358 Nil means to show the text pointer. Other options are `arrow', `text',
22359 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22360 Vvoid_text_area_pointer = Qarrow;
22361
22362 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22363 doc: /* Non-nil means don't actually do any redisplay.
22364 This is used for internal purposes. */);
22365 Vinhibit_redisplay = Qnil;
22366
22367 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22368 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22369 Vglobal_mode_string = Qnil;
22370
22371 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22372 doc: /* Marker for where to display an arrow on top of the buffer text.
22373 This must be the beginning of a line in order to work.
22374 See also `overlay-arrow-string'. */);
22375 Voverlay_arrow_position = Qnil;
22376
22377 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22378 doc: /* String to display as an arrow in non-window frames.
22379 See also `overlay-arrow-position'. */);
22380 Voverlay_arrow_string = Qnil;
22381
22382 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22383 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22384 The symbols on this list are examined during redisplay to determine
22385 where to display overlay arrows. */);
22386 Voverlay_arrow_variable_list
22387 = Fcons (intern ("overlay-arrow-position"), Qnil);
22388
22389 DEFVAR_INT ("scroll-step", &scroll_step,
22390 doc: /* *The number of lines to try scrolling a window by when point moves out.
22391 If that fails to bring point back on frame, point is centered instead.
22392 If this is zero, point is always centered after it moves off frame.
22393 If you want scrolling to always be a line at a time, you should set
22394 `scroll-conservatively' to a large value rather than set this to 1. */);
22395
22396 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22397 doc: /* *Scroll up to this many lines, to bring point back on screen.
22398 A value of zero means to scroll the text to center point vertically
22399 in the window. */);
22400 scroll_conservatively = 0;
22401
22402 DEFVAR_INT ("scroll-margin", &scroll_margin,
22403 doc: /* *Number of lines of margin at the top and bottom of a window.
22404 Recenter the window whenever point gets within this many lines
22405 of the top or bottom of the window. */);
22406 scroll_margin = 0;
22407
22408 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22409 doc: /* Pixels per inch on current display.
22410 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22411 Vdisplay_pixels_per_inch = make_float (72.0);
22412
22413 #if GLYPH_DEBUG
22414 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22415 #endif
22416
22417 DEFVAR_BOOL ("truncate-partial-width-windows",
22418 &truncate_partial_width_windows,
22419 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22420 truncate_partial_width_windows = 1;
22421
22422 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22423 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22424 Any other value means to use the appropriate face, `mode-line',
22425 `header-line', or `menu' respectively. */);
22426 mode_line_inverse_video = 1;
22427
22428 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22429 doc: /* *Maximum buffer size for which line number should be displayed.
22430 If the buffer is bigger than this, the line number does not appear
22431 in the mode line. A value of nil means no limit. */);
22432 Vline_number_display_limit = Qnil;
22433
22434 DEFVAR_INT ("line-number-display-limit-width",
22435 &line_number_display_limit_width,
22436 doc: /* *Maximum line width (in characters) for line number display.
22437 If the average length of the lines near point is bigger than this, then the
22438 line number may be omitted from the mode line. */);
22439 line_number_display_limit_width = 200;
22440
22441 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22442 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22443 highlight_nonselected_windows = 0;
22444
22445 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22446 doc: /* Non-nil if more than one frame is visible on this display.
22447 Minibuffer-only frames don't count, but iconified frames do.
22448 This variable is not guaranteed to be accurate except while processing
22449 `frame-title-format' and `icon-title-format'. */);
22450
22451 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22452 doc: /* Template for displaying the title bar of visible frames.
22453 \(Assuming the window manager supports this feature.)
22454 This variable has the same structure as `mode-line-format' (which see),
22455 and is used only on frames for which no explicit name has been set
22456 \(see `modify-frame-parameters'). */);
22457
22458 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22459 doc: /* Template for displaying the title bar of an iconified frame.
22460 \(Assuming the window manager supports this feature.)
22461 This variable has the same structure as `mode-line-format' (which see),
22462 and is used only on frames for which no explicit name has been set
22463 \(see `modify-frame-parameters'). */);
22464 Vicon_title_format
22465 = Vframe_title_format
22466 = Fcons (intern ("multiple-frames"),
22467 Fcons (build_string ("%b"),
22468 Fcons (Fcons (empty_string,
22469 Fcons (intern ("invocation-name"),
22470 Fcons (build_string ("@"),
22471 Fcons (intern ("system-name"),
22472 Qnil)))),
22473 Qnil)));
22474
22475 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22476 doc: /* Maximum number of lines to keep in the message log buffer.
22477 If nil, disable message logging. If t, log messages but don't truncate
22478 the buffer when it becomes large. */);
22479 Vmessage_log_max = make_number (50);
22480
22481 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22482 doc: /* Functions called before redisplay, if window sizes have changed.
22483 The value should be a list of functions that take one argument.
22484 Just before redisplay, for each frame, if any of its windows have changed
22485 size since the last redisplay, or have been split or deleted,
22486 all the functions in the list are called, with the frame as argument. */);
22487 Vwindow_size_change_functions = Qnil;
22488
22489 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22490 doc: /* List of functions to call before redisplaying a window with scrolling.
22491 Each function is called with two arguments, the window
22492 and its new display-start position. Note that the value of `window-end'
22493 is not valid when these functions are called. */);
22494 Vwindow_scroll_functions = Qnil;
22495
22496 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22497 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22498 mouse_autoselect_window = 0;
22499
22500 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22501 doc: /* *Non-nil means automatically resize tool-bars.
22502 This increases a tool-bar's height if not all tool-bar items are visible.
22503 It decreases a tool-bar's height when it would display blank lines
22504 otherwise. */);
22505 auto_resize_tool_bars_p = 1;
22506
22507 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22508 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22509 auto_raise_tool_bar_buttons_p = 1;
22510
22511 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22512 doc: /* *Margin around tool-bar buttons in pixels.
22513 If an integer, use that for both horizontal and vertical margins.
22514 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22515 HORZ specifying the horizontal margin, and VERT specifying the
22516 vertical margin. */);
22517 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22518
22519 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22520 doc: /* *Relief thickness of tool-bar buttons. */);
22521 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22522
22523 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22524 doc: /* List of functions to call to fontify regions of text.
22525 Each function is called with one argument POS. Functions must
22526 fontify a region starting at POS in the current buffer, and give
22527 fontified regions the property `fontified'. */);
22528 Vfontification_functions = Qnil;
22529 Fmake_variable_buffer_local (Qfontification_functions);
22530
22531 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22532 &unibyte_display_via_language_environment,
22533 doc: /* *Non-nil means display unibyte text according to language environment.
22534 Specifically this means that unibyte non-ASCII characters
22535 are displayed by converting them to the equivalent multibyte characters
22536 according to the current language environment. As a result, they are
22537 displayed according to the current fontset. */);
22538 unibyte_display_via_language_environment = 0;
22539
22540 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22541 doc: /* *Maximum height for resizing mini-windows.
22542 If a float, it specifies a fraction of the mini-window frame's height.
22543 If an integer, it specifies a number of lines. */);
22544 Vmax_mini_window_height = make_float (0.25);
22545
22546 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22547 doc: /* *How to resize mini-windows.
22548 A value of nil means don't automatically resize mini-windows.
22549 A value of t means resize them to fit the text displayed in them.
22550 A value of `grow-only', the default, means let mini-windows grow
22551 only, until their display becomes empty, at which point the windows
22552 go back to their normal size. */);
22553 Vresize_mini_windows = Qgrow_only;
22554
22555 DEFVAR_LISP ("cursor-in-non-selected-windows",
22556 &Vcursor_in_non_selected_windows,
22557 doc: /* *Cursor type to display in non-selected windows.
22558 t means to use hollow box cursor. See `cursor-type' for other values. */);
22559 Vcursor_in_non_selected_windows = Qt;
22560
22561 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22562 doc: /* Alist specifying how to blink the cursor off.
22563 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22564 `cursor-type' frame-parameter or variable equals ON-STATE,
22565 comparing using `equal', Emacs uses OFF-STATE to specify
22566 how to blink it off. */);
22567 Vblink_cursor_alist = Qnil;
22568
22569 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22570 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22571 automatic_hscrolling_p = 1;
22572
22573 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22574 doc: /* *How many columns away from the window edge point is allowed to get
22575 before automatic hscrolling will horizontally scroll the window. */);
22576 hscroll_margin = 5;
22577
22578 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22579 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22580 When point is less than `automatic-hscroll-margin' columns from the window
22581 edge, automatic hscrolling will scroll the window by the amount of columns
22582 determined by this variable. If its value is a positive integer, scroll that
22583 many columns. If it's a positive floating-point number, it specifies the
22584 fraction of the window's width to scroll. If it's nil or zero, point will be
22585 centered horizontally after the scroll. Any other value, including negative
22586 numbers, are treated as if the value were zero.
22587
22588 Automatic hscrolling always moves point outside the scroll margin, so if
22589 point was more than scroll step columns inside the margin, the window will
22590 scroll more than the value given by the scroll step.
22591
22592 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22593 and `scroll-right' overrides this variable's effect. */);
22594 Vhscroll_step = make_number (0);
22595
22596 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22597 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22598 Bind this around calls to `message' to let it take effect. */);
22599 message_truncate_lines = 0;
22600
22601 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22602 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22603 Can be used to update submenus whose contents should vary. */);
22604 Vmenu_bar_update_hook = Qnil;
22605
22606 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22607 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22608 inhibit_menubar_update = 0;
22609
22610 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22611 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22612 inhibit_eval_during_redisplay = 0;
22613
22614 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22615 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22616 inhibit_free_realized_faces = 0;
22617
22618 #if GLYPH_DEBUG
22619 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22620 doc: /* Inhibit try_window_id display optimization. */);
22621 inhibit_try_window_id = 0;
22622
22623 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22624 doc: /* Inhibit try_window_reusing display optimization. */);
22625 inhibit_try_window_reusing = 0;
22626
22627 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22628 doc: /* Inhibit try_cursor_movement display optimization. */);
22629 inhibit_try_cursor_movement = 0;
22630 #endif /* GLYPH_DEBUG */
22631 }
22632
22633
22634 /* Initialize this module when Emacs starts. */
22635
22636 void
22637 init_xdisp ()
22638 {
22639 Lisp_Object root_window;
22640 struct window *mini_w;
22641
22642 current_header_line_height = current_mode_line_height = -1;
22643
22644 CHARPOS (this_line_start_pos) = 0;
22645
22646 mini_w = XWINDOW (minibuf_window);
22647 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22648
22649 if (!noninteractive)
22650 {
22651 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22652 int i;
22653
22654 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22655 set_window_height (root_window,
22656 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22657 0);
22658 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22659 set_window_height (minibuf_window, 1, 0);
22660
22661 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22662 mini_w->total_cols = make_number (FRAME_COLS (f));
22663
22664 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22665 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22666 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22667
22668 /* The default ellipsis glyphs `...'. */
22669 for (i = 0; i < 3; ++i)
22670 default_invis_vector[i] = make_number ('.');
22671 }
22672
22673 {
22674 /* Allocate the buffer for frame titles.
22675 Also used for `format-mode-line'. */
22676 int size = 100;
22677 frame_title_buf = (char *) xmalloc (size);
22678 frame_title_buf_end = frame_title_buf + size;
22679 frame_title_ptr = NULL;
22680 }
22681
22682 help_echo_showing_p = 0;
22683 }
22684
22685
22686 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22687 (do not change this comment) */